Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src/apps
diff options
context:
space:
mode:
authorCasimir666 <casimir666@users.sourceforge.net>2006-06-25 01:37:43 +0400
committerCasimir666 <casimir666@users.sourceforge.net>2006-06-25 01:37:43 +0400
commit0868305e78da2b0742c2ce349efa041d5622ae21 (patch)
tree663fd93132c7927910ba7c13188d6332b2e3e5b2 /src/apps
parent43c8656956a0460fc4551e3ea7a39b9f3094a3e3 (diff)
git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@14 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/apps')
-rw-r--r--src/apps/asf2mkv/asf2mkv.cpp106
-rw-r--r--src/apps/asf2mkv/asf2mkv.h53
-rw-r--r--src/apps/asf2mkv/asf2mkv.rc219
-rw-r--r--src/apps/asf2mkv/asf2mkv.sln79
-rw-r--r--src/apps/asf2mkv/asf2mkv.vcproj315
-rw-r--r--src/apps/asf2mkv/asf2mkvDlg.cpp609
-rw-r--r--src/apps/asf2mkv/asf2mkvDlg.h111
-rw-r--r--src/apps/asf2mkv/res/asf2mkv.icobin0 -> 21630 bytes
-rw-r--r--src/apps/asf2mkv/res/asf2mkv.manifest22
-rw-r--r--src/apps/asf2mkv/res/asf2mkv.rc213
-rw-r--r--src/apps/asf2mkv/resource.h29
-rw-r--r--src/apps/asf2mkv/stdafx.cpp29
-rw-r--r--src/apps/asf2mkv/stdafx.h75
-rw-r--r--src/apps/mpcinfo/Resource.h16
-rw-r--r--src/apps/mpcinfo/doc/mpcinfo.txt72
-rw-r--r--src/apps/mpcinfo/mpcinfo.cpp288
-rw-r--r--src/apps/mpcinfo/mpcinfo.def13
-rw-r--r--src/apps/mpcinfo/mpcinfo.h48
-rw-r--r--src/apps/mpcinfo/mpcinfo.ncbbin0 -> 27648 bytes
-rw-r--r--src/apps/mpcinfo/mpcinfo.rc135
-rw-r--r--src/apps/mpcinfo/mpcinfo.sln21
-rw-r--r--src/apps/mpcinfo/mpcinfo.suobin0 -> 7680 bytes
-rw-r--r--src/apps/mpcinfo/mpcinfo.vcproj190
-rw-r--r--src/apps/mpcinfo/res/mpcinfo.rc213
-rw-r--r--src/apps/mpcinfo/stdafx.cpp28
-rw-r--r--src/apps/mpcinfo/stdafx.h73
-rw-r--r--src/apps/mplayerc/AuthDlg.cpp171
-rw-r--r--src/apps/mplayerc/AuthDlg.h57
-rw-r--r--src/apps/mplayerc/BaseGraph.cpp354
-rw-r--r--src/apps/mplayerc/BaseGraph.h255
-rw-r--r--src/apps/mplayerc/CShockwaveFlash.cpp35
-rw-r--r--src/apps/mplayerc/CShockwaveFlash.h462
-rw-r--r--src/apps/mplayerc/ChildView.cpp284
-rw-r--r--src/apps/mplayerc/ChildView.h65
-rw-r--r--src/apps/mplayerc/ComPropertyPage.cpp109
-rw-r--r--src/apps/mplayerc/ComPropertyPage.h52
-rw-r--r--src/apps/mplayerc/ComPropertySheet.cpp246
-rw-r--r--src/apps/mplayerc/ComPropertySheet.h61
-rw-r--r--src/apps/mplayerc/ConvertChapDlg.cpp92
-rw-r--r--src/apps/mplayerc/ConvertChapDlg.h45
-rw-r--r--src/apps/mplayerc/ConvertDlg.cpp1366
-rw-r--r--src/apps/mplayerc/ConvertDlg.h190
-rw-r--r--src/apps/mplayerc/ConvertPropsDlg.cpp202
-rw-r--r--src/apps/mplayerc/ConvertPropsDlg.h60
-rw-r--r--src/apps/mplayerc/ConvertResDlg.cpp125
-rw-r--r--src/apps/mplayerc/ConvertResDlg.h49
-rw-r--r--src/apps/mplayerc/D3DFont.cpp881
-rw-r--r--src/apps/mplayerc/D3DFont.h58
-rw-r--r--src/apps/mplayerc/DX7AllocatorPresenter.cpp1321
-rw-r--r--src/apps/mplayerc/DX7AllocatorPresenter.h40
-rw-r--r--src/apps/mplayerc/DX9AllocatorPresenter.cpp2447
-rw-r--r--src/apps/mplayerc/DX9AllocatorPresenter.h44
-rw-r--r--src/apps/mplayerc/Debug Unicode/d3dx9_28.dllbin0 -> 2323664 bytes
-rw-r--r--src/apps/mplayerc/DeinterlacerFilter.cpp123
-rw-r--r--src/apps/mplayerc/DeinterlacerFilter.h16
-rw-r--r--src/apps/mplayerc/FGFilter.cpp592
-rw-r--r--src/apps/mplayerc/FGFilter.h138
-rw-r--r--src/apps/mplayerc/FGManager.cpp1840
-rw-r--r--src/apps/mplayerc/FGManager.h164
-rw-r--r--src/apps/mplayerc/FakeFilterMapper2.cpp474
-rw-r--r--src/apps/mplayerc/FakeFilterMapper2.h124
-rw-r--r--src/apps/mplayerc/FavoriteAddDlg.cpp79
-rw-r--r--src/apps/mplayerc/FavoriteAddDlg.h52
-rw-r--r--src/apps/mplayerc/FavoriteOrganizeDlg.cpp284
-rw-r--r--src/apps/mplayerc/FavoriteOrganizeDlg.h65
-rw-r--r--src/apps/mplayerc/FileDropTarget.cpp78
-rw-r--r--src/apps/mplayerc/FileDropTarget.h63
-rw-r--r--src/apps/mplayerc/FloatEdit.cpp157
-rw-r--r--src/apps/mplayerc/FloatEdit.h66
-rw-r--r--src/apps/mplayerc/FullscreenWnd.cpp103
-rw-r--r--src/apps/mplayerc/FullscreenWnd.h32
-rw-r--r--src/apps/mplayerc/GoToDlg.cpp204
-rw-r--r--src/apps/mplayerc/GoToDlg.h56
-rw-r--r--src/apps/mplayerc/History.txt38
-rw-r--r--src/apps/mplayerc/IGraphBuilder2.h44
-rw-r--r--src/apps/mplayerc/IPinHook.cpp475
-rw-r--r--src/apps/mplayerc/IPinHook.h180
-rw-r--r--src/apps/mplayerc/IQTVideoSurface.h33
-rw-r--r--src/apps/mplayerc/ISDb.cpp89
-rw-r--r--src/apps/mplayerc/ISDb.h37
-rw-r--r--src/apps/mplayerc/KeyProvider.cpp53
-rw-r--r--src/apps/mplayerc/KeyProvider.h40
-rw-r--r--src/apps/mplayerc/LineNumberEdit.cpp971
-rw-r--r--src/apps/mplayerc/LineNumberEdit.h99
-rw-r--r--src/apps/mplayerc/MacrovisionKicker.cpp92
-rw-r--r--src/apps/mplayerc/MacrovisionKicker.h44
-rw-r--r--src/apps/mplayerc/MainFrm.cpp10265
-rw-r--r--src/apps/mplayerc/MainFrm.h693
-rw-r--r--src/apps/mplayerc/MediaFormats.cpp344
-rw-r--r--src/apps/mplayerc/MediaFormats.h90
-rw-r--r--src/apps/mplayerc/MediaTypesDlg.cpp340
-rw-r--r--src/apps/mplayerc/MediaTypesDlg.h59
-rw-r--r--src/apps/mplayerc/OpenCapDeviceDlg.cpp448
-rw-r--r--src/apps/mplayerc/OpenCapDeviceDlg.h58
-rw-r--r--src/apps/mplayerc/OpenDlg.cpp195
-rw-r--r--src/apps/mplayerc/OpenDlg.h58
-rw-r--r--src/apps/mplayerc/OpenFileDlg.cpp153
-rw-r--r--src/apps/mplayerc/OpenFileDlg.h59
-rw-r--r--src/apps/mplayerc/PPageAccelTbl.cpp962
-rw-r--r--src/apps/mplayerc/PPageAccelTbl.h85
-rw-r--r--src/apps/mplayerc/PPageAudioSwitcher.cpp338
-rw-r--r--src/apps/mplayerc/PPageAudioSwitcher.h80
-rw-r--r--src/apps/mplayerc/PPageBase.cpp102
-rw-r--r--src/apps/mplayerc/PPageBase.h49
-rw-r--r--src/apps/mplayerc/PPageCasimir.cpp204
-rw-r--r--src/apps/mplayerc/PPageCasimir.h68
-rw-r--r--src/apps/mplayerc/PPageDVD.cpp329
-rw-r--r--src/apps/mplayerc/PPageDVD.h67
-rw-r--r--src/apps/mplayerc/PPageExternalFilters.cpp731
-rw-r--r--src/apps/mplayerc/PPageExternalFilters.h84
-rw-r--r--src/apps/mplayerc/PPageFileInfoClip.cpp110
-rw-r--r--src/apps/mplayerc/PPageFileInfoClip.h58
-rw-r--r--src/apps/mplayerc/PPageFileInfoDetails.cpp309
-rw-r--r--src/apps/mplayerc/PPageFileInfoDetails.h63
-rw-r--r--src/apps/mplayerc/PPageFileInfoRes.cpp151
-rw-r--r--src/apps/mplayerc/PPageFileInfoRes.h60
-rw-r--r--src/apps/mplayerc/PPageFileInfoSheet.cpp79
-rw-r--r--src/apps/mplayerc/PPageFileInfoSheet.h51
-rw-r--r--src/apps/mplayerc/PPageFormats.cpp767
-rw-r--r--src/apps/mplayerc/PPageFormats.h86
-rw-r--r--src/apps/mplayerc/PPageInternalFilters.cpp292
-rw-r--r--src/apps/mplayerc/PPageInternalFilters.h74
-rw-r--r--src/apps/mplayerc/PPageLogo.cpp195
-rw-r--r--src/apps/mplayerc/PPageLogo.h60
-rw-r--r--src/apps/mplayerc/PPageOutput.cpp208
-rw-r--r--src/apps/mplayerc/PPageOutput.h63
-rw-r--r--src/apps/mplayerc/PPagePlayback.cpp210
-rw-r--r--src/apps/mplayerc/PPagePlayback.h73
-rw-r--r--src/apps/mplayerc/PPagePlayer.cpp180
-rw-r--r--src/apps/mplayerc/PPagePlayer.h68
-rw-r--r--src/apps/mplayerc/PPageSheet.cpp121
-rw-r--r--src/apps/mplayerc/PPageSheet.h92
-rw-r--r--src/apps/mplayerc/PPageSubDB.cpp117
-rw-r--r--src/apps/mplayerc/PPageSubDB.h50
-rw-r--r--src/apps/mplayerc/PPageSubStyle.cpp303
-rw-r--r--src/apps/mplayerc/PPageSubStyle.h114
-rw-r--r--src/apps/mplayerc/PPageSubtitles.cpp139
-rw-r--r--src/apps/mplayerc/PPageSubtitles.h61
-rw-r--r--src/apps/mplayerc/PPageTweaks.cpp139
-rw-r--r--src/apps/mplayerc/PPageTweaks.h65
-rw-r--r--src/apps/mplayerc/PPageWebServer.cpp255
-rw-r--r--src/apps/mplayerc/PPageWebServer.h70
-rw-r--r--src/apps/mplayerc/PixelShaderCompiler.cpp111
-rw-r--r--src/apps/mplayerc/PixelShaderCompiler.h64
-rw-r--r--src/apps/mplayerc/PlayerCaptureBar.cpp75
-rw-r--r--src/apps/mplayerc/PlayerCaptureBar.h49
-rw-r--r--src/apps/mplayerc/PlayerCaptureDialog.cpp1659
-rw-r--r--src/apps/mplayerc/PlayerCaptureDialog.h452
-rw-r--r--src/apps/mplayerc/PlayerInfoBar.cpp219
-rw-r--r--src/apps/mplayerc/PlayerInfoBar.h62
-rw-r--r--src/apps/mplayerc/PlayerListCtrl.cpp871
-rw-r--r--src/apps/mplayerc/PlayerListCtrl.h150
-rw-r--r--src/apps/mplayerc/PlayerPlaylistBar.cpp1405
-rw-r--r--src/apps/mplayerc/PlayerPlaylistBar.h118
-rw-r--r--src/apps/mplayerc/PlayerSeekBar.cpp304
-rw-r--r--src/apps/mplayerc/PlayerSeekBar.h73
-rw-r--r--src/apps/mplayerc/PlayerShaderEditorBar.cpp84
-rw-r--r--src/apps/mplayerc/PlayerShaderEditorBar.h52
-rw-r--r--src/apps/mplayerc/PlayerStatusBar.cpp374
-rw-r--r--src/apps/mplayerc/PlayerStatusBar.h71
-rw-r--r--src/apps/mplayerc/PlayerSubresyncBar.cpp1301
-rw-r--r--src/apps/mplayerc/PlayerSubresyncBar.h107
-rw-r--r--src/apps/mplayerc/PlayerToolBar.cpp276
-rw-r--r--src/apps/mplayerc/PlayerToolBar.h69
-rw-r--r--src/apps/mplayerc/Playlist.cpp272
-rw-r--r--src/apps/mplayerc/Playlist.h73
-rw-r--r--src/apps/mplayerc/PnSPresetsDlg.cpp247
-rw-r--r--src/apps/mplayerc/PnSPresetsDlg.h68
-rw-r--r--src/apps/mplayerc/QuicktimeGraph.cpp652
-rw-r--r--src/apps/mplayerc/QuicktimeGraph.h125
-rw-r--r--src/apps/mplayerc/RealMediaGraph.cpp714
-rw-r--r--src/apps/mplayerc/RealMediaGraph.h229
-rw-r--r--src/apps/mplayerc/RealMediaWindowlessSite.cpp710
-rw-r--r--src/apps/mplayerc/RealMediaWindowlessSite.h218
-rw-r--r--src/apps/mplayerc/RegFilterChooserDlg.cpp174
-rw-r--r--src/apps/mplayerc/RegFilterChooserDlg.h56
-rw-r--r--src/apps/mplayerc/Release Unicode/d3dx9_28.dllbin0 -> 2323664 bytes
-rw-r--r--src/apps/mplayerc/SaveDlg.cpp232
-rw-r--r--src/apps/mplayerc/SaveDlg.h61
-rw-r--r--src/apps/mplayerc/SaveTextFileDialog.cpp93
-rw-r--r--src/apps/mplayerc/SaveTextFileDialog.h56
-rw-r--r--src/apps/mplayerc/SaveThumbnailsDialog.cpp91
-rw-r--r--src/apps/mplayerc/SaveThumbnailsDialog.h50
-rw-r--r--src/apps/mplayerc/SelectMediaType.cpp101
-rw-r--r--src/apps/mplayerc/SelectMediaType.h55
-rw-r--r--src/apps/mplayerc/ShaderAutoCompleteDlg.cpp179
-rw-r--r--src/apps/mplayerc/ShaderAutoCompleteDlg.h33
-rw-r--r--src/apps/mplayerc/ShaderCombineDlg.cpp131
-rw-r--r--src/apps/mplayerc/ShaderCombineDlg.h38
-rw-r--r--src/apps/mplayerc/ShaderEditorDlg.cpp482
-rw-r--r--src/apps/mplayerc/ShaderEditorDlg.h81
-rw-r--r--src/apps/mplayerc/ShockwaveGraph.cpp232
-rw-r--r--src/apps/mplayerc/ShockwaveGraph.h79
-rw-r--r--src/apps/mplayerc/StaticLink.cpp171
-rw-r--r--src/apps/mplayerc/StaticLink.h81
-rw-r--r--src/apps/mplayerc/StatusLabel.cpp98
-rw-r--r--src/apps/mplayerc/StatusLabel.h47
-rw-r--r--src/apps/mplayerc/StdAfx.cpp27
-rw-r--r--src/apps/mplayerc/StdAfx.h68
-rw-r--r--src/apps/mplayerc/SubtitleDlDlg.cpp153
-rw-r--r--src/apps/mplayerc/SubtitleDlDlg.h42
-rw-r--r--src/apps/mplayerc/TextPassThruFilter.cpp249
-rw-r--r--src/apps/mplayerc/TextPassThruFilter.h46
-rw-r--r--src/apps/mplayerc/VMROSD.cpp302
-rw-r--r--src/apps/mplayerc/VMROSD.h89
-rw-r--r--src/apps/mplayerc/VolumeCtrl.cpp186
-rw-r--r--src/apps/mplayerc/VolumeCtrl.h51
-rw-r--r--src/apps/mplayerc/WebClientSocket.cpp727
-rw-r--r--src/apps/mplayerc/WebClientSocket.h44
-rw-r--r--src/apps/mplayerc/WebServer.cpp614
-rw-r--r--src/apps/mplayerc/WebServer.h50
-rw-r--r--src/apps/mplayerc/WebServerSocket.cpp22
-rw-r--r--src/apps/mplayerc/WebServerSocket.h15
-rw-r--r--src/apps/mplayerc/jpeg.cpp404
-rw-r--r--src/apps/mplayerc/jpeg.h59
-rw-r--r--src/apps/mplayerc/jpeg_tables.h233
-rw-r--r--src/apps/mplayerc/mplayerc.apsbin0 -> 1184196 bytes
-rw-r--r--src/apps/mplayerc/mplayerc.cpp2408
-rw-r--r--src/apps/mplayerc/mplayerc.h580
-rw-r--r--src/apps/mplayerc/mplayerc.ncbbin0 -> 8162304 bytes
-rw-r--r--src/apps/mplayerc/mplayerc.rc2825
-rw-r--r--src/apps/mplayerc/mplayerc.sln147
-rw-r--r--src/apps/mplayerc/mplayerc.suobin0 -> 38400 bytes
-rw-r--r--src/apps/mplayerc/mplayerc.vcproj1927
-rw-r--r--src/apps/mplayerc/mplayerc.vcproj.vspscc10
-rw-r--r--src/apps/mplayerc/mplayerc.vssscc10
-rw-r--r--src/apps/mplayerc/res/Icon_114.icobin0 -> 23558 bytes
-rw-r--r--src/apps/mplayerc/res/Icon_116.icobin0 -> 22486 bytes
-rw-r--r--src/apps/mplayerc/res/Icon_41.icobin0 -> 5854 bytes
-rw-r--r--src/apps/mplayerc/res/ani.avibin0 -> 14848 bytes
-rw-r--r--src/apps/mplayerc/res/authhdrpic.bmpbin0 -> 57654 bytes
-rw-r--r--src/apps/mplayerc/res/icon.icobin0 -> 1078 bytes
-rw-r--r--src/apps/mplayerc/res/logo.0.bmpbin0 -> 122 bytes
-rw-r--r--src/apps/mplayerc/res/logo.1.bmpbin0 -> 78934 bytes
-rw-r--r--src/apps/mplayerc/res/logo.2.bmpbin0 -> 117078 bytes
-rw-r--r--src/apps/mplayerc/res/logo.3.bmpbin0 -> 63554 bytes
-rw-r--r--src/apps/mplayerc/res/logo.4.bmpbin0 -> 91814 bytes
-rw-r--r--src/apps/mplayerc/res/logo.5.bmpbin0 -> 31402 bytes
-rw-r--r--src/apps/mplayerc/res/logo.6.bmpbin0 -> 163154 bytes
-rw-r--r--src/apps/mplayerc/res/logo.7.bmpbin0 -> 143406 bytes
-rw-r--r--src/apps/mplayerc/res/mono.bmpbin0 -> 1582 bytes
-rw-r--r--src/apps/mplayerc/res/mpc.pngbin0 -> 9145 bytes
-rw-r--r--src/apps/mplayerc/res/mplayerc.manifest23
-rw-r--r--src/apps/mplayerc/res/multi.icobin0 -> 766 bytes
-rw-r--r--src/apps/mplayerc/res/noaudio.bmpbin0 -> 1666 bytes
-rw-r--r--src/apps/mplayerc/res/onoff.bmpbin0 -> 358 bytes
-rw-r--r--src/apps/mplayerc/res/shaders/EdgeSharpen.psh63
-rw-r--r--src/apps/mplayerc/res/shaders/SharpenComplex.psh82
-rw-r--r--src/apps/mplayerc/res/shaders/contour.psh30
-rw-r--r--src/apps/mplayerc/res/shaders/deinterlace (blend).psh24
-rw-r--r--src/apps/mplayerc/res/shaders/emboss.psh30
-rw-r--r--src/apps/mplayerc/res/shaders/empty.psh19
-rw-r--r--src/apps/mplayerc/res/shaders/grayscale.psh19
-rw-r--r--src/apps/mplayerc/res/shaders/invert.psh19
-rw-r--r--src/apps/mplayerc/res/shaders/letterbox.psh25
-rw-r--r--src/apps/mplayerc/res/shaders/procamp.psh61
-rw-r--r--src/apps/mplayerc/res/shaders/resizer.psh105
-rw-r--r--src/apps/mplayerc/res/shaders/sharpen.psh30
-rw-r--r--src/apps/mplayerc/res/shaders/sphere.psh60
-rw-r--r--src/apps/mplayerc/res/shaders/spotlight.psh22
-rw-r--r--src/apps/mplayerc/res/shaders/wave.psh29
-rw-r--r--src/apps/mplayerc/res/single.icobin0 -> 766 bytes
-rw-r--r--src/apps/mplayerc/res/stereo.bmpbin0 -> 1834 bytes
-rw-r--r--src/apps/mplayerc/res/streamtypes.bmpbin0 -> 6966 bytes
-rw-r--r--src/apps/mplayerc/res/toolbar1.bmpbin0 -> 2038 bytes
-rw-r--r--src/apps/mplayerc/res/web/1pix.gifbin0 -> 43 bytes
-rw-r--r--src/apps/mplayerc/res/web/404.html10
-rw-r--r--src/apps/mplayerc/res/web/bottomside.pngbin0 -> 97 bytes
-rw-r--r--src/apps/mplayerc/res/web/browser.html28
-rw-r--r--src/apps/mplayerc/res/web/controlback.pngbin0 -> 148 bytes
-rw-r--r--src/apps/mplayerc/res/web/controlbuttondecrate.pngbin0 -> 181 bytes
-rw-r--r--src/apps/mplayerc/res/web/controlbuttonincrate.pngbin0 -> 174 bytes
-rw-r--r--src/apps/mplayerc/res/web/controlbuttonpause.pngbin0 -> 143 bytes
-rw-r--r--src/apps/mplayerc/res/web/controlbuttonplay.pngbin0 -> 237 bytes
-rw-r--r--src/apps/mplayerc/res/web/controlbuttonskipback.pngbin0 -> 190 bytes
-rw-r--r--src/apps/mplayerc/res/web/controlbuttonskipforward.pngbin0 -> 190 bytes
-rw-r--r--src/apps/mplayerc/res/web/controlbuttonstep.pngbin0 -> 183 bytes
-rw-r--r--src/apps/mplayerc/res/web/controlbuttonstop.pngbin0 -> 149 bytes
-rw-r--r--src/apps/mplayerc/res/web/controls.html1735
-rw-r--r--src/apps/mplayerc/res/web/controlvolumebar.pngbin0 -> 239 bytes
-rw-r--r--src/apps/mplayerc/res/web/controlvolumegrip.pngbin0 -> 173 bytes
-rw-r--r--src/apps/mplayerc/res/web/controlvolumeoff.pngbin0 -> 410 bytes
-rw-r--r--src/apps/mplayerc/res/web/controlvolumeon.pngbin0 -> 270 bytes
-rw-r--r--src/apps/mplayerc/res/web/default.css5
-rw-r--r--src/apps/mplayerc/res/web/headerback.pngbin0 -> 161 bytes
-rw-r--r--src/apps/mplayerc/res/web/headerclose.pngbin0 -> 1658 bytes
-rw-r--r--src/apps/mplayerc/res/web/headericon.pngbin0 -> 801 bytes
-rw-r--r--src/apps/mplayerc/res/web/index.html35
-rw-r--r--src/apps/mplayerc/res/web/leftbottomside.pngbin0 -> 180 bytes
-rw-r--r--src/apps/mplayerc/res/web/leftside.pngbin0 -> 151 bytes
-rw-r--r--src/apps/mplayerc/res/web/logo.pngbin0 -> 61474 bytes
-rw-r--r--src/apps/mplayerc/res/web/player.html303
-rw-r--r--src/apps/mplayerc/res/web/rightbottomside.pngbin0 -> 118 bytes
-rw-r--r--src/apps/mplayerc/res/web/rightside.pngbin0 -> 95 bytes
-rw-r--r--src/apps/mplayerc/res/web/seekbargrip.pngbin0 -> 158 bytes
-rw-r--r--src/apps/mplayerc/res/web/seekbarleft.pngbin0 -> 112 bytes
-rw-r--r--src/apps/mplayerc/res/web/seekbarmid.pngbin0 -> 100 bytes
-rw-r--r--src/apps/mplayerc/res/web/seekbarright.pngbin0 -> 107 bytes
-rw-r--r--src/apps/mplayerc/res/web/sliderback.gifbin0 -> 351 bytes
-rw-r--r--src/apps/mplayerc/res/web/sliderbar.gifbin0 -> 91 bytes
-rw-r--r--src/apps/mplayerc/res/web/slidergrip.gifbin0 -> 157 bytes
-rw-r--r--src/apps/mplayerc/res/web/vbg.GIFbin0 -> 228 bytes
-rw-r--r--src/apps/mplayerc/res/web/vbs.GIFbin0 -> 127 bytes
-rw-r--r--src/apps/mplayerc/resource.h758
-rw-r--r--src/apps/subresync/res/bitmap1.bmpbin0 -> 742 bytes
-rw-r--r--src/apps/subresync/res/bitmap2.bmpbin0 -> 378 bytes
-rw-r--r--src/apps/subresync/res/subresync.icobin0 -> 21630 bytes
-rw-r--r--src/apps/subresync/res/subresync.manifest22
-rw-r--r--src/apps/subresync/res/subresync.rc213
-rw-r--r--src/apps/subresync/resource.h56
-rw-r--r--src/apps/subresync/stdafx.cpp28
-rw-r--r--src/apps/subresync/stdafx.h63
-rw-r--r--src/apps/subresync/subresync.cpp98
-rw-r--r--src/apps/subresync/subresync.h53
-rw-r--r--src/apps/subresync/subresync.rc352
-rw-r--r--src/apps/subresync/subresync.sln21
-rw-r--r--src/apps/subresync/subresync.vcproj177
-rw-r--r--src/apps/subresync/subresyncDlg.cpp169
-rw-r--r--src/apps/subresync/subresyncDlg.h97
-rw-r--r--src/apps/vsconv/Resource.h20
-rw-r--r--src/apps/vsconv/res/vsconv.icobin0 -> 21630 bytes
-rw-r--r--src/apps/vsconv/res/vsconv.manifest22
-rw-r--r--src/apps/vsconv/res/vsconv.rc213
-rw-r--r--src/apps/vsconv/stdafx.cpp28
-rw-r--r--src/apps/vsconv/stdafx.h65
-rw-r--r--src/apps/vsconv/vsconv.cpp197
-rw-r--r--src/apps/vsconv/vsconv.h52
-rw-r--r--src/apps/vsconv/vsconv.rc199
-rw-r--r--src/apps/vsconv/vsconv.sln40
-rw-r--r--src/apps/vsconv/vsconv.vcproj321
-rw-r--r--src/apps/vsconv/vsconvDlg.cpp169
-rw-r--r--src/apps/vsconv/vsconvDlg.h52
-rw-r--r--src/apps/vsrip/VSRip.cpp82
-rw-r--r--src/apps/vsrip/VSRip.h52
-rw-r--r--src/apps/vsrip/VSRip.rc263
-rw-r--r--src/apps/vsrip/VSRip.sln53
-rw-r--r--src/apps/vsrip/VSRip.vcproj349
-rw-r--r--src/apps/vsrip/VSRipDlg.cpp312
-rw-r--r--src/apps/vsrip/VSRipDlg.h71
-rw-r--r--src/apps/vsrip/VSRipFileDlg.cpp112
-rw-r--r--src/apps/vsrip/VSRipFileDlg.h61
-rw-r--r--src/apps/vsrip/VSRipIndexingDlg.cpp179
-rw-r--r--src/apps/vsrip/VSRipIndexingDlg.h73
-rw-r--r--src/apps/vsrip/VSRipPGCDlg.cpp247
-rw-r--r--src/apps/vsrip/VSRipPGCDlg.h71
-rw-r--r--src/apps/vsrip/VSRipPage.cpp62
-rw-r--r--src/apps/vsrip/VSRipPage.h60
-rw-r--r--src/apps/vsrip/res/VSRip.icobin0 -> 21630 bytes
-rw-r--r--src/apps/vsrip/res/VSRip.manifest22
-rw-r--r--src/apps/vsrip/res/VSRip.rc213
-rw-r--r--src/apps/vsrip/resource.h37
-rw-r--r--src/apps/vsrip/stdafx.cpp28
-rw-r--r--src/apps/vsrip/stdafx.h64
353 files changed, 72293 insertions, 0 deletions
diff --git a/src/apps/asf2mkv/asf2mkv.cpp b/src/apps/asf2mkv/asf2mkv.cpp
new file mode 100644
index 000000000..d7fcc1e4d
--- /dev/null
+++ b/src/apps/asf2mkv/asf2mkv.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// asf2mkv.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "asf2mkv.h"
+#include "asf2mkvDlg.h"
+#include ".\asf2mkv.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+// Casf2mkvApp
+
+BEGIN_MESSAGE_MAP(Casf2mkvApp, CWinApp)
+ ON_COMMAND(ID_HELP, CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// Casf2mkvApp construction
+
+Casf2mkvApp::Casf2mkvApp()
+{
+ // TODO: add construction code here,
+ // Place all significant initialization in InitInstance
+}
+
+
+// The one and only Casf2mkvApp object
+
+Casf2mkvApp theApp;
+
+
+// Casf2mkvApp initialization
+
+BOOL Casf2mkvApp::InitInstance()
+{
+ // InitCommonControls() is required on Windows XP if an application
+ // manifest specifies use of ComCtl32.dll version 6 or later to enable
+ // visual styles. Otherwise, any window creation will fail.
+ InitCommonControls();
+
+ CWinApp::InitInstance();
+
+ // Standard initialization
+ // If you are not using these features and wish to reduce the size
+ // of your final executable, you should remove from the following
+ // the specific initialization routines you do not need
+ // Change the registry key under which our settings are stored
+ // TODO: You should modify this string to be something appropriate
+ // such as the name of your company or organization
+ SetRegistryKey(_T("Gabest"));
+
+ HRESULT hr;
+ if(FAILED(hr = OleInitialize(0)))
+ {
+ AfxMessageBox(_T("OleInitialize failed!"));
+ return FALSE;
+ }
+
+ Casf2mkvDlg dlg;
+ m_pMainWnd = &dlg;
+ INT_PTR nResponse = dlg.DoModal();
+ if (nResponse == IDOK)
+ {
+ // TODO: Place code here to handle when the dialog is
+ // dismissed with OK
+ }
+ else if (nResponse == IDCANCEL)
+ {
+ // TODO: Place code here to handle when the dialog is
+ // dismissed with Cancel
+ }
+
+ // Since the dialog has been closed, return FALSE so that we exit the
+ // application, rather than start the application's message pump.
+ return FALSE;
+}
+
+int Casf2mkvApp::ExitInstance()
+{
+ OleUninitialize();
+
+ return CWinApp::ExitInstance();
+}
diff --git a/src/apps/asf2mkv/asf2mkv.h b/src/apps/asf2mkv/asf2mkv.h
new file mode 100644
index 000000000..e6e49dbfb
--- /dev/null
+++ b/src/apps/asf2mkv/asf2mkv.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// asf2mkv.h : main header file for the PROJECT_NAME application
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h" // main symbols
+
+
+// Casf2mkvApp:
+// See asf2mkv.cpp for the implementation of this class
+//
+
+class Casf2mkvApp : public CWinApp
+{
+public:
+ Casf2mkvApp();
+
+// Overrides
+ public:
+ virtual BOOL InitInstance();
+
+// Implementation
+
+ DECLARE_MESSAGE_MAP()
+ virtual int ExitInstance();
+};
+
+extern Casf2mkvApp theApp; \ No newline at end of file
diff --git a/src/apps/asf2mkv/asf2mkv.rc b/src/apps/asf2mkv/asf2mkv.rc
new file mode 100644
index 000000000..4a4b4aa60
--- /dev/null
+++ b/src/apps/asf2mkv/asf2mkv.rc
@@ -0,0 +1,219 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Hungarian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_HUN)
+#ifdef _WIN32
+LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
+#pragma code_page(1250)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#include ""res\\asf2mkv.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON "res\\asf2mkv.ico"
+#endif // Hungarian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 235, 55
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "About asf2mkv"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
+ LTEXT "asf2mkv Version 1.01",IDC_STATIC,40,10,119,8,
+ SS_NOPREFIX
+ LTEXT "Copyright (C) 2003-2004",IDC_STATIC,40,25,119,8
+ DEFPUSHBUTTON "OK",IDOK,178,7,50,16,WS_GROUP
+END
+
+IDD_ASF2MKV_DIALOG DIALOGEX 0, 0, 204, 167
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX |
+ WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "asf2mkv"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "Record!",IDC_BUTTON1,147,146,50,14
+ CONTROL "",IDC_STATIC1,"Static",SS_BLACKRECT,7,7,190,119,
+ WS_EX_CLIENTEDGE
+ COMBOBOX IDC_COMBO1,7,129,190,91,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "Settings...",IDC_BUTTON2,95,146,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "Comments", "http://gabest.org/"
+ VALUE "CompanyName", "Gabest"
+ VALUE "FileDescription", "Records streaming windows media into the matroska container format."
+ VALUE "FileVersion", "1, 0, 0, 1"
+ VALUE "InternalName", "asf2mkv.exe"
+ VALUE "LegalCopyright", "Copyright (C) 2003-2005 Gabest. All rights reserved."
+ VALUE "OriginalFilename", "asf2mkv.exe"
+ VALUE "ProductName", "asf2mkv recorder"
+ VALUE "ProductVersion", "1, 0, 0, 1"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_ABOUTBOX, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 228
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 48
+ END
+
+ IDD_ASF2MKV_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 197
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 160
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_ABOUTBOX "&About asf2mkv..."
+ IDS_RECORD "Record!"
+ IDS_STOP "Stop"
+ IDS_TITLE "asf2mkv recorder"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#include "res\asf2mkv.rc2" // non-Microsoft Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/src/apps/asf2mkv/asf2mkv.sln b/src/apps/asf2mkv/asf2mkv.sln
new file mode 100644
index 000000000..91947b933
--- /dev/null
+++ b/src/apps/asf2mkv/asf2mkv.sln
@@ -0,0 +1,79 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asf2mkv", "asf2mkv.vcproj", "{B4E3D650-306F-4F9B-A7DD-2F70C2F69007}"
+ ProjectSection(ProjectDependencies) = postProject
+ {03208025-D5C2-426A-B0FA-251D4338F30C} = {03208025-D5C2-426A-B0FA-251D4338F30C}
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0} = {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}
+ {FC70988B-1AE5-4381-866D-4F405E28AC42} = {FC70988B-1AE5-4381-866D-4F405E28AC42}
+ {EAFA80A3-EF50-4D3F-AAC6-3D7CD873B90F} = {EAFA80A3-EF50-4D3F-AAC6-3D7CD873B90F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CmdUI", "..\..\ui\CmdUI\CmdUI.vcproj", "{03208025-D5C2-426A-B0FA-251D4338F30C}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ResizableLib", "..\..\ui\ResizableLib\ResizableLib.vcproj", "{4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dsutil", "..\..\dsutil\dsutil.vcproj", "{FC70988B-1AE5-4381-866D-4F405E28AC42}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BaseClasses", "C:\Program Files\Microsoft DirectX 9.0 SDK (October 2004)\Samples\C++\DirectShow\BaseClasses\baseclasses.vcproj", "{EAFA80A3-EF50-4D3F-AAC6-3D7CD873B90F}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Debug Unicode = Debug Unicode
+ Release = Release
+ Release Unicode = Release Unicode
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {B4E3D650-306F-4F9B-A7DD-2F70C2F69007}.Debug.ActiveCfg = Debug|Win32
+ {B4E3D650-306F-4F9B-A7DD-2F70C2F69007}.Debug.Build.0 = Debug|Win32
+ {B4E3D650-306F-4F9B-A7DD-2F70C2F69007}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {B4E3D650-306F-4F9B-A7DD-2F70C2F69007}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {B4E3D650-306F-4F9B-A7DD-2F70C2F69007}.Release.ActiveCfg = Release|Win32
+ {B4E3D650-306F-4F9B-A7DD-2F70C2F69007}.Release.Build.0 = Release|Win32
+ {B4E3D650-306F-4F9B-A7DD-2F70C2F69007}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {B4E3D650-306F-4F9B-A7DD-2F70C2F69007}.Release Unicode.Build.0 = Release Unicode|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Debug.ActiveCfg = Debug|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Debug.Build.0 = Debug|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Release.ActiveCfg = Release|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Release.Build.0 = Release|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Release Unicode.Build.0 = Release Unicode|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Debug.ActiveCfg = Debug|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Debug.Build.0 = Debug|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Release.ActiveCfg = Release|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Release.Build.0 = Release|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Release Unicode.Build.0 = Release Unicode|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Debug.ActiveCfg = Debug|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Debug.Build.0 = Debug|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Release.ActiveCfg = Release|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Release.Build.0 = Release|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Release Unicode.Build.0 = Release Unicode|Win32
+ {EAFA80A3-EF50-4D3F-AAC6-3D7CD873B90F}.Debug.ActiveCfg = Debug|Win32
+ {EAFA80A3-EF50-4D3F-AAC6-3D7CD873B90F}.Debug.Build.0 = Debug|Win32
+ {EAFA80A3-EF50-4D3F-AAC6-3D7CD873B90F}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {EAFA80A3-EF50-4D3F-AAC6-3D7CD873B90F}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {EAFA80A3-EF50-4D3F-AAC6-3D7CD873B90F}.Release.ActiveCfg = Release|Win32
+ {EAFA80A3-EF50-4D3F-AAC6-3D7CD873B90F}.Release.Build.0 = Release|Win32
+ {EAFA80A3-EF50-4D3F-AAC6-3D7CD873B90F}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {EAFA80A3-EF50-4D3F-AAC6-3D7CD873B90F}.Release Unicode.Build.0 = Release Unicode|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/src/apps/asf2mkv/asf2mkv.vcproj b/src/apps/asf2mkv/asf2mkv.vcproj
new file mode 100644
index 000000000..07b623c7e
--- /dev/null
+++ b/src/apps/asf2mkv/asf2mkv.vcproj
@@ -0,0 +1,315 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="asf2mkv"
+ ProjectGUID="{B4E3D650-306F-4F9B-A7DD-2F70C2F69007}"
+ Keyword="MFCProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ UseOfMFC="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="strmbaseD.lib filtersD.lib dsutilD.lib uiD.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="..\..\..\lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ MinimalRebuild="FALSE"
+ RuntimeLibrary="0"
+ TreatWChar_tAsBuiltInType="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="strmbaseR.lib filtersR.lib dsutilR.lib uiR.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="..\..\..\lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ UseOfMFC="2"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="strmbaseDU.lib filtersDU.lib dsutilDU.lib uiDU.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="..\..\..\lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ MinimalRebuild="FALSE"
+ RuntimeLibrary="0"
+ TreatWChar_tAsBuiltInType="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="strmbaseRU.lib filtersRU.lib dsutilRU.lib uiRU.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="..\..\..\lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\asf2mkv.cpp">
+ </File>
+ <File
+ RelativePath=".\asf2mkvDlg.cpp">
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\asf2mkv.h">
+ </File>
+ <File
+ RelativePath=".\asf2mkvDlg.h">
+ </File>
+ <File
+ RelativePath=".\Resource.h">
+ </File>
+ <File
+ RelativePath=".\stdafx.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ <File
+ RelativePath=".\res\asf2mkv.ico">
+ </File>
+ <File
+ RelativePath=".\asf2mkv.rc">
+ </File>
+ <File
+ RelativePath=".\res\asf2mkv.rc2">
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\res\asf2mkv.manifest">
+ </File>
+ </Files>
+ <Globals>
+ <Global
+ Name="RESOURCE_FILE"
+ Value="asf2mkv.rc"/>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/apps/asf2mkv/asf2mkvDlg.cpp b/src/apps/asf2mkv/asf2mkvDlg.cpp
new file mode 100644
index 000000000..cd0775abc
--- /dev/null
+++ b/src/apps/asf2mkv/asf2mkvDlg.cpp
@@ -0,0 +1,609 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// asf2mkvDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "asf2mkv.h"
+#include "asf2mkvDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+#include <initguid.h>
+#include ".\asf2mkvdlg.h"
+
+// {6B6D0800-9ADA-11d0-A520-00A0D10129C0}
+DEFINE_GUID(CLSID_NetShowSource,
+0x6b6d0800, 0x9ada, 0x11d0, 0xa5, 0x20, 0x0, 0xa0, 0xd1, 0x1, 0x29, 0xc0);
+
+// CAboutDlg dialog used for App About
+
+class CAboutDlg : public CDialog
+{
+public:
+ CAboutDlg();
+
+// Dialog Data
+ enum { IDD = IDD_ABOUTBOX };
+
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+// Implementation
+protected:
+ DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+END_MESSAGE_MAP()
+
+// CUrlDropTarget
+
+BEGIN_MESSAGE_MAP(CUrlDropTarget, COleDropTarget)
+END_MESSAGE_MAP()
+
+DROPEFFECT CUrlDropTarget::OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
+{
+ return DROPEFFECT_NONE;
+}
+
+DROPEFFECT CUrlDropTarget::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
+{
+ UINT CF_URL = RegisterClipboardFormat(_T("UniformResourceLocator"));
+ return pDataObject->IsDataAvailable(CF_URL) ? DROPEFFECT_COPY : DROPEFFECT_NONE;
+}
+
+BOOL CUrlDropTarget::OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
+{
+ UINT CF_URL = RegisterClipboardFormat(_T("UniformResourceLocator"));
+
+ BOOL bResult = FALSE;
+
+ if(pDataObject->IsDataAvailable(CF_URL))
+ {
+ FORMATETC fmt = {CF_URL, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ if(HGLOBAL hGlobal = pDataObject->GetGlobalData(CF_URL, &fmt))
+ {
+ LPCSTR pText = (LPCSTR)GlobalLock(hGlobal);
+ if(AfxIsValidString(pText))
+ {
+ AfxGetMainWnd()->SendMessage(WM_OPENURL, 0, (LPARAM)pText);
+ GlobalUnlock(hGlobal);
+ bResult = TRUE;
+ }
+ }
+ }
+
+ return bResult;
+}
+
+DROPEFFECT CUrlDropTarget::OnDropEx(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point)
+{
+ return (DROPEFFECT)-1;
+}
+
+void CUrlDropTarget::OnDragLeave(CWnd* pWnd)
+{
+}
+
+DROPEFFECT CUrlDropTarget::OnDragScroll(CWnd* pWnd, DWORD dwKeyState, CPoint point)
+{
+ return DROPEFFECT_NONE;
+}
+
+// Casf2mkvDlg dialog
+
+#define WM_GRAPHNOTIFY (WM_APP+1)
+
+Casf2mkvDlg::Casf2mkvDlg(CWnd* pParent /*=NULL*/)
+ : CResizableDialog(Casf2mkvDlg::IDD, pParent)
+ , m_fRecording(false)
+ , m_mru(0, _T("MRU"), _T("file%d"), 20, 10)
+{
+ m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+void Casf2mkvDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_COMBO1, m_combo);
+ DDX_Control(pDX, IDC_STATIC1, m_video);
+}
+
+
+void Casf2mkvDlg::SetupCombo()
+{
+ m_combo.ResetContent();
+ for(int i = 0; i < m_mru.GetSize(); i++)
+ if(!m_mru[i].IsEmpty())
+ m_combo.AddString(m_mru[i]);
+}
+
+void Casf2mkvDlg::SetVideoRect()
+{
+ if(pVW)
+ {
+ CRect r;
+ m_video.GetWindowRect(r);
+ r -= r.TopLeft();
+ pVW->SetWindowPosition(r.left, r.top, r.Width(), r.Height());
+ }
+}
+
+BEGIN_MESSAGE_MAP(Casf2mkvDlg, CResizableDialog)
+ ON_WM_SYSCOMMAND()
+ ON_WM_PAINT()
+ ON_WM_QUERYDRAGICON()
+ ON_MESSAGE(WM_GRAPHNOTIFY, OnGraphNotify)
+ ON_BN_CLICKED(IDC_BUTTON1, OnRecord)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateRecord)
+ ON_UPDATE_COMMAND_UI(IDC_COMBO1, OnUpdateFileName)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateSettings)
+ ON_UPDATE_COMMAND_UI(IDC_CHECK2, OnUpdateSettings)
+ ON_WM_SIZE()
+ ON_WM_TIMER()
+ ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
+ ON_MESSAGE(WM_APP, OnUrlOpen)
+END_MESSAGE_MAP()
+
+
+// Casf2mkvDlg message handlers
+
+BOOL Casf2mkvDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ // Add "About..." menu item to system menu.
+
+ // IDM_ABOUTBOX must be in the system command range.
+ ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+ ASSERT(IDM_ABOUTBOX < 0xF000);
+
+ CMenu* pSysMenu = GetSystemMenu(FALSE);
+ if (pSysMenu != NULL)
+ {
+ CString strAboutMenu;
+ strAboutMenu.LoadString(IDS_ABOUTBOX);
+ if (!strAboutMenu.IsEmpty())
+ {
+ pSysMenu->AppendMenu(MF_SEPARATOR);
+ pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+ }
+ }
+
+ // Set the icon for this dialog. The framework does this automatically
+ // when the application's main window is not a dialog
+ SetIcon(m_hIcon, TRUE); // Set big icon
+ SetIcon(m_hIcon, FALSE); // Set small icon
+
+ // TODO: Add extra initialization here
+
+ AddAnchor(IDC_STATIC1, TOP_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_COMBO1, BOTTOM_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_BUTTON1, BOTTOM_RIGHT);
+ AddAnchor(IDC_BUTTON2, BOTTOM_RIGHT);
+
+ m_mru.ReadList();
+ SetupCombo();
+
+ m_video.ModifyStyle(0, WS_CLIPCHILDREN);
+
+ SetWindowText(ResStr(IDS_TITLE));
+
+ m_urlDropTarget.Register(this);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+}
+
+BOOL Casf2mkvDlg::DestroyWindow()
+{
+ m_urlDropTarget.Revoke();
+
+ return __super::DestroyWindow();
+}
+
+void Casf2mkvDlg::OnSysCommand(UINT nID, LPARAM lParam)
+{
+ if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+ {
+ CAboutDlg dlgAbout;
+ dlgAbout.DoModal();
+ }
+ else
+ {
+ __super::OnSysCommand(nID, lParam);
+ }
+}
+
+// If you add a minimize button to your dialog, you will need the code below
+// to draw the icon. For MFC applications using the document/view model,
+// this is automatically done for you by the framework.
+
+void Casf2mkvDlg::OnPaint()
+{
+ if (IsIconic())
+ {
+ CPaintDC dc(this); // device context for painting
+
+ SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
+
+ // Center icon in client rectangle
+ int cxIcon = GetSystemMetrics(SM_CXICON);
+ int cyIcon = GetSystemMetrics(SM_CYICON);
+ CRect rect;
+ GetClientRect(&rect);
+ int x = (rect.Width() - cxIcon + 1) / 2;
+ int y = (rect.Height() - cyIcon + 1) / 2;
+
+ // Draw the icon
+ dc.DrawIcon(x, y, m_hIcon);
+ }
+ else
+ {
+ __super::OnPaint();
+ }
+}
+
+// The system calls this function to obtain the cursor to display while the user drags
+// the minimized window.
+HCURSOR Casf2mkvDlg::OnQueryDragIcon()
+{
+ return static_cast<HCURSOR>(m_hIcon);
+}
+
+
+LRESULT Casf2mkvDlg::OnGraphNotify(WPARAM wParam, LPARAM lParam)
+{
+ HRESULT hr = S_OK;
+
+ LONG evCode, evParam1, evParam2;
+ while(pME && SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR*)&evParam1, (LONG_PTR*)&evParam2, 0)))
+ {
+ hr = pME->FreeEventParams(evCode, evParam1, evParam2);
+
+ if(EC_COMPLETE == evCode)
+ {
+ if(m_fRecording)
+ {
+ OnRecord();
+ break;
+ }
+ }
+ }
+
+ return hr;
+}
+
+void Casf2mkvDlg::OnRecord()
+{
+ UpdateData();
+
+ HRESULT hr;
+
+ if(!m_fRecording)
+ {
+ m_fRecording = true;
+
+ UpdateDialogControls(this, FALSE);
+
+ hr = E_FAIL;
+
+ do
+ {
+ // i/o
+
+ CString src;
+ m_combo.GetWindowText(src);
+
+ CFileDialog fd(
+ FALSE, _T("mkv"), m_dst,
+ OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_EXPLORER|OFN_ENABLESIZING,
+ _T("Matroska file (*.mkv;*.mka)|*.mkv;*.mka||"),
+ this);
+ if(fd.DoModal() != IDOK) break;
+ m_dst = fd.GetPathName();
+
+ m_mru.Add(src);
+ m_mru.WriteList();
+ SetupCombo();
+ m_combo.SetWindowText(src);
+
+ if(src.Trim().IsEmpty() || m_dst.Trim().IsEmpty())
+ break;
+
+ // filer graph
+
+ if(FAILED(hr = pGB.CoCreateInstance(CLSID_FilterGraph)))
+ break;
+
+ pMC = pGB; pME = pGB; pMS = pGB; pVW = pGB; pBV = pGB;
+ if(!pMC || !pME || !pMS || !pVW || !pBV)
+ break;
+
+ if(FAILED(hr = pME->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0)))
+ break;
+
+ // windows media source filter
+
+ CComPtr<IBaseFilter> pSrc;
+ if(FAILED(hr = pSrc.CoCreateInstance(CLSID_NetShowSource))
+ || FAILED(hr = pGB->AddFilter(pSrc, CStringW(src)))
+ || FAILED(hr = CComQIPtr<IFileSourceFilter>(pSrc)->Load(CStringW(src), NULL)))
+ break;
+
+ // matroska muxer
+
+ CComPtr<IBaseFilter> pMux;
+ if(FAILED(hr = pMux.CoCreateInstance(__uuidof(CMatroskaMuxerFilter)))
+ && !(pMux = new CMatroskaMuxerFilter(NULL, NULL))
+ || FAILED(hr = pGB->AddFilter(pMux, L"Matroska Muxer")))
+ break;
+
+ BeginEnumPins(pSrc, pEP, pPin)
+ if(FAILED(hr = pGB->Connect(pPin, GetFirstDisconnectedPin(pMux, PINDIR_INPUT))))
+ break;
+ EndEnumPins
+
+ if(FAILED(hr))
+ break;
+
+ // file writer
+
+ CComPtr<IBaseFilter> pFW;
+ if(FAILED(hr = pFW.CoCreateInstance(CLSID_FileWriter))
+ || FAILED(hr = pGB->AddFilter(pFW, CStringW(m_dst)))
+ || FAILED(hr = CComQIPtr<IFileSinkFilter2>(pFW)->SetFileName(CStringW(m_dst), NULL))
+ || FAILED(hr = CComQIPtr<IFileSinkFilter2>(pFW)->SetMode(AM_FILE_OVERWRITE))
+ || FAILED(hr = pGB->Connect(GetFirstDisconnectedPin(pMux, PINDIR_OUTPUT), GetFirstDisconnectedPin(pFW, PINDIR_INPUT))))
+ break;
+
+ // insert inf. pin tee
+
+ BeginEnumPins(pMux, pEP, pPin)
+ {
+ PIN_DIRECTION dir;
+ CComPtr<IPin> pPinTo;
+ CMediaType mt;
+ if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_INPUT
+ || FAILED(pPin->ConnectedTo(&pPinTo))
+ || FAILED(pPin->ConnectionMediaType(&mt)))
+ continue;
+
+ // FIXME: the inf pin tee filter makes the video messed up, like when seeking
+ // onto a non-keyframe and starting to decode from that point. (audio seems to be ok)
+
+ CComPtr<IBaseFilter> pInfPinTee;
+ if(mt.majortype == MEDIATYPE_Video
+ || mt.majortype == MEDIATYPE_Audio)
+ {
+ if(FAILED(pGB->Disconnect(pPin))
+ || FAILED(pGB->Disconnect(pPinTo))
+ || FAILED(pInfPinTee.CoCreateInstance(CLSID_InfTee))
+ || FAILED(pGB->AddFilter(pInfPinTee, L"Infinite Pin Tee")))
+ continue;
+
+ if(FAILED(pGB->Connect(pPinTo, GetFirstDisconnectedPin(pInfPinTee, PINDIR_INPUT)))
+ || FAILED(pGB->Connect(GetFirstDisconnectedPin(pInfPinTee, PINDIR_OUTPUT), pPin)))
+ {
+ pGB->RemoveFilter(pInfPinTee);
+ pGB->ConnectDirect(pPinTo, pPin, NULL);
+ continue;
+ }
+ }
+
+ pPin = GetFirstDisconnectedPin(pInfPinTee, PINDIR_OUTPUT);
+
+ CComPtr<IBaseFilter> pRenderer;
+
+ if(mt.majortype == MEDIATYPE_Video)
+ {
+ if(SUCCEEDED(pRenderer.CoCreateInstance(CLSID_VideoRendererDefault))
+ || SUCCEEDED(pRenderer.CoCreateInstance(CLSID_VideoRenderer)))
+ pPinTo = ::GetFirstDisconnectedPin(pRenderer, PINDIR_INPUT);
+ }
+ else if(mt.majortype == MEDIATYPE_Audio)
+ {
+ if(SUCCEEDED(pRenderer.CoCreateInstance(CLSID_DSoundRender)))
+ pPinTo = ::GetFirstDisconnectedPin(pRenderer, PINDIR_INPUT);
+ }
+
+ if(pPin && pPinTo && pRenderer)
+ {
+ if(SUCCEEDED(pGB->AddFilter(pRenderer, L"Renderer"))
+ && FAILED(pGB->Connect(pPin, pPinTo)))
+ pGB->RemoveFilter(pRenderer);
+ }
+ }
+ EndEnumPins
+
+ // setup video window
+
+ if(SUCCEEDED(pVW->put_Owner((OAHWND)m_video.m_hWnd))
+ && SUCCEEDED(pVW->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN))
+ && SUCCEEDED(pVW->put_MessageDrain((OAHWND)m_hWnd)))
+ {
+ SetVideoRect();
+ }
+
+ // timer for polling the position
+
+ SetTimer(1, 500, NULL);
+
+ // go!
+
+ if(FAILED(hr = pMC->Run()))
+ break;
+
+ hr = S_OK;
+ }
+ while(false);
+
+ if(FAILED(hr)) OnRecord();
+ }
+ else
+ {
+ if(pMC) pMC->Stop();
+
+ pMC.Release(); pME.Release(); pMS.Release();
+ pVW.Release(); pBV.Release();
+ pGB.Release();
+
+ m_fRecording = false;
+
+ SetWindowText(ResStr(IDS_TITLE));
+ }
+}
+
+void Casf2mkvDlg::OnUpdateRecord(CCmdUI* pCmdUI)
+{
+ CString url;
+ m_combo.GetWindowText(url);
+ url.Trim();
+ pCmdUI->Enable(!url.IsEmpty());
+ pCmdUI->SetText(ResStr(!m_fRecording ? IDS_RECORD : IDS_STOP));
+}
+
+void Casf2mkvDlg::OnUpdateFileName(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(!m_fRecording);
+}
+
+void Casf2mkvDlg::OnUpdateSettings(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(!m_fRecording);
+}
+
+void Casf2mkvDlg::OnSize(UINT nType, int cx, int cy)
+{
+ CResizableDialog::OnSize(nType, cx, cy);
+
+ SetVideoRect();
+}
+
+void Casf2mkvDlg::OnTimer(UINT nIDEvent)
+{
+ if(nIDEvent == 1)
+ {
+ if(pMS)
+ {
+ REFERENCE_TIME rtPos = 0, rtDur = 0;
+ pMS->GetCurrentPosition(&rtPos);
+ pMS->GetDuration(&rtDur);
+
+ CString title;
+ if(rtDur > 0) title.Format(_T("%s (progress: %I64d%%)"), ResStr(IDS_TITLE), 100i64 * rtPos / rtDur);
+ else title = ResStr(IDS_TITLE) + _T(" (live)");
+
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ if(CComQIPtr<IAMNetworkStatus, &IID_IAMNetworkStatus> pAMNS = pBF)
+ {
+ long BufferingProgress = 0;
+ if(SUCCEEDED(pAMNS->get_BufferingProgress(&BufferingProgress)) && BufferingProgress > 0)
+ {
+ CString str;
+ str.Format(_T(" (buffer: %d%%)"), BufferingProgress);
+ title += str;
+ }
+ break;
+ }
+ }
+ EndEnumFilters
+
+ SetWindowText(title);
+ }
+ }
+
+ CResizableDialog::OnTimer(nIDEvent);
+}
+
+void Casf2mkvDlg::OnBnClickedButton2()
+{
+ CComPtr<IBaseFilter> pBF;
+ pBF.CoCreateInstance(CLSID_NetShowSource);
+ if(pBF) ShowPPage(pBF, m_hWnd);
+}
+
+LRESULT Casf2mkvDlg::OnUrlOpen(WPARAM wParam, LPARAM lParam)
+{
+ m_combo.SetWindowText(CString((char*)lParam));
+ return 0;
+}
+
+//////////////////
+
+Casf2mkvDlg::CRecentFileAndURLList::CRecentFileAndURLList(UINT nStart, LPCTSTR lpszSection,
+ LPCTSTR lpszEntryFormat, int nSize,
+ int nMaxDispLen)
+ : CRecentFileList(nStart, lpszSection, lpszEntryFormat, nSize, nMaxDispLen)
+{
+}
+
+//#include <afximpl.h>
+extern BOOL AFXAPI AfxFullPath(LPTSTR lpszPathOut, LPCTSTR lpszFileIn);
+extern BOOL AFXAPI AfxComparePath(LPCTSTR lpszPath1, LPCTSTR lpszPath2);
+
+void Casf2mkvDlg::CRecentFileAndURLList::Add(LPCTSTR lpszPathName)
+{
+ ASSERT(m_arrNames != NULL);
+ ASSERT(lpszPathName != NULL);
+ ASSERT(AfxIsValidString(lpszPathName));
+
+ if(CString(lpszPathName).MakeLower().Find(_T("@device:")) >= 0)
+ return;
+
+ bool fURL = (CString(lpszPathName).Find(_T("://")) >= 0);
+
+ // fully qualify the path name
+ TCHAR szTemp[_MAX_PATH];
+ if(fURL) _tcscpy(szTemp, lpszPathName);
+ else AfxFullPath(szTemp, lpszPathName);
+
+ // update the MRU list, if an existing MRU string matches file name
+ int iMRU;
+ for (iMRU = 0; iMRU < m_nSize-1; iMRU++)
+ {
+ if((fURL && !_tcscmp(m_arrNames[iMRU], szTemp))
+ || AfxComparePath(m_arrNames[iMRU], szTemp))
+ break; // iMRU will point to matching entry
+ }
+ // move MRU strings before this one down
+ for (; iMRU > 0; iMRU--)
+ {
+ ASSERT(iMRU > 0);
+ ASSERT(iMRU < m_nSize);
+ m_arrNames[iMRU] = m_arrNames[iMRU-1];
+ }
+ // place this one at the beginning
+ m_arrNames[0] = szTemp;
+}
diff --git a/src/apps/asf2mkv/asf2mkvDlg.h b/src/apps/asf2mkv/asf2mkvDlg.h
new file mode 100644
index 000000000..c20117ccf
--- /dev/null
+++ b/src/apps/asf2mkv/asf2mkvDlg.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// asf2mkvDlg.h : header file
+//
+
+#pragma once
+
+#include <afxole.h>
+
+#define WM_OPENURL WM_APP
+
+class CUrlDropTarget : public COleDropTarget
+{
+public:
+ CUrlDropTarget() {}
+
+ DROPEFFECT OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
+ DROPEFFECT OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
+ BOOL OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point);
+ DROPEFFECT OnDropEx(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point);
+ void OnDragLeave(CWnd* pWnd);
+ DROPEFFECT OnDragScroll(CWnd* pWnd, DWORD dwKeyState, CPoint point);
+
+ DECLARE_MESSAGE_MAP()
+};
+
+// Casf2mkvDlg dialog
+class Casf2mkvDlg : public CResizableDialog
+{
+ CComPtr<IGraphBuilder> pGB;
+ CComQIPtr<IMediaControl> pMC;
+ CComQIPtr<IMediaEventEx> pME;
+ CComQIPtr<IMediaSeeking> pMS;
+ CComQIPtr<IVideoWindow> pVW;
+ CComQIPtr<IBasicVideo> pBV;
+
+ bool m_fRecording;
+ CString m_dst;
+
+ class CRecentFileAndURLList : public CRecentFileList
+ {
+ public:
+ CRecentFileAndURLList(UINT nStart, LPCTSTR lpszSection,
+ LPCTSTR lpszEntryFormat, int nSize,
+ int nMaxDispLen = AFX_ABBREV_FILENAME_LEN);
+
+ virtual void Add(LPCTSTR lpszPathName); // we have to override CRecentFileList::Add because the original version can't handle URLs
+ };
+
+ CRecentFileAndURLList m_mru;
+ void SetupCombo();
+
+ void SetVideoRect();
+
+ CUrlDropTarget m_urlDropTarget;
+
+// Construction
+public:
+ Casf2mkvDlg(CWnd* pParent = NULL); // standard constructor
+
+// Dialog Data
+ enum { IDD = IDD_ASF2MKV_DIALOG };
+
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+// Implementation
+protected:
+ HICON m_hIcon;
+
+ CComboBox m_combo;
+ CStatic m_video;
+
+ // Generated message map functions
+ virtual BOOL OnInitDialog();
+ virtual BOOL DestroyWindow();
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+ afx_msg void OnPaint();
+ afx_msg HCURSOR OnQueryDragIcon();
+ afx_msg LRESULT OnGraphNotify(WPARAM wParam, LPARAM lParam);
+ afx_msg void OnRecord();
+ afx_msg void OnUpdateRecord(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateFileName(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateSettings(CCmdUI* pCmdUI);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnTimer(UINT nIDEvent);
+ afx_msg void OnBnClickedButton2();
+ afx_msg LRESULT OnUrlOpen(WPARAM wParam, LPARAM lParam);
+};
diff --git a/src/apps/asf2mkv/res/asf2mkv.ico b/src/apps/asf2mkv/res/asf2mkv.ico
new file mode 100644
index 000000000..8a84ca3d3
--- /dev/null
+++ b/src/apps/asf2mkv/res/asf2mkv.ico
Binary files differ
diff --git a/src/apps/asf2mkv/res/asf2mkv.manifest b/src/apps/asf2mkv/res/asf2mkv.manifest
new file mode 100644
index 000000000..b3f17a6fa
--- /dev/null
+++ b/src/apps/asf2mkv/res/asf2mkv.manifest
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="X86"
+ name="Microsoft.Windows.asf2mkv"
+ type="win32"
+/>
+<description>Your app description here</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="X86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+</assembly>
diff --git a/src/apps/asf2mkv/res/asf2mkv.rc2 b/src/apps/asf2mkv/res/asf2mkv.rc2
new file mode 100644
index 000000000..acf1fad94
--- /dev/null
+++ b/src/apps/asf2mkv/res/asf2mkv.rc2
@@ -0,0 +1,13 @@
+//
+// asf2mkv.RC2 - resources Microsoft Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/src/apps/asf2mkv/resource.h b/src/apps/asf2mkv/resource.h
new file mode 100644
index 000000000..d6b8350e2
--- /dev/null
+++ b/src/apps/asf2mkv/resource.h
@@ -0,0 +1,29 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by asf2mkv.rc
+//
+#define IDM_ABOUTBOX 0x0010
+#define IDD_ABOUTBOX 100
+#define IDS_ABOUTBOX 101
+#define IDD_ASF2MKV_DIALOG 102
+#define IDS_RECORD 102
+#define IDS_STOP 103
+#define IDS_TITLE 104
+#define IDR_MAINFRAME 128
+#define IDC_BUTTON1 1002
+#define IDC_STATIC1 1003
+#define IDC_COMBO1 1004
+#define IDC_CHECK1 1005
+#define IDC_BUTTON2 1006
+#define IDC_CHECK2 1007
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 129
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1008
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/apps/asf2mkv/stdafx.cpp b/src/apps/asf2mkv/stdafx.cpp
new file mode 100644
index 000000000..7dc1f46ff
--- /dev/null
+++ b/src/apps/asf2mkv/stdafx.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+// stdafx.cpp : source file that includes just the standard includes
+// asf2mkv.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
diff --git a/src/apps/asf2mkv/stdafx.h b/src/apps/asf2mkv/stdafx.h
new file mode 100644
index 000000000..5afaba526
--- /dev/null
+++ b/src/apps/asf2mkv/stdafx.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+#endif
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
+#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
+#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
+#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.
+#endif
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
+
+// turns off MFC's hiding of some common and often safely ignored warning messages
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <afxtempl.h>
+#include <afxdisp.h>
+#include <Shlwapi.h>
+#include <atlpath.h>
+#include <streams.h>
+#include <dvdmedia.h>
+
+#include "..\..\ui\ui.h"
+#include "..\..\DSUtil\DSUtil.h"
+#include "..\..\filters\filters.h"
+
+#define ResStr(id) CString(MAKEINTRESOURCE(id)) \ No newline at end of file
diff --git a/src/apps/mpcinfo/Resource.h b/src/apps/mpcinfo/Resource.h
new file mode 100644
index 000000000..ef473e336
--- /dev/null
+++ b/src/apps/mpcinfo/Resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by mpcinfo.RC
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+
+#define _APS_NEXT_RESOURCE_VALUE 3000
+#define _APS_NEXT_CONTROL_VALUE 3000
+#define _APS_NEXT_SYMED_VALUE 3000
+#define _APS_NEXT_COMMAND_VALUE 32771
+#endif
+#endif
diff --git a/src/apps/mpcinfo/doc/mpcinfo.txt b/src/apps/mpcinfo/doc/mpcinfo.txt
new file mode 100644
index 000000000..22653f002
--- /dev/null
+++ b/src/apps/mpcinfo/doc/mpcinfo.txt
@@ -0,0 +1,72 @@
+MPCINFO.DLL by Gabest
+MPCINFO.TXT by Krofinzki
+
+The dll file reads information from Media Player Classic. Wich is a great player!
+It can be downloaded from: http://www.gabest.org/mpc.php
+
+This textfile explains how to use mpcinfo.dll with mIRC.
+
+
+Functions Explained:
+-------------------
+
+ file $dll(mpcinfo.dll,file,) returns:
+
+ File name, with path.
+ Use $nopath($dll(mpcinfo.dll,file,)) if you don't want the path
+
+
+ size $dll(mpcinfo.dll,size,) returns:
+
+ Size of the file being played (in bytes)
+
+
+ pos $dll(mpcinfo.dll,pos,) returns:
+
+ Current position of the playback in position/duration form
+
+ Example: 01:34/02:46
+
+
+ info $dll(mpcinfo.dll,info,)
+
+ All-in-one, "file, size, pos"
+
+
+ running $dll(mpcinfo.dll,running,) returns:
+
+ 0: File opened, state wrong
+ 1: File opened, state matching
+ 2: Nothing is opened, or mpc is not running
+
+
+ stopped $dll(mpcinfo.dll,stopped,) returns:
+
+ 0: File opened, state wrong
+ 1: File opened, state matching
+ 2: Nothing is opened, or mpc is not running
+
+
+ paused $dll(mpcinfo.dll,paused,) returns:
+
+ 0: File opened, state wrong
+ 1: File opened, state matching
+ 2: Nothing is opened, or mpc is not running
+
+
+Combined Example:
+----------------
+
+Add the following in remotes (Alt+R)
+
+alias mplayerc {
+ if ($dll(mpcinfo.dll,running,) != 2) {
+ if ($dll(mpcinfo.dll,file,) != $null) { me watches: $nopath($dll(mpcinfo.dll,file,)) ( $+ $dll(mpcinfo.dll,pos,) $+ ) Size: $round($calc($dll(mpcinfo.dll,size,) / 1024 / 1024 ),1) mb }
+ else { echo -a *** Couldn't retrive MplayerC information }
+ halt
+ }
+ else { echo -a *** Media Player Classic is not running }
+}
+
+Then type /mplayerc in mIRC (Also make sure your playing something in MPC :p)
+
diff --git a/src/apps/mpcinfo/mpcinfo.cpp b/src/apps/mpcinfo/mpcinfo.cpp
new file mode 100644
index 000000000..64293f639
--- /dev/null
+++ b/src/apps/mpcinfo/mpcinfo.cpp
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// mpcinfo.cpp : Defines the initialization routines for the DLL.
+//
+
+#include "stdafx.h"
+#include "mpcinfo.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+//
+// Note!
+//
+// If this DLL is dynamically linked against the MFC
+// DLLs, any functions exported from this DLL which
+// call into MFC must have the AFX_MANAGE_STATE macro
+// added at the very beginning of the function.
+//
+// For example:
+//
+// extern "C" BOOL PASCAL EXPORT ExportedFunction()
+// {
+// AFX_MANAGE_STATE(AfxGetStaticModuleState());
+// // normal function body here
+// }
+//
+// It is very important that this macro appear in each
+// function, prior to any calls into MFC. This means that
+// it must appear as the first statement within the
+// function, even before any object variable declarations
+// as their constructors may generate calls into the MFC
+// DLL.
+//
+// Please see MFC Technical Notes 33 and 58 for additional
+// details.
+//
+
+// CmpcinfoApp
+
+BEGIN_MESSAGE_MAP(CmpcinfoApp, CWinApp)
+END_MESSAGE_MAP()
+
+
+// CmpcinfoApp construction
+
+CmpcinfoApp::CmpcinfoApp()
+{
+ // TODO: add construction code here,
+ // Place all significant initialization in InitInstance
+}
+
+
+// The one and only CmpcinfoApp object
+
+CmpcinfoApp theApp;
+
+
+// CmpcinfoApp initialization
+
+BOOL CmpcinfoApp::InitInstance()
+{
+ CWinApp::InitInstance();
+
+ return TRUE;
+}
+
+#include <dshow.h>
+#include <streams.h>
+#include <atlbase.h>
+
+static bool GetFilterGraph(IFilterGraph** ppFG)
+{
+ if(!ppFG) return(false);
+
+ CComPtr<IRunningObjectTable> pROT;
+ if(FAILED(GetRunningObjectTable(0, &pROT)))
+ return 1;
+
+ CComPtr<IEnumMoniker> pEM;
+ if(FAILED(pROT->EnumRunning(&pEM)))
+ return 1;
+
+ CComPtr<IBindCtx> pBindCtx;
+ CreateBindCtx(0, &pBindCtx);
+
+ for(CComPtr<IMoniker> pMoniker; S_OK == pEM->Next(1, &pMoniker, NULL); pMoniker = NULL)
+ {
+ LPOLESTR pDispName = NULL;
+ if(FAILED(pMoniker->GetDisplayName(pBindCtx, NULL, &pDispName)))
+ continue;
+
+ CStringW strw(pDispName);
+
+ CComPtr<IMalloc> pMalloc;
+ if(FAILED(CoGetMalloc(1, &pMalloc)))
+ continue;
+ pMalloc->Free(pDispName);
+
+ if(strw.Find(L"(MPC)") < 0)
+ continue;
+
+ CComPtr<IUnknown> pUnk;
+ if(S_OK != pROT->GetObject(pMoniker, &pUnk))
+ continue;
+
+ CComQIPtr<IFilterGraph> pFG = pUnk;
+ if(!pFG)
+ continue;
+
+ *ppFG = pFG.Detach();
+
+ break;
+ }
+
+ return(!!*ppFG);
+}
+
+extern "C" int WINAPI file(HWND,HWND,char *data,char*,BOOL,BOOL)
+{
+ CComPtr<IFilterGraph> pFG;
+ if(!GetFilterGraph(&pFG))
+ return 1;
+
+ CString fn;
+
+ CComPtr<IEnumFilters> pEF;
+ if(FAILED(pFG->EnumFilters(&pEF)))
+ return 1;
+
+ ULONG cFetched = 0;
+ for(CComPtr<IBaseFilter> pBF; S_OK == pEF->Next(1, &pBF, &cFetched); pBF = NULL)
+ {
+ if(CComQIPtr<IFileSourceFilter> pFSF = pBF)
+ {
+ LPOLESTR pFileName = NULL;
+ AM_MEDIA_TYPE mt;
+ if(FAILED(pFSF->GetCurFile(&pFileName, &mt)))
+ continue;
+
+ fn = CStringW(pFileName);
+
+ CoTaskMemFree(pFileName);
+ FreeMediaType(mt);
+
+ break;
+ }
+ }
+
+ if(fn.IsEmpty())
+ return 1;
+
+ sprintf(data, _T("%s"), fn);
+
+ return 3;
+}
+
+extern "C" int WINAPI size(HWND,HWND,char *data,char*,BOOL,BOOL)
+{
+ if(file(0,0,data,0,0,0) != 3)
+ return 1;
+
+ CString fn = CStringA(data);
+ data[0] = 0;
+
+ HANDLE hFile = CreateFile(fn, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
+ if(hFile == INVALID_HANDLE_VALUE)
+ return 1;
+
+ LARGE_INTEGER size;
+ size.QuadPart = 0;
+ size.LowPart = GetFileSize(hFile, (DWORD*)&size.HighPart);
+
+ sprintf(data, _T("%I64d"), size.QuadPart);
+
+ CloseHandle(hFile);
+
+ return 3;
+}
+
+extern "C" int WINAPI pos(HWND,HWND,char *data,char*,BOOL,BOOL)
+{
+ CComPtr<IFilterGraph> pFG;
+ if(!GetFilterGraph(&pFG))
+ return 1;
+
+ CComQIPtr<IMediaSeeking> pMS = pFG;
+ REFERENCE_TIME pos, dur;
+ if(FAILED(pMS->GetCurrentPosition(&pos)) || FAILED(pMS->GetDuration(&dur)))
+ return 1;
+
+ if(dur > 10000000i64*60*60)
+ {
+ sprintf(data, _T("%02d:%02d:%02d/%02d:%02d:%02d"),
+ (int)(pos/10000000/60/60), (int)(pos/10000000/60)%60, (int)(pos/10000000)%60,
+ (int)(dur/10000000/60/60), (int)(dur/10000000/60)%60, (int)(dur/10000000)%60);
+ }
+ else
+ {
+ sprintf(data, _T("%02d:%02d/%02d:%02d"),
+ (int)(pos/10000000/60)%60, (int)(pos/10000000)%60,
+ (int)(dur/10000000/60)%60, (int)(dur/10000000)%60);
+ }
+
+ return 3;
+}
+
+extern "C" int WINAPI info(HWND,HWND,char *data,char*,BOOL,BOOL)
+{
+ CStringA ret;
+ if(file(0,0,data,0,0,0)!=3) return 1;
+ ret += data;
+ ret += ", ";
+ if(size(0,0,data,0,0,0)!=3) return 1;
+ ret += data;
+ ret += ", ";
+ if(pos(0,0,data,0,0,0)!=3) return 1;
+ ret += data;
+
+ strcpy(data, ret);
+
+ return 3;
+}
+
+extern "C" int WINAPI stopped(HWND,HWND,char *data,char*,BOOL,BOOL)
+{
+ sprintf(data, _T("2"));
+
+ CComPtr<IFilterGraph> pFG;
+ CComQIPtr<IMediaControl> pMC;
+ OAFilterState fs;
+ if(!GetFilterGraph(&pFG) || !(pMC = pFG) || FAILED(pMC->GetState(0, &fs)))
+ return 3;
+
+ sprintf(data, _T("%d"), fs == State_Stopped ? 1 : 0);
+
+ return 3;
+}
+
+extern "C" int WINAPI paused(HWND,HWND,char *data,char*,BOOL,BOOL)
+{
+ sprintf(data, _T("2"));
+
+ CComPtr<IFilterGraph> pFG;
+ CComQIPtr<IMediaControl> pMC;
+ OAFilterState fs;
+ if(!GetFilterGraph(&pFG) || !(pMC = pFG) || FAILED(pMC->GetState(0, &fs)))
+ return 3;
+
+ sprintf(data, _T("%d"), fs == State_Paused ? 1 : 0);
+
+ return 3;
+}
+
+extern "C" int WINAPI running(HWND,HWND,char *data,char*,BOOL,BOOL)
+{
+ sprintf(data, _T("2"));
+
+ CComPtr<IFilterGraph> pFG;
+ CComQIPtr<IMediaControl> pMC;
+ OAFilterState fs;
+ if(!GetFilterGraph(&pFG) || !(pMC = pFG) || FAILED(pMC->GetState(0, &fs)))
+ return 3;
+
+ sprintf(data, _T("%d"), fs == State_Running ? 1 : 0);
+
+ return 3;
+}
diff --git a/src/apps/mpcinfo/mpcinfo.def b/src/apps/mpcinfo/mpcinfo.def
new file mode 100644
index 000000000..ac51b673f
--- /dev/null
+++ b/src/apps/mpcinfo/mpcinfo.def
@@ -0,0 +1,13 @@
+; mpcinfo.def : Declares the module parameters for the DLL.
+
+LIBRARY "mpcinfo"
+
+EXPORTS
+ ; Explicit exports can go here
+ file
+ size
+ pos
+ info
+ stopped
+ paused
+ running \ No newline at end of file
diff --git a/src/apps/mpcinfo/mpcinfo.h b/src/apps/mpcinfo/mpcinfo.h
new file mode 100644
index 000000000..1693cdce1
--- /dev/null
+++ b/src/apps/mpcinfo/mpcinfo.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// mpcinfo.h : main header file for the mpcinfo DLL
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h" // main symbols
+
+
+// CmpcinfoApp
+// See mpcinfo.cpp for the implementation of this class
+//
+
+class CmpcinfoApp : public CWinApp
+{
+public:
+ CmpcinfoApp();
+
+// Overrides
+public:
+ virtual BOOL InitInstance();
+
+ DECLARE_MESSAGE_MAP()
+};
diff --git a/src/apps/mpcinfo/mpcinfo.ncb b/src/apps/mpcinfo/mpcinfo.ncb
new file mode 100644
index 000000000..a35ff906a
--- /dev/null
+++ b/src/apps/mpcinfo/mpcinfo.ncb
Binary files differ
diff --git a/src/apps/mpcinfo/mpcinfo.rc b/src/apps/mpcinfo/mpcinfo.rc
new file mode 100644
index 000000000..7dd7e5740
--- /dev/null
+++ b/src/apps/mpcinfo/mpcinfo.rc
@@ -0,0 +1,135 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Hungarian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_HUN)
+#ifdef _WIN32
+LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
+#pragma code_page(1250)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#include ""res\\mpcinfo.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Hungarian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "http://gabest.org/"
+ VALUE "CompanyName", "Gabest"
+ VALUE "FileDescription", "plugin dll for mirc"
+ VALUE "FileVersion", "1.0.0.0"
+ VALUE "InternalName", "mpcinfo.dll"
+ VALUE "LegalCopyright", "Copyright (C) 2003-2005 Gabest. All rights reserved."
+ VALUE "OriginalFilename", "mpcinfo.dll"
+ VALUE "ProductName", "mpcinfo"
+ VALUE "ProductVersion", "1.0.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#include "res\mpcinfo.rc2" // non-Microsoft Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/src/apps/mpcinfo/mpcinfo.sln b/src/apps/mpcinfo/mpcinfo.sln
new file mode 100644
index 000000000..7d4123f10
--- /dev/null
+++ b/src/apps/mpcinfo/mpcinfo.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpcinfo", "mpcinfo.vcproj", "{AF754B6B-75F8-4A8A-9A98-2E34DB02D4A8}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {AF754B6B-75F8-4A8A-9A98-2E34DB02D4A8}.Debug.ActiveCfg = Debug|Win32
+ {AF754B6B-75F8-4A8A-9A98-2E34DB02D4A8}.Debug.Build.0 = Debug|Win32
+ {AF754B6B-75F8-4A8A-9A98-2E34DB02D4A8}.Release.ActiveCfg = Release|Win32
+ {AF754B6B-75F8-4A8A-9A98-2E34DB02D4A8}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/src/apps/mpcinfo/mpcinfo.suo b/src/apps/mpcinfo/mpcinfo.suo
new file mode 100644
index 000000000..9559d4194
--- /dev/null
+++ b/src/apps/mpcinfo/mpcinfo.suo
Binary files differ
diff --git a/src/apps/mpcinfo/mpcinfo.vcproj b/src/apps/mpcinfo/mpcinfo.vcproj
new file mode 100644
index 000000000..3d00b0643
--- /dev/null
+++ b/src/apps/mpcinfo/mpcinfo.vcproj
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="mpcinfo"
+ ProjectGUID="{AF754B6B-75F8-4A8A-9A98-2E34DB02D4A8}"
+ Keyword="MFCDLLProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="2"
+ UseOfMFC="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_USRDLL"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="TRUE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="strmbaseD.lib"
+ OutputFile="$(OutDir)/mpcinfo.dll"
+ LinkIncremental="2"
+ ModuleDefinitionFile=".\mpcinfo.def"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ ImportLibrary="$(OutDir)/mpcinfo.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="2"
+ UseOfMFC="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="TRUE"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;_USRDLL"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ TreatWChar_tAsBuiltInType="TRUE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="delayimp.lib strmbaseR.lib"
+ OutputFile="$(OutDir)/mpcinfo.dll"
+ LinkIncremental="1"
+ ModuleDefinitionFile=".\mpcinfo.def"
+ DelayLoadDLLs="oleacc.dll"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary="$(OutDir)/mpcinfo.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
+ <File
+ RelativePath="mpcinfo.cpp">
+ </File>
+ <File
+ RelativePath="mpcinfo.def">
+ </File>
+ <File
+ RelativePath="stdafx.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc">
+ <File
+ RelativePath="mpcinfo.h">
+ </File>
+ <File
+ RelativePath="Resource.h">
+ </File>
+ <File
+ RelativePath="stdafx.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+ <File
+ RelativePath="mpcinfo.rc">
+ </File>
+ <File
+ RelativePath="res\mpcinfo.rc2">
+ </File>
+ </Filter>
+ <File
+ RelativePath="ReadMe.txt">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/apps/mpcinfo/res/mpcinfo.rc2 b/src/apps/mpcinfo/res/mpcinfo.rc2
new file mode 100644
index 000000000..7dc6c48dc
--- /dev/null
+++ b/src/apps/mpcinfo/res/mpcinfo.rc2
@@ -0,0 +1,13 @@
+//
+// mpcinfo.RC2 - resources Microsoft Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/src/apps/mpcinfo/stdafx.cpp b/src/apps/mpcinfo/stdafx.cpp
new file mode 100644
index 000000000..92b493be5
--- /dev/null
+++ b/src/apps/mpcinfo/stdafx.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// stdafx.cpp : source file that includes just the standard includes
+// mpcinfo.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
diff --git a/src/apps/mpcinfo/stdafx.h b/src/apps/mpcinfo/stdafx.h
new file mode 100644
index 000000000..cf7d4edb4
--- /dev/null
+++ b/src/apps/mpcinfo/stdafx.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+#endif
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
+#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
+#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
+#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.
+#endif
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxole.h> // MFC OLE classes
+#include <afxodlgs.h> // MFC OLE dialog classes
+#include <afxdisp.h> // MFC Automation classes
+#endif // _AFX_NO_OLE_SUPPORT
+
+#ifndef _AFX_NO_DB_SUPPORT
+#include <afxdb.h> // MFC ODBC database classes
+#endif // _AFX_NO_DB_SUPPORT
+
+#ifndef _AFX_NO_DAO_SUPPORT
+#include <afxdao.h> // MFC DAO database classes
+#endif // _AFX_NO_DAO_SUPPORT
+
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
diff --git a/src/apps/mplayerc/AuthDlg.cpp b/src/apps/mplayerc/AuthDlg.cpp
new file mode 100644
index 000000000..204d67816
--- /dev/null
+++ b/src/apps/mplayerc/AuthDlg.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+// AuthDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "AuthDlg.h"
+
+// CAuthDlg dialog
+
+IMPLEMENT_DYNAMIC(CAuthDlg, CDialog)
+CAuthDlg::CAuthDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CAuthDlg::IDD, pParent)
+ , m_username(_T(""))
+ , m_password(_T(""))
+ , m_remember(FALSE)
+{
+}
+
+CAuthDlg::~CAuthDlg()
+{
+}
+
+void CAuthDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_COMBO1, m_usernamectrl);
+ DDX_Text(pDX, IDC_COMBO1, m_username);
+ DDX_Text(pDX, IDC_EDIT3, m_password);
+ DDX_Check(pDX, IDC_CHECK1, m_remember);
+}
+
+CString CAuthDlg::DEncrypt(CString str)
+{
+ for(int i = 0; i < str.GetLength(); i++)
+ str.SetAt(i, str[i]^5);
+ return str;
+}
+
+
+BEGIN_MESSAGE_MAP(CAuthDlg, CDialog)
+ ON_BN_CLICKED(IDOK, OnBnClickedOk)
+ ON_CBN_SELCHANGE(IDC_COMBO1, OnCbnSelchangeCombo1)
+ ON_EN_SETFOCUS(IDC_EDIT3, OnEnSetfocusEdit3)
+END_MESSAGE_MAP()
+
+
+// CAuthDlg message handlers
+
+BOOL CAuthDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ CWinApp* pApp = AfxGetApp();
+
+ if(pApp->m_pszRegistryKey)
+ {
+ CRegKey hSecKey(pApp->GetSectionKey(ResStr(IDS_R_LOGINS)));
+ if(hSecKey)
+ {
+ int i = 0;
+ TCHAR username[256], password[256];
+ while(1)
+ {
+ DWORD unlen = countof(username);
+ DWORD pwlen = sizeof(password);
+ DWORD type = REG_SZ;
+ if(ERROR_SUCCESS == RegEnumValue(
+ hSecKey, i++, username, &unlen, 0, &type, (BYTE*)password, &pwlen))
+ {
+ m_logins[username] = DEncrypt(password);
+ m_usernamectrl.AddString(username);
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ CAutoVectorPtr<TCHAR> buff;
+ buff.Allocate(32767/sizeof(TCHAR));
+
+ DWORD len = GetPrivateProfileSection(
+ ResStr(IDS_R_LOGINS), buff, 32767/sizeof(TCHAR), pApp->m_pszProfileName);
+
+ TCHAR* p = buff;
+ while(*p && len > 0)
+ {
+ CString str = p;
+ p += str.GetLength()+1;
+ len -= str.GetLength()+1;
+ CAtlList<CString> sl;
+ Explode(str, sl, '=', 2);
+ if(sl.GetCount() == 2)
+ {
+ m_logins[sl.GetHead()] = DEncrypt(sl.GetTail());
+ m_usernamectrl.AddString(sl.GetHead());
+ }
+ }
+ }
+
+ m_usernamectrl.SetFocus();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CAuthDlg::OnBnClickedOk()
+{
+ UpdateData();
+
+ if(!m_username.IsEmpty())
+ {
+ CWinApp* pApp = AfxGetApp();
+ pApp->WriteProfileString(ResStr(IDS_R_LOGINS), m_username, m_remember ? DEncrypt(m_password) : _T(""));
+ }
+
+ OnOK();
+}
+
+
+void CAuthDlg::OnCbnSelchangeCombo1()
+{
+ CString username;
+ m_usernamectrl.GetLBText(m_usernamectrl.GetCurSel(), username);
+
+ CString password;
+ if(m_logins.Lookup(username, password))
+ {
+ m_password = password;
+ m_remember = TRUE;
+ UpdateData(FALSE);
+ }
+}
+
+void CAuthDlg::OnEnSetfocusEdit3()
+{
+ UpdateData();
+
+ CString password;
+ if(m_logins.Lookup(m_username, password))
+ {
+ m_password = password;
+ m_remember = TRUE;
+ UpdateData(FALSE);
+ }
+}
diff --git a/src/apps/mplayerc/AuthDlg.h b/src/apps/mplayerc/AuthDlg.h
new file mode 100644
index 000000000..86e9b496c
--- /dev/null
+++ b/src/apps/mplayerc/AuthDlg.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "afxwin.h"
+
+
+// CAuthDlg dialog
+
+class CAuthDlg : public CDialog
+{
+ DECLARE_DYNAMIC(CAuthDlg)
+
+private:
+ CString DEncrypt(CString pw);
+ CMapStringToString m_logins;
+
+public:
+ CAuthDlg(CWnd* pParent = NULL); // standard constructor
+ virtual ~CAuthDlg();
+
+// Dialog Data
+ enum { IDD = IDD_AUTH_DLG };
+ CComboBox m_usernamectrl;
+ CString m_username;
+ CString m_password;
+ BOOL m_remember;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnBnClickedOk();
+ afx_msg void OnCbnSelchangeCombo1();
+ afx_msg void OnEnSetfocusEdit3();
+};
diff --git a/src/apps/mplayerc/BaseGraph.cpp b/src/apps/mplayerc/BaseGraph.cpp
new file mode 100644
index 000000000..87a63200a
--- /dev/null
+++ b/src/apps/mplayerc/BaseGraph.cpp
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "basegraph.h"
+#include "..\..\DSUtil\DSUtil.h"
+
+//
+// CPlayerWindow
+//
+
+BOOL CPlayerWindow::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if(!CWnd::PreCreateWindow(cs))
+ return FALSE;
+
+ cs.style &= ~WS_BORDER;
+ cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
+ ::LoadCursor(NULL, IDC_HAND), NULL, NULL);
+
+ return TRUE;
+}
+
+BEGIN_MESSAGE_MAP(CPlayerWindow, CWnd)
+ ON_WM_ERASEBKGND()
+END_MESSAGE_MAP()
+
+BOOL CPlayerWindow::OnEraseBkgnd(CDC* pDC)
+{
+ for(CWnd* pChild = GetWindow(GW_CHILD); pChild; pChild = pChild->GetNextWindow())
+ {
+ if(!pChild->IsWindowVisible()) continue;
+
+ CRect r;
+ pChild->GetClientRect(&r);
+ pChild->MapWindowPoints(this, &r);
+ pDC->ExcludeClipRect(&r);
+ }
+
+ CRect r;
+ GetClientRect(&r);
+ pDC->FillSolidRect(&r, 0);
+
+ return TRUE;
+}
+
+//
+// CBaseGraph
+//
+
+CBaseGraph::CBaseGraph()
+ : CUnknown(NAME("CBaseGraph"), NULL)
+ , m_hNotifyWnd(NULL)
+{
+}
+
+CBaseGraph::~CBaseGraph()
+{
+}
+
+STDMETHODIMP CBaseGraph::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ CheckPointer(ppv, E_POINTER);
+
+ return
+ QI(IFilterGraph)
+ QI(IGraphBuilder)
+ QI(IFilterGraph2)
+ QI(IGraphBuilder2)
+ QI(IMediaControl)
+ QI(IMediaSeeking)
+ QI(IMediaEventEx)
+ QI(IVideoWindow)
+ QI(IBasicVideo)
+ QI(IBasicAudio)
+ QI(IAMOpenProgress)
+ QI(IGraphEngine)
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+void CBaseGraph::ClearMessageQueue()
+{
+ while(!m_msgqueue.IsEmpty())
+ {
+ GMSG msg = m_msgqueue.RemoveHead();
+ FreeEventParams(msg.m_lEventCode, msg.m_lParam1, msg.m_lParam2);
+ }
+}
+
+
+void CBaseGraph::NotifyEvent(long lEventCode, LONG_PTR lParam1, LONG_PTR lParam2)
+{
+ if(!m_hNotifyWnd) return;
+
+ GMSG msg;
+ msg.m_lEventCode = lEventCode;
+ msg.m_lParam1 = lParam1;
+ msg.m_lParam2 = lParam2;
+ m_msgqueue.AddTail(msg);
+
+ PostMessage((HWND)m_hNotifyWnd, m_lNotifyMsg, 0, m_lNotifyInstData);
+}
+
+// IDispatch
+STDMETHODIMP CBaseGraph::GetTypeInfoCount(UINT* pctinfo) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) {return E_NOTIMPL;}
+
+// IFilterGraph
+STDMETHODIMP CBaseGraph::AddFilter(IBaseFilter* pFilter, LPCWSTR pName) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::RemoveFilter(IBaseFilter* pFilter) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::EnumFilters(IEnumFilters** ppEnum) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::FindFilterByName(LPCWSTR pName, IBaseFilter** ppFilter) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::ConnectDirect(IPin* ppinOut, IPin* ppinIn, const AM_MEDIA_TYPE* pmt) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::Reconnect(IPin* ppin) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::Disconnect(IPin* ppin) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::SetDefaultSyncSource() {return E_NOTIMPL;}
+
+// IGraphBuilder
+STDMETHODIMP CBaseGraph::Connect(IPin* ppinOut, IPin* ppinIn) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::Render(IPin* ppinOut) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::AddSourceFilter(LPCWSTR lpcwstrFileName, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter) {*ppFilter = NULL; return RenderFile(lpcwstrFileName, NULL);}//E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::SetLogFile(DWORD_PTR hFile) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::Abort() {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::ShouldOperationContinue() {return E_NOTIMPL;}
+
+// IFilterGraph2
+STDMETHODIMP CBaseGraph::AddSourceFilterForMoniker(IMoniker* pMoniker, IBindCtx* pCtx, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::ReconnectEx(IPin* ppin, const AM_MEDIA_TYPE* pmt) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::RenderEx(IPin* pPinOut, DWORD dwFlags, DWORD* pvContext) {return E_NOTIMPL;}
+
+// IGraphBuilder2
+STDMETHODIMP CBaseGraph::IsPinDirection(IPin* pPin, PIN_DIRECTION dir) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::IsPinConnected(IPin* pPin) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::ConnectFilter(IBaseFilter* pBF, IPin* pPinIn) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::ConnectFilter(IPin* pPinOut, IBaseFilter* pBF) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::ConnectFilterDirect(IPin* pPinOut, IBaseFilter* pBF, const AM_MEDIA_TYPE* pmt) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::NukeDownstream(IUnknown* pUnk) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::FindInterface(REFIID iid, void** ppv, BOOL bRemove) {return QueryInterface(iid, ppv);}
+STDMETHODIMP CBaseGraph::AddToROT() {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::RemoveFromROT() {return E_NOTIMPL;}
+
+// IMediaControl
+STDMETHODIMP CBaseGraph::Run() {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::Pause() {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::Stop() {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetState(LONG msTimeout, OAFilterState* pfs) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::RenderFile(BSTR strFilename) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::AddSourceFilter(BSTR strFilename, IDispatch** ppUnk) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_FilterCollection(IDispatch** ppUnk) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_RegFilterCollection(IDispatch** ppUnk) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::StopWhenReady() {return Stop();}
+
+// IMediaEvent
+STDMETHODIMP CBaseGraph::GetEventHandle(OAEVENT* hEvent) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetEvent(long* lEventCode, LONG_PTR* lParam1, LONG_PTR* lParam2, long msTimeout)
+{
+ if(m_msgqueue.IsEmpty()) return E_FAIL;
+
+ GMSG msg = m_msgqueue.RemoveHead();
+ if(lEventCode) *lEventCode = msg.m_lEventCode;
+ if(lParam1) *lParam1 = msg.m_lParam1;
+ if(lParam2) *lParam2 = msg.m_lParam2;
+
+ return S_OK;
+}
+STDMETHODIMP CBaseGraph::WaitForCompletion(long msTimeout, long* pEvCode) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::CancelDefaultHandling(long lEvCode) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::RestoreDefaultHandling(long lEvCode) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::FreeEventParams(long lEvCode, LONG_PTR lParam1, LONG_PTR lParam2)
+{
+ if(EC_BG_ERROR == lEvCode)
+ {
+ if(lParam1) CoTaskMemFree((void*)lParam1);
+ }
+
+ return S_OK;
+}
+
+// IMediaEventEx
+STDMETHODIMP CBaseGraph::SetNotifyWindow(OAHWND hwnd, long lMsg, LONG_PTR lInstanceData)
+{
+ m_hNotifyWnd = hwnd;
+ m_lNotifyMsg = lMsg;
+ m_lNotifyInstData = lInstanceData;
+
+ if(!IsWindow((HWND)m_hNotifyWnd))
+ {
+ m_hNotifyWnd = NULL;
+ return E_FAIL;
+ }
+
+ return S_OK;
+}
+STDMETHODIMP CBaseGraph::SetNotifyFlags(long lNoNotifyFlags) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetNotifyFlags(long* lplNoNotifyFlags) {return E_NOTIMPL;}
+
+// IMediaSeeking
+STDMETHODIMP CBaseGraph::GetCapabilities(DWORD* pCapabilities)
+{
+ return pCapabilities ? *pCapabilities = AM_SEEKING_CanSeekAbsolute|AM_SEEKING_CanGetCurrentPos|AM_SEEKING_CanGetDuration, S_OK : E_POINTER;
+}
+STDMETHODIMP CBaseGraph::CheckCapabilities(DWORD* pCapabilities)
+{
+ CheckPointer(pCapabilities, E_POINTER);
+
+ if(*pCapabilities == 0) return S_OK;
+
+ DWORD caps;
+ GetCapabilities(&caps);
+
+ DWORD caps2 = caps & *pCapabilities;
+
+ return caps2 == 0 ? E_FAIL : caps2 == *pCapabilities ? S_OK : S_FALSE;
+}
+STDMETHODIMP CBaseGraph::IsFormatSupported(const GUID* pFormat)
+{
+ return !pFormat ? E_POINTER : *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;
+}
+STDMETHODIMP CBaseGraph::QueryPreferredFormat(GUID* pFormat)
+{
+ return GetTimeFormat(pFormat);
+}
+STDMETHODIMP CBaseGraph::GetTimeFormat(GUID* pFormat)
+{
+ return pFormat ? *pFormat = TIME_FORMAT_MEDIA_TIME, S_OK : E_POINTER;
+}
+STDMETHODIMP CBaseGraph::IsUsingTimeFormat(const GUID* pFormat)
+{
+ return IsFormatSupported(pFormat);
+}
+STDMETHODIMP CBaseGraph::SetTimeFormat(const GUID* pFormat)
+{
+ return S_OK == IsFormatSupported(pFormat) ? S_OK : E_INVALIDARG;
+}
+STDMETHODIMP CBaseGraph::GetDuration(LONGLONG* pDuration) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetStopPosition(LONGLONG* pStop) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetCurrentPosition(LONGLONG* pCurrent) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetPositions(LONGLONG* pCurrent, LONGLONG* pStop) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::SetRate(double dRate) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetRate(double* pdRate) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetPreroll(LONGLONG* pllPreroll) {return E_NOTIMPL;}
+
+// IVideoWindow
+STDMETHODIMP CBaseGraph::put_Caption(BSTR strCaption) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_Caption(BSTR* strCaption) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_WindowStyle(long WindowStyle) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_WindowStyle(long* WindowStyle) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_WindowStyleEx(long WindowStyleEx) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_WindowStyleEx(long* WindowStyleEx) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_AutoShow(long AutoShow) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_AutoShow(long* AutoShow) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_WindowState(long WindowState) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_WindowState(long* WindowState) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_BackgroundPalette(long BackgroundPalette) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_BackgroundPalette(long* pBackgroundPalette) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_Visible(long Visible) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_Visible(long* pVisible) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_Left(long Left) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_Left(long* pLeft) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_Width(long Width) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_Width(long* pWidth) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_Top(long Top) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_Top(long* pTop) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_Height(long Height) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_Height(long* pHeight) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_Owner(OAHWND Owner) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_Owner(OAHWND* Owner) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_MessageDrain(OAHWND Drain) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_MessageDrain(OAHWND* Drain) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_BorderColor(long* Color) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_BorderColor(long Color) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_FullScreenMode(long* FullScreenMode) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_FullScreenMode(long FullScreenMode) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::SetWindowForeground(long Focus) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::NotifyOwnerMessage(OAHWND hwnd, long uMsg, LONG_PTR wParam, LONG_PTR lParam) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::SetWindowPosition(long Left, long Top, long Width, long Height) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetWindowPosition(long* pLeft, long* pTop, long* pWidth, long* pHeight) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetMinIdealImageSize(long* pWidth, long* pHeight) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetMaxIdealImageSize(long* pWidth, long* pHeight) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetRestorePosition(long* pLeft, long* pTop, long* pWidth, long* pHeight) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::HideCursor(long HideCursor) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::IsCursorHidden(long* CursorHidden) {return E_NOTIMPL;}
+
+// IBasicVideo
+STDMETHODIMP CBaseGraph::get_AvgTimePerFrame(REFTIME* pAvgTimePerFrame) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_BitRate(long* pBitRate) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_BitErrorRate(long* pBitErrorRate) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_VideoWidth(long* pVideoWidth) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_VideoHeight(long* pVideoHeight) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_SourceLeft(long SourceLeft) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_SourceLeft(long* pSourceLeft) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_SourceWidth(long SourceWidth) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_SourceWidth(long* pSourceWidth) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_SourceTop(long SourceTop) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_SourceTop(long* pSourceTop) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_SourceHeight(long SourceHeight) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_SourceHeight(long* pSourceHeight) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_DestinationLeft(long DestinationLeft) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_DestinationLeft(long* pDestinationLeft) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_DestinationWidth(long DestinationWidth) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_DestinationWidth(long* pDestinationWidth) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_DestinationTop(long DestinationTop) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_DestinationTop(long* pDestinationTop) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_DestinationHeight(long DestinationHeight) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_DestinationHeight(long* pDestinationHeight) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::SetSourcePosition(long Left, long Top, long Width, long Height) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetSourcePosition(long* pLeft, long* pTop, long* pWidth, long* pHeight) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::SetDefaultSourcePosition() {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::SetDestinationPosition(long Left, long Top, long Width, long Height) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetDestinationPosition(long* pLeft, long* pTop, long* pWidth, long* pHeight) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::SetDefaultDestinationPosition() {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetVideoSize(long* pWidth, long* pHeight) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetVideoPaletteEntries(long StartIndex, long Entries, long* pRetrieved, long* pPalette) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::GetCurrentImage(long* pBufferSize, long* pDIBImage) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::IsUsingDefaultSource() {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::IsUsingDefaultDestination() {return E_NOTIMPL;}
+
+// IBasicAudio
+STDMETHODIMP CBaseGraph::put_Volume(long lVolume) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_Volume(long* plVolume) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::put_Balance(long lBalance) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::get_Balance(long* plBalance) {return E_NOTIMPL;}
+
+// IAMOpenProgress
+STDMETHODIMP CBaseGraph::QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent) {return E_NOTIMPL;}
+STDMETHODIMP CBaseGraph::AbortOperation() {return E_NOTIMPL;}
+
+// IGraphEngine
+STDMETHODIMP_(engine_t) CBaseGraph::GetEngine() {return DirectShow;}
+
diff --git a/src/apps/mplayerc/BaseGraph.h b/src/apps/mplayerc/BaseGraph.h
new file mode 100644
index 000000000..fd56597be
--- /dev/null
+++ b/src/apps/mplayerc/BaseGraph.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "IGraphBuilder2.h"
+
+class CPlayerWindow : public CWnd
+{
+public:
+ CPlayerWindow() {}
+
+protected:
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ DECLARE_MESSAGE_MAP()
+};
+
+typedef enum {DirectShow = 0, RealMedia, QuickTime, ShockWave} engine_t;
+
+[uuid("B110CDE5-6331-4118-8AAF-A870D6F7E2E4")]
+interface IGraphEngine : public IUnknown
+{
+ STDMETHOD_(engine_t, GetEngine) () = 0;
+};
+
+enum
+{
+ EC_BG_AUDIO_CHANGED = EC_USER+1,
+ EC_BG_ERROR
+};
+
+class CBaseGraph
+ : public CUnknown
+ , public IGraphBuilder2
+ , public IMediaControl
+ , public IMediaEventEx
+ , public IMediaSeeking
+ , public IVideoWindow
+ , public IBasicVideo
+ , public IBasicAudio
+ , public IAMOpenProgress
+ , public IGraphEngine
+{
+ OAHWND m_hNotifyWnd;
+ long m_lNotifyMsg;
+ LONG_PTR m_lNotifyInstData;
+
+ typedef struct {long m_lEventCode; LONG_PTR m_lParam1, m_lParam2;} GMSG;
+ CList<GMSG> m_msgqueue;
+
+protected:
+ void ClearMessageQueue();
+
+public:
+ CBaseGraph();
+ virtual ~CBaseGraph();
+
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ void NotifyEvent(long lEventCode, LONG_PTR lParam1 = 0, LONG_PTR lParam2 = 0);
+
+protected:
+ // IDispatch
+ STDMETHODIMP GetTypeInfoCount(UINT* pctinfo);
+ STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo);
+ STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId);
+ STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr);
+
+ // IFilterGraph
+ STDMETHODIMP AddFilter(IBaseFilter* pFilter, LPCWSTR pName);
+ STDMETHODIMP RemoveFilter(IBaseFilter* pFilter);
+ STDMETHODIMP EnumFilters(IEnumFilters** ppEnum);
+ STDMETHODIMP FindFilterByName(LPCWSTR pName, IBaseFilter** ppFilter);
+ STDMETHODIMP ConnectDirect(IPin* ppinOut, IPin* ppinIn, const AM_MEDIA_TYPE* pmt);
+ STDMETHODIMP Reconnect(IPin* ppin);
+ STDMETHODIMP Disconnect(IPin* ppin);
+ STDMETHODIMP SetDefaultSyncSource();
+
+ // IGraphBuilder
+ STDMETHODIMP Connect(IPin* ppinOut, IPin* ppinIn);
+ STDMETHODIMP Render(IPin* ppinOut);
+ STDMETHODIMP RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList);
+ STDMETHODIMP AddSourceFilter(LPCWSTR lpcwstrFileName, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter);
+ STDMETHODIMP SetLogFile(DWORD_PTR hFile);
+ STDMETHODIMP Abort();
+ STDMETHODIMP ShouldOperationContinue();
+
+ // IFilterGraph2
+ STDMETHODIMP AddSourceFilterForMoniker(IMoniker* pMoniker, IBindCtx* pCtx, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter);
+ STDMETHODIMP ReconnectEx(IPin* ppin, const AM_MEDIA_TYPE* pmt);
+ STDMETHODIMP RenderEx(IPin* pPinOut, DWORD dwFlags, DWORD* pvContext);
+
+ // IGraphBuilder2
+ STDMETHODIMP IsPinDirection(IPin* pPin, PIN_DIRECTION dir);
+ STDMETHODIMP IsPinConnected(IPin* pPin);
+ STDMETHODIMP ConnectFilter(IBaseFilter* pBF, IPin* pPinIn);
+ STDMETHODIMP ConnectFilter(IPin* pPinOut, IBaseFilter* pBF);
+ STDMETHODIMP ConnectFilterDirect(IPin* pPinOut, IBaseFilter* pBF, const AM_MEDIA_TYPE* pmt);
+ STDMETHODIMP NukeDownstream(IUnknown* pUnk);
+ STDMETHODIMP FindInterface(REFIID iid, void** ppv, BOOL bRemove);
+ STDMETHODIMP AddToROT();
+ STDMETHODIMP RemoveFromROT();
+
+ // IMediaControl
+ STDMETHODIMP Run();
+ STDMETHODIMP Pause();
+ STDMETHODIMP Stop();
+ STDMETHODIMP GetState(LONG msTimeout, OAFilterState* pfs);
+ STDMETHODIMP RenderFile(BSTR strFilename);
+ STDMETHODIMP AddSourceFilter(BSTR strFilename, IDispatch** ppUnk);
+ STDMETHODIMP get_FilterCollection(IDispatch** ppUnk);
+ STDMETHODIMP get_RegFilterCollection(IDispatch** ppUnk);
+ STDMETHODIMP StopWhenReady();
+
+ // IMediaEvent
+ STDMETHODIMP GetEventHandle(OAEVENT* hEvent);
+ STDMETHODIMP GetEvent(long* lEventCode, LONG_PTR* lParam1, LONG_PTR* lParam2, long msTimeout);
+ STDMETHODIMP WaitForCompletion(long msTimeout, long* pEvCode);
+ STDMETHODIMP CancelDefaultHandling(long lEvCode);
+ STDMETHODIMP RestoreDefaultHandling(long lEvCode);
+ STDMETHODIMP FreeEventParams(long lEvCode, LONG_PTR lParam1, LONG_PTR lParam2);
+
+ // IMediaEventEx
+ STDMETHODIMP SetNotifyWindow(OAHWND hwnd, long lMsg, LONG_PTR lInstanceData);
+ STDMETHODIMP SetNotifyFlags(long lNoNotifyFlags);
+ STDMETHODIMP GetNotifyFlags(long* lplNoNotifyFlags);
+
+ // IMediaSeeking
+ STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
+ STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
+ STDMETHODIMP IsFormatSupported(const GUID* pFormat);
+ STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
+ STDMETHODIMP GetTimeFormat(GUID* pFormat);
+ STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
+ STDMETHODIMP SetTimeFormat(const GUID* pFormat);
+ STDMETHODIMP GetDuration(LONGLONG* pDuration);
+ STDMETHODIMP GetStopPosition(LONGLONG* pStop);
+ STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
+ STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
+ STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
+ STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
+ STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
+ STDMETHODIMP SetRate(double dRate);
+ STDMETHODIMP GetRate(double* pdRate);
+ STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
+
+ // IVideoWindow
+ STDMETHODIMP put_Caption(BSTR strCaption);
+ STDMETHODIMP get_Caption(BSTR* strCaption);
+ STDMETHODIMP put_WindowStyle(long WindowStyle);
+ STDMETHODIMP get_WindowStyle(long* WindowStyle);
+ STDMETHODIMP put_WindowStyleEx(long WindowStyleEx);
+ STDMETHODIMP get_WindowStyleEx(long* WindowStyleEx);
+ STDMETHODIMP put_AutoShow(long AutoShow);
+ STDMETHODIMP get_AutoShow(long* AutoShow);
+ STDMETHODIMP put_WindowState(long WindowState);
+ STDMETHODIMP get_WindowState(long* WindowState);
+ STDMETHODIMP put_BackgroundPalette(long BackgroundPalette);
+ STDMETHODIMP get_BackgroundPalette(long* pBackgroundPalette);
+ STDMETHODIMP put_Visible(long Visible);
+ STDMETHODIMP get_Visible(long* pVisible);
+ STDMETHODIMP put_Left(long Left);
+ STDMETHODIMP get_Left(long* pLeft);
+ STDMETHODIMP put_Width(long Width);
+ STDMETHODIMP get_Width(long* pWidth);
+ STDMETHODIMP put_Top(long Top);
+ STDMETHODIMP get_Top(long* pTop);
+ STDMETHODIMP put_Height(long Height);
+ STDMETHODIMP get_Height(long* pHeight);
+ STDMETHODIMP put_Owner(OAHWND Owner);
+ STDMETHODIMP get_Owner(OAHWND* Owner);
+ STDMETHODIMP put_MessageDrain(OAHWND Drain);
+ STDMETHODIMP get_MessageDrain(OAHWND* Drain);
+ STDMETHODIMP get_BorderColor(long* Color);
+ STDMETHODIMP put_BorderColor(long Color);
+ STDMETHODIMP get_FullScreenMode(long* FullScreenMode);
+ STDMETHODIMP put_FullScreenMode(long FullScreenMode);
+ STDMETHODIMP SetWindowForeground(long Focus);
+ STDMETHODIMP NotifyOwnerMessage(OAHWND hwnd, long uMsg, LONG_PTR wParam, LONG_PTR lParam);
+ STDMETHODIMP SetWindowPosition(long Left, long Top, long Width, long Height);
+ STDMETHODIMP GetWindowPosition(long* pLeft, long* pTop, long* pWidth, long* pHeight);
+ STDMETHODIMP GetMinIdealImageSize(long* pWidth, long* pHeight);
+ STDMETHODIMP GetMaxIdealImageSize(long* pWidth, long* pHeight);
+ STDMETHODIMP GetRestorePosition(long* pLeft, long* pTop, long* pWidth, long* pHeight);
+ STDMETHODIMP HideCursor(long HideCursor);
+ STDMETHODIMP IsCursorHidden(long* CursorHidden);
+
+ // IBasicVideo
+ STDMETHODIMP get_AvgTimePerFrame(REFTIME* pAvgTimePerFrame);
+ STDMETHODIMP get_BitRate(long* pBitRate);
+ STDMETHODIMP get_BitErrorRate(long* pBitErrorRate);
+ STDMETHODIMP get_VideoWidth(long* pVideoWidth);
+ STDMETHODIMP get_VideoHeight(long* pVideoHeight);
+ STDMETHODIMP put_SourceLeft(long SourceLeft);
+ STDMETHODIMP get_SourceLeft(long* pSourceLeft);
+ STDMETHODIMP put_SourceWidth(long SourceWidth);
+ STDMETHODIMP get_SourceWidth(long* pSourceWidth);
+ STDMETHODIMP put_SourceTop(long SourceTop);
+ STDMETHODIMP get_SourceTop(long* pSourceTop);
+ STDMETHODIMP put_SourceHeight(long SourceHeight);
+ STDMETHODIMP get_SourceHeight(long* pSourceHeight);
+ STDMETHODIMP put_DestinationLeft(long DestinationLeft);
+ STDMETHODIMP get_DestinationLeft(long* pDestinationLeft);
+ STDMETHODIMP put_DestinationWidth(long DestinationWidth);
+ STDMETHODIMP get_DestinationWidth(long* pDestinationWidth);
+ STDMETHODIMP put_DestinationTop(long DestinationTop);
+ STDMETHODIMP get_DestinationTop(long* pDestinationTop);
+ STDMETHODIMP put_DestinationHeight(long DestinationHeight);
+ STDMETHODIMP get_DestinationHeight(long* pDestinationHeight);
+ STDMETHODIMP SetSourcePosition(long Left, long Top, long Width, long Height);
+ STDMETHODIMP GetSourcePosition(long* pLeft, long* pTop, long* pWidth, long* pHeight);
+ STDMETHODIMP SetDefaultSourcePosition();
+ STDMETHODIMP SetDestinationPosition(long Left, long Top, long Width, long Height);
+ STDMETHODIMP GetDestinationPosition(long* pLeft, long* pTop, long* pWidth, long* pHeight);
+ STDMETHODIMP SetDefaultDestinationPosition();
+ STDMETHODIMP GetVideoSize(long* pWidth, long* pHeight);
+ STDMETHODIMP GetVideoPaletteEntries(long StartIndex, long Entries, long* pRetrieved, long* pPalette);
+ STDMETHODIMP GetCurrentImage(long* pBufferSize, long* pDIBImage);
+ STDMETHODIMP IsUsingDefaultSource();
+ STDMETHODIMP IsUsingDefaultDestination();
+
+ // IBasicAudio
+ STDMETHODIMP put_Volume(long lVolume);
+ STDMETHODIMP get_Volume(long* plVolume);
+ STDMETHODIMP put_Balance(long lBalance);
+ STDMETHODIMP get_Balance(long* plBalance);
+
+ // IAMOpenProgress
+ STDMETHODIMP QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent);
+ STDMETHODIMP AbortOperation();
+
+ // IGraphEngine
+ STDMETHODIMP_(engine_t) GetEngine();
+};
+
diff --git a/src/apps/mplayerc/CShockwaveFlash.cpp b/src/apps/mplayerc/CShockwaveFlash.cpp
new file mode 100644
index 000000000..002a1249e
--- /dev/null
+++ b/src/apps/mplayerc/CShockwaveFlash.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// CShockwaveFlash.cpp : Definition of ActiveX Control wrapper class(es) created by Microsoft Visual C++
+
+
+#include "stdafx.h"
+#include "CShockwaveFlash.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// CShockwaveFlash
+
+IMPLEMENT_DYNCREATE(CShockwaveFlash, CWnd)
+
+// CShockwaveFlash properties
+
+// CShockwaveFlash operations
diff --git a/src/apps/mplayerc/CShockwaveFlash.h b/src/apps/mplayerc/CShockwaveFlash.h
new file mode 100644
index 000000000..da084cffe
--- /dev/null
+++ b/src/apps/mplayerc/CShockwaveFlash.h
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// CShockwaveFlash.h : Declaration of ActiveX Control wrapper class(es) created by Microsoft Visual C++
+
+#pragma once
+
+/////////////////////////////////////////////////////////////////////////////
+// CShockwaveFlash
+
+class CShockwaveFlash : public CWnd
+{
+protected:
+ DECLARE_DYNCREATE(CShockwaveFlash)
+public:
+ CLSID const& GetClsid()
+ {
+ static CLSID const clsid
+ = { 0xD27CDB6E, 0xAE6D, 0x11CF, { 0x96, 0xB8, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0 } };
+ return clsid;
+ }
+ virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle,
+ const RECT& rect, CWnd* pParentWnd, UINT nID,
+ CCreateContext* pContext = NULL)
+ {
+ return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID);
+ }
+
+ BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
+ UINT nID, CFile* pPersist = NULL, BOOL bStorage = FALSE,
+ BSTR bstrLicKey = NULL)
+ {
+ return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID,
+ pPersist, bStorage, bstrLicKey);
+ }
+
+// Attributes
+public:
+
+// Operations
+public:
+
+ long get_ReadyState()
+ {
+ long result;
+ InvokeHelper(DISPID_READYSTATE, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
+ return result;
+ }
+ long get_TotalFrames()
+ {
+ long result;
+ InvokeHelper(0x7c, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
+ return result;
+ }
+ BOOL get_Playing()
+ {
+ BOOL result;
+ InvokeHelper(0x7d, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL);
+ return result;
+ }
+ void put_Playing(BOOL newValue)
+ {
+ static BYTE parms[] = VTS_BOOL ;
+ InvokeHelper(0x7d, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ long get_Quality()
+ {
+ long result;
+ InvokeHelper(0x69, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
+ return result;
+ }
+ void put_Quality(long newValue)
+ {
+ static BYTE parms[] = VTS_I4 ;
+ InvokeHelper(0x69, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ long get_ScaleMode()
+ {
+ long result;
+ InvokeHelper(0x78, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
+ return result;
+ }
+ void put_ScaleMode(long newValue)
+ {
+ static BYTE parms[] = VTS_I4 ;
+ InvokeHelper(0x78, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ long get_AlignMode()
+ {
+ long result;
+ InvokeHelper(0x79, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
+ return result;
+ }
+ void put_AlignMode(long newValue)
+ {
+ static BYTE parms[] = VTS_I4 ;
+ InvokeHelper(0x79, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ long get_BackgroundColor()
+ {
+ long result;
+ InvokeHelper(0x7b, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
+ return result;
+ }
+ void put_BackgroundColor(long newValue)
+ {
+ static BYTE parms[] = VTS_I4 ;
+ InvokeHelper(0x7b, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ BOOL get_Loop()
+ {
+ BOOL result;
+ InvokeHelper(0x6a, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL);
+ return result;
+ }
+ void put_Loop(BOOL newValue)
+ {
+ static BYTE parms[] = VTS_BOOL ;
+ InvokeHelper(0x6a, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ CString get_Movie()
+ {
+ CString result;
+ InvokeHelper(0x66, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
+ return result;
+ }
+ void put_Movie(LPCTSTR newValue)
+ {
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0x66, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ long get_FrameNum()
+ {
+ long result;
+ InvokeHelper(0x6b, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
+ return result;
+ }
+ void put_FrameNum(long newValue)
+ {
+ static BYTE parms[] = VTS_I4 ;
+ InvokeHelper(0x6b, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ void SetZoomRect(long left, long top, long right, long bottom)
+ {
+ static BYTE parms[] = VTS_I4 VTS_I4 VTS_I4 VTS_I4 ;
+ InvokeHelper(0x6d, DISPATCH_METHOD, VT_EMPTY, NULL, parms, left, top, right, bottom);
+ }
+ void Zoom(long factor)
+ {
+ static BYTE parms[] = VTS_I4 ;
+ InvokeHelper(0x76, DISPATCH_METHOD, VT_EMPTY, NULL, parms, factor);
+ }
+ void Pan(long x, long y, long mode)
+ {
+ static BYTE parms[] = VTS_I4 VTS_I4 VTS_I4 ;
+ InvokeHelper(0x77, DISPATCH_METHOD, VT_EMPTY, NULL, parms, x, y, mode);
+ }
+ void Play()
+ {
+ InvokeHelper(0x70, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
+ }
+ void Stop()
+ {
+ InvokeHelper(0x71, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
+ }
+ void Back()
+ {
+ InvokeHelper(0x72, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
+ }
+ void Forward()
+ {
+ InvokeHelper(0x73, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
+ }
+ void Rewind()
+ {
+ InvokeHelper(0x74, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
+ }
+ void StopPlay()
+ {
+ InvokeHelper(0x7e, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
+ }
+ void GotoFrame(long FrameNum)
+ {
+ static BYTE parms[] = VTS_I4 ;
+ InvokeHelper(0x7f, DISPATCH_METHOD, VT_EMPTY, NULL, parms, FrameNum);
+ }
+ long CurrentFrame()
+ {
+ long result;
+ InvokeHelper(0x80, DISPATCH_METHOD, VT_I4, (void*)&result, NULL);
+ return result;
+ }
+ BOOL IsPlaying()
+ {
+ BOOL result;
+ InvokeHelper(0x81, DISPATCH_METHOD, VT_BOOL, (void*)&result, NULL);
+ return result;
+ }
+ long PercentLoaded()
+ {
+ long result;
+ InvokeHelper(0x82, DISPATCH_METHOD, VT_I4, (void*)&result, NULL);
+ return result;
+ }
+ BOOL FrameLoaded(long FrameNum)
+ {
+ BOOL result;
+ static BYTE parms[] = VTS_I4 ;
+ InvokeHelper(0x83, DISPATCH_METHOD, VT_BOOL, (void*)&result, parms, FrameNum);
+ return result;
+ }
+ long FlashVersion()
+ {
+ long result;
+ InvokeHelper(0x84, DISPATCH_METHOD, VT_I4, (void*)&result, NULL);
+ return result;
+ }
+ CString get_WMode()
+ {
+ CString result;
+ InvokeHelper(0x85, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
+ return result;
+ }
+ void put_WMode(LPCTSTR newValue)
+ {
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0x85, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ CString get_SAlign()
+ {
+ CString result;
+ InvokeHelper(0x86, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
+ return result;
+ }
+ void put_SAlign(LPCTSTR newValue)
+ {
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0x86, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ BOOL get_Menu()
+ {
+ BOOL result;
+ InvokeHelper(0x87, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL);
+ return result;
+ }
+ void put_Menu(BOOL newValue)
+ {
+ static BYTE parms[] = VTS_BOOL ;
+ InvokeHelper(0x87, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ CString get_Base()
+ {
+ CString result;
+ InvokeHelper(0x88, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
+ return result;
+ }
+ void put_Base(LPCTSTR newValue)
+ {
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0x88, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ CString get_Scale()
+ {
+ CString result;
+ InvokeHelper(0x89, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
+ return result;
+ }
+ void put_Scale(LPCTSTR newValue)
+ {
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0x89, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ BOOL get_DeviceFont()
+ {
+ BOOL result;
+ InvokeHelper(0x8a, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL);
+ return result;
+ }
+ void put_DeviceFont(BOOL newValue)
+ {
+ static BYTE parms[] = VTS_BOOL ;
+ InvokeHelper(0x8a, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ BOOL get_EmbedMovie()
+ {
+ BOOL result;
+ InvokeHelper(0x8b, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL);
+ return result;
+ }
+ void put_EmbedMovie(BOOL newValue)
+ {
+ static BYTE parms[] = VTS_BOOL ;
+ InvokeHelper(0x8b, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ CString get_BGColor()
+ {
+ CString result;
+ InvokeHelper(0x8c, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
+ return result;
+ }
+ void put_BGColor(LPCTSTR newValue)
+ {
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0x8c, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ CString get_Quality2()
+ {
+ CString result;
+ InvokeHelper(0x8d, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
+ return result;
+ }
+ void put_Quality2(LPCTSTR newValue)
+ {
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0x8d, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ void LoadMovie(long layer, LPCTSTR url)
+ {
+ static BYTE parms[] = VTS_I4 VTS_BSTR ;
+ InvokeHelper(0x8e, DISPATCH_METHOD, VT_EMPTY, NULL, parms, layer, url);
+ }
+ void TGotoFrame(LPCTSTR target, long FrameNum)
+ {
+ static BYTE parms[] = VTS_BSTR VTS_I4 ;
+ InvokeHelper(0x8f, DISPATCH_METHOD, VT_EMPTY, NULL, parms, target, FrameNum);
+ }
+ void TGotoLabel(LPCTSTR target, LPCTSTR label)
+ {
+ static BYTE parms[] = VTS_BSTR VTS_BSTR ;
+ InvokeHelper(0x90, DISPATCH_METHOD, VT_EMPTY, NULL, parms, target, label);
+ }
+ long TCurrentFrame(LPCTSTR target)
+ {
+ long result;
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0x91, DISPATCH_METHOD, VT_I4, (void*)&result, parms, target);
+ return result;
+ }
+ CString TCurrentLabel(LPCTSTR target)
+ {
+ CString result;
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0x92, DISPATCH_METHOD, VT_BSTR, (void*)&result, parms, target);
+ return result;
+ }
+ void TPlay(LPCTSTR target)
+ {
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0x93, DISPATCH_METHOD, VT_EMPTY, NULL, parms, target);
+ }
+ void TStopPlay(LPCTSTR target)
+ {
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0x94, DISPATCH_METHOD, VT_EMPTY, NULL, parms, target);
+ }
+ void SetVariable(LPCTSTR name, LPCTSTR value)
+ {
+ static BYTE parms[] = VTS_BSTR VTS_BSTR ;
+ InvokeHelper(0x97, DISPATCH_METHOD, VT_EMPTY, NULL, parms, name, value);
+ }
+ CString GetVariable(LPCTSTR name)
+ {
+ CString result;
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0x98, DISPATCH_METHOD, VT_BSTR, (void*)&result, parms, name);
+ return result;
+ }
+ void TSetProperty(LPCTSTR target, long property, LPCTSTR value)
+ {
+ static BYTE parms[] = VTS_BSTR VTS_I4 VTS_BSTR ;
+ InvokeHelper(0x99, DISPATCH_METHOD, VT_EMPTY, NULL, parms, target, property, value);
+ }
+ CString TGetProperty(LPCTSTR target, long property)
+ {
+ CString result;
+ static BYTE parms[] = VTS_BSTR VTS_I4 ;
+ InvokeHelper(0x9a, DISPATCH_METHOD, VT_BSTR, (void*)&result, parms, target, property);
+ return result;
+ }
+ void TCallFrame(LPCTSTR target, long FrameNum)
+ {
+ static BYTE parms[] = VTS_BSTR VTS_I4 ;
+ InvokeHelper(0x9b, DISPATCH_METHOD, VT_EMPTY, NULL, parms, target, FrameNum);
+ }
+ void TCallLabel(LPCTSTR target, LPCTSTR label)
+ {
+ static BYTE parms[] = VTS_BSTR VTS_BSTR ;
+ InvokeHelper(0x9c, DISPATCH_METHOD, VT_EMPTY, NULL, parms, target, label);
+ }
+ void TSetPropertyNum(LPCTSTR target, long property, double value)
+ {
+ static BYTE parms[] = VTS_BSTR VTS_I4 VTS_R8 ;
+ InvokeHelper(0x9d, DISPATCH_METHOD, VT_EMPTY, NULL, parms, target, property, value);
+ }
+ double TGetPropertyNum(LPCTSTR target, long property)
+ {
+ double result;
+ static BYTE parms[] = VTS_BSTR VTS_I4 ;
+ InvokeHelper(0x9e, DISPATCH_METHOD, VT_R8, (void*)&result, parms, target, property);
+ return result;
+ }
+ double TGetPropertyAsNumber(LPCTSTR target, long property)
+ {
+ double result;
+ static BYTE parms[] = VTS_BSTR VTS_I4 ;
+ InvokeHelper(0xac, DISPATCH_METHOD, VT_R8, (void*)&result, parms, target, property);
+ return result;
+ }
+ CString get_SWRemote()
+ {
+ CString result;
+ InvokeHelper(0x9f, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
+ return result;
+ }
+ void put_SWRemote(LPCTSTR newValue)
+ {
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0x9f, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ CString get_FlashVars()
+ {
+ CString result;
+ InvokeHelper(0xaa, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
+ return result;
+ }
+ void put_FlashVars(LPCTSTR newValue)
+ {
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0xaa, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+ CString get_AllowScriptAccess()
+ {
+ CString result;
+ InvokeHelper(0xab, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
+ return result;
+ }
+ void put_AllowScriptAccess(LPCTSTR newValue)
+ {
+ static BYTE parms[] = VTS_BSTR ;
+ InvokeHelper(0xab, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
+ }
+
+
+};
diff --git a/src/apps/mplayerc/ChildView.cpp b/src/apps/mplayerc/ChildView.cpp
new file mode 100644
index 000000000..c16641802
--- /dev/null
+++ b/src/apps/mplayerc/ChildView.cpp
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// ChildView.cpp : implementation of the CChildView class
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "ChildView.h"
+#include "MainFrm.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CChildView
+
+CChildView::CChildView() : m_vrect(0,0,0,0)
+{
+ m_lastlmdowntime = 0;
+ m_lastlmdownpoint.SetPoint(0, 0);
+
+ LoadLogo();
+}
+
+CChildView::~CChildView()
+{
+}
+
+BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if(!CWnd::PreCreateWindow(cs))
+ return FALSE;
+
+ cs.style &= ~WS_BORDER;
+ cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
+ ::LoadCursor(NULL, IDC_HAND), HBRUSH(COLOR_WINDOW+1), NULL);
+
+ return TRUE;
+}
+
+BOOL CChildView::PreTranslateMessage(MSG* pMsg)
+{
+ if(pMsg->message >= WM_MOUSEFIRST && pMsg->message <= WM_MYMOUSELAST)
+ {
+ CWnd* pParent = GetParent();
+ CPoint p(pMsg->lParam);
+ ::MapWindowPoints(pMsg->hwnd, pParent->m_hWnd, &p, 1);
+
+ bool fDblClick = false;
+
+ bool fInteractiveVideo = ((CMainFrame*)AfxGetMainWnd())->IsInteractiveVideo();
+/*
+ if(fInteractiveVideo)
+ {
+ if(pMsg->message == WM_LBUTTONDOWN)
+ {
+ if((pMsg->time - m_lastlmdowntime) <= GetDoubleClickTime()
+ && abs(pMsg->pt.x - m_lastlmdownpoint.x) <= GetSystemMetrics(SM_CXDOUBLECLK)
+ && abs(pMsg->pt.y - m_lastlmdownpoint.y) <= GetSystemMetrics(SM_CYDOUBLECLK))
+ {
+ fDblClick = true;
+ m_lastlmdowntime = 0;
+ m_lastlmdownpoint.SetPoint(0, 0);
+ }
+ else
+ {
+ m_lastlmdowntime = pMsg->time;
+ m_lastlmdownpoint = pMsg->pt;
+ }
+ }
+ else if(pMsg->message == WM_LBUTTONDBLCLK)
+ {
+ m_lastlmdowntime = pMsg->time;
+ m_lastlmdownpoint = pMsg->pt;
+ }
+ }
+*/
+ if((pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONUP || pMsg->message == WM_MOUSEMOVE)
+ && fInteractiveVideo)
+ {
+ if(pMsg->message == WM_MOUSEMOVE)
+ {
+ pParent->PostMessage(pMsg->message, pMsg->wParam, MAKELPARAM(p.x, p.y));
+ }
+
+ if(fDblClick)
+ {
+ pParent->PostMessage(WM_LBUTTONDOWN, pMsg->wParam, MAKELPARAM(p.x, p.y));
+ pParent->PostMessage(WM_LBUTTONDBLCLK, pMsg->wParam, MAKELPARAM(p.x, p.y));
+ }
+ }
+ else
+ {
+ pParent->PostMessage(pMsg->message, pMsg->wParam, MAKELPARAM(p.x, p.y));
+ return TRUE;
+ }
+ }
+
+ return CWnd::PreTranslateMessage(pMsg);
+}
+
+void CChildView::SetVideoRect(CRect r)
+{
+ m_vrect = r;
+
+ Invalidate();
+}
+
+void CChildView::LoadLogo()
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ CAutoLock cAutoLock(&m_csLogo);
+
+ m_logo.Destroy();
+
+ if(s.logoext)
+ {
+ if(AfxGetAppSettings().fXpOrBetter)
+ m_logo.Load(s.logofn);
+ else if(HANDLE h = LoadImage(NULL, s.logofn, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE))
+ m_logo.Attach((HBITMAP)h); // win9x bug: Inside Attach GetObject() will return all zeros in DIBSECTION and silly CImage uses that to init width, height, bpp, ... so we can't use CImage::Draw later
+ }
+
+ if(m_logo.IsNull())
+ {
+ m_logo.LoadFromResource(AfxGetInstanceHandle(), s.logoid);
+ }
+
+ if(m_hWnd) Invalidate();
+}
+
+CSize CChildView::GetLogoSize()
+{
+ CSize ret(0,0);
+ if(!m_logo.IsNull())
+ ret.SetSize(m_logo.GetWidth(), m_logo.GetHeight());
+ return ret;
+}
+
+IMPLEMENT_DYNAMIC(CChildView, CWnd)
+
+BEGIN_MESSAGE_MAP(CChildView, CWnd)
+ //{{AFX_MSG_MAP(CChildView)
+ ON_WM_PAINT()
+ ON_WM_ERASEBKGND()
+ ON_WM_SIZE()
+ ON_WM_WINDOWPOSCHANGED()
+ ON_COMMAND_EX(ID_PLAY_PLAYPAUSE, OnPlayPlayPauseStop)
+ ON_COMMAND_EX(ID_PLAY_PLAY, OnPlayPlayPauseStop)
+ ON_COMMAND_EX(ID_PLAY_PAUSE, OnPlayPlayPauseStop)
+ ON_COMMAND_EX(ID_PLAY_STOP, OnPlayPlayPauseStop)
+ ON_WM_SETCURSOR()
+ ON_WM_NCCALCSIZE()
+ ON_WM_NCPAINT()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CChildView message handlers
+
+void CChildView::OnPaint()
+{
+ CPaintDC dc(this); // device context for painting
+
+ ((CMainFrame*)GetParentFrame())->RepaintVideo();
+
+ // Do not call CWnd::OnPaint() for painting messages
+}
+
+BOOL CChildView::OnEraseBkgnd(CDC* pDC)
+{
+ CRect r;
+
+ CAutoLock cAutoLock(&m_csLogo);
+
+ if(((CMainFrame*)GetParentFrame())->IsSomethingLoaded())
+ {
+ pDC->ExcludeClipRect(m_vrect);
+ }
+ else if(!m_logo.IsNull() /*&& ((CMainFrame*)GetParentFrame())->IsPlaylistEmpty()*/)
+ {
+ BITMAP bm;
+ GetObject(m_logo, sizeof(bm), &bm);
+
+ GetClientRect(r);
+ int w = min(bm.bmWidth, r.Width());
+ int h = min(abs(bm.bmHeight), r.Height());
+// int w = min(m_logo.GetWidth(), r.Width());
+// int h = min(m_logo.GetHeight(), r.Height());
+ int x = (r.Width() - w) / 2;
+ int y = (r.Height() - h) / 2;
+ r = CRect(CPoint(x, y), CSize(w, h));
+
+ int oldmode = pDC->SetStretchBltMode(STRETCH_HALFTONE);
+ m_logo.StretchBlt(*pDC, r, CRect(0,0,bm.bmWidth,abs(bm.bmHeight)));
+// m_logo.Draw(*pDC, r);
+ pDC->SetStretchBltMode(oldmode);
+
+ pDC->ExcludeClipRect(r);
+ }
+
+ GetClientRect(r);
+ pDC->FillSolidRect(r, 0);
+
+ return TRUE;
+}
+
+void CChildView::OnSize(UINT nType, int cx, int cy)
+{
+ CWnd::OnSize(nType, cx, cy);
+
+ ((CMainFrame*)GetParentFrame())->MoveVideoWindow();
+}
+
+void CChildView::OnWindowPosChanged(WINDOWPOS* lpwndpos)
+{
+ CWnd::OnWindowPosChanged(lpwndpos);
+
+ ((CMainFrame*)GetParentFrame())->MoveVideoWindow();
+}
+
+BOOL CChildView::OnPlayPlayPauseStop(UINT nID)
+{
+ if(nID == ID_PLAY_STOP) SetVideoRect();
+ return FALSE;
+}
+
+BOOL CChildView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
+{
+ if(((CMainFrame*)GetParentFrame())->m_fHideCursor)
+ {
+ SetCursor(NULL);
+ return TRUE;
+ }
+
+ return CWnd::OnSetCursor(pWnd, nHitTest, message);
+}
+
+void CChildView::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
+{
+ if(!((CMainFrame*)GetParentFrame())->IsFrameLessWindow())
+ {
+ InflateRect(&lpncsp->rgrc[0], -1, -1);
+ }
+
+ CWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
+}
+
+void CChildView::OnNcPaint()
+{
+ if(!((CMainFrame*)GetParentFrame())->IsFrameLessWindow())
+ {
+ CRect r;
+ GetWindowRect(r);
+ r.OffsetRect(-r.left, -r.top);
+
+ CWindowDC(this).Draw3dRect(&r, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
+ }
+}
+
diff --git a/src/apps/mplayerc/ChildView.h b/src/apps/mplayerc/ChildView.h
new file mode 100644
index 000000000..7b91ca90a
--- /dev/null
+++ b/src/apps/mplayerc/ChildView.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <atlimage.h>
+
+class CChildView : public CWnd
+{
+ CRect m_vrect;
+
+ DWORD m_lastlmdowntime;
+ CPoint m_lastlmdownpoint;
+
+ CCritSec m_csLogo;
+ CImage m_logo;
+
+public:
+ CChildView();
+ virtual ~CChildView();
+
+ DECLARE_DYNAMIC(CChildView)
+
+public:
+ void SetVideoRect(CRect r = CRect(0,0,0,0));
+ CRect GetVideoRect() {return(m_vrect);}
+
+ void LoadLogo();
+ CSize GetLogoSize();
+
+protected:
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ afx_msg void OnPaint();
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnWindowPosChanged(WINDOWPOS* lpwndpos);
+ afx_msg BOOL OnPlayPlayPauseStop(UINT nID);
+ afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
+ afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp);
+ afx_msg void OnNcPaint();
+
+ DECLARE_MESSAGE_MAP()
+public:
+ afx_msg void OnSetFocus(CWnd* pOldWnd);
+};
diff --git a/src/apps/mplayerc/ComPropertyPage.cpp b/src/apps/mplayerc/ComPropertyPage.cpp
new file mode 100644
index 000000000..23df655a2
--- /dev/null
+++ b/src/apps/mplayerc/ComPropertyPage.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// ComPropertyPage.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "ComPropertyPage.h"
+#include "ComPropertySheet.h"
+
+
+// CComPropertyPage dialog
+
+IMPLEMENT_DYNAMIC(CComPropertyPage, CPropertyPage)
+CComPropertyPage::CComPropertyPage(IPropertyPage* pPage)
+ : CPropertyPage(CComPropertyPage::IDD), m_pPage(pPage)
+{
+ PROPPAGEINFO ppi;
+ m_pPage->GetPageInfo(&ppi);
+ m_pPSP->pszTitle = (m_strCaption = ppi.pszTitle);
+ m_psp.dwFlags |= PSP_USETITLE;
+}
+
+CComPropertyPage::~CComPropertyPage()
+{
+}
+
+void CComPropertyPage::DoDataExchange(CDataExchange* pDX)
+{
+ CPropertyPage::DoDataExchange(pDX);
+}
+
+BOOL CComPropertyPage::OnInitDialog()
+{
+ CPropertyPage::OnInitDialog();
+
+ CRect r;
+ PROPPAGEINFO ppi;
+ m_pPage->GetPageInfo(&ppi);
+ r = CRect(CPoint(0,0), ppi.size);
+ m_pPage->Activate(m_hWnd, r, FALSE);
+ m_pPage->Show(SW_SHOW);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CComPropertyPage::OnDestroy()
+{
+ CPropertyPage::OnDestroy();
+
+ m_pPage->Deactivate();
+}
+
+BOOL CComPropertyPage::OnSetActive()
+{
+ SetModified(S_OK == m_pPage->IsPageDirty());
+
+ CWnd* pParent = GetParent();
+ if(pParent->IsKindOf(RUNTIME_CLASS(CComPropertySheet)))
+ {
+ CComPropertySheet* pSheet = (CComPropertySheet*)pParent;
+ pSheet->OnActivated(this);
+ }
+
+ return CPropertyPage::OnSetActive();
+}
+
+BOOL CComPropertyPage::OnKillActive()
+{
+ SetModified(FALSE);
+
+ return CPropertyPage::OnKillActive();
+}
+
+
+BEGIN_MESSAGE_MAP(CComPropertyPage, CPropertyPage)
+ ON_WM_DESTROY()
+END_MESSAGE_MAP()
+
+
+// CComPropertyPage message handlers
+
+void CComPropertyPage::OnOK()
+{
+ if(S_OK == m_pPage->IsPageDirty()) m_pPage->Apply();
+ SetModified(FALSE);
+
+ CPropertyPage::OnOK();
+}
diff --git a/src/apps/mplayerc/ComPropertyPage.h b/src/apps/mplayerc/ComPropertyPage.h
new file mode 100644
index 000000000..e36ea6801
--- /dev/null
+++ b/src/apps/mplayerc/ComPropertyPage.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+
+// CComPropertyPage dialog
+
+class CComPropertyPage : public CPropertyPage
+{
+ DECLARE_DYNAMIC(CComPropertyPage)
+
+ CComPtr<IPropertyPage> m_pPage;
+
+public:
+ CComPropertyPage(IPropertyPage* pPage);
+ virtual ~CComPropertyPage();
+
+// Dialog Data
+ enum { IDD = IDD_COMPROPERTYPAGE };
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnSetActive();
+ virtual BOOL OnKillActive();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ virtual BOOL OnInitDialog();
+ afx_msg void OnDestroy();
+ virtual void OnOK();
+};
+
diff --git a/src/apps/mplayerc/ComPropertySheet.cpp b/src/apps/mplayerc/ComPropertySheet.cpp
new file mode 100644
index 000000000..49cc664ed
--- /dev/null
+++ b/src/apps/mplayerc/ComPropertySheet.cpp
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// ComPropertySheet.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "ComPropertySheet.h"
+#include "..\..\DSUtil\DSUtil.h"
+#include "..\..\filters\InternalPropertyPage.h"
+
+// CComPropertyPageSite
+
+class CComPropertyPageSite : public CUnknown, public IPropertyPageSite
+{
+ IComPropertyPageDirty* m_pPPD;
+
+public:
+ CComPropertyPageSite(IComPropertyPageDirty* pPPD) : CUnknown(NAME("CComPropertyPageSite"), NULL), m_pPPD(pPPD) {}
+
+ DECLARE_IUNKNOWN
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv)
+ {
+ return
+ QI(IPropertyPageSite)
+ __super::NonDelegatingQueryInterface(riid, ppv);
+ }
+
+ // IPropertyPageSite
+ STDMETHODIMP OnStatusChange(DWORD flags)
+ {
+ if(m_pPPD)
+ {
+ if(flags&PROPPAGESTATUS_DIRTY) m_pPPD->OnSetDirty(true);
+ if(flags&PROPPAGESTATUS_CLEAN) m_pPPD->OnSetDirty(false);
+ }
+ return S_OK;
+ }
+ STDMETHODIMP GetLocaleID(LCID* pLocaleID)
+ {
+ CheckPointer(pLocaleID, E_POINTER);
+ *pLocaleID = ::GetUserDefaultLCID();
+ return S_OK;
+ }
+ STDMETHODIMP GetPageContainer(IUnknown** ppUnk) {return E_NOTIMPL;}
+ STDMETHODIMP TranslateAccelerator(LPMSG pMsg) {return E_NOTIMPL;}
+};
+
+// CComPropertySheet
+
+IMPLEMENT_DYNAMIC(CComPropertySheet, CPropertySheet)
+CComPropertySheet::CComPropertySheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
+ : CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
+{
+ m_pSite = new CComPropertyPageSite(this);
+ m_size.SetSize(0, 0);
+}
+
+CComPropertySheet::CComPropertySheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
+ : CPropertySheet(pszCaption, pParentWnd, iSelectPage)
+{
+ m_pSite = new CComPropertyPageSite(this);
+ m_size.SetSize(0, 0);
+}
+
+CComPropertySheet::~CComPropertySheet()
+{
+}
+
+int CComPropertySheet::AddPages(CComPtr<ISpecifyPropertyPages> pSPP)
+{
+ if(!pSPP) return(0);
+
+ CAUUID caGUID;
+ caGUID.pElems = NULL;
+ if(FAILED(pSPP->GetPages(&caGUID)))
+ return(0);
+
+ IUnknown* lpUnk = NULL;
+ if(FAILED(pSPP.QueryInterface(&lpUnk)))
+ return(0);
+
+ m_spp.AddTail(pSPP);
+
+ CComQIPtr<ISpecifyPropertyPages2> pSPP2 = pSPP;
+ CComQIPtr<IPersist> pPersist = pSPP;
+
+ ULONG nPages = 0;
+ for(ULONG i = 0; i < caGUID.cElems; i++)
+ {
+ CComPtr<IPropertyPage> pPage;
+
+ HRESULT hr = E_FAIL;
+
+ if(FAILED(hr) && !pPage && pSPP2)
+ {
+ hr = pSPP2->CreatePage(caGUID.pElems[i], &pPage);
+ }
+
+ if(FAILED(hr) && !pPage)
+ {
+ hr = pPage.CoCreateInstance(caGUID.pElems[i]);
+ }
+
+ if(FAILED(hr) && !pPage && pPersist)
+ {
+ hr = LoadExternalPropertyPage(pPersist, caGUID.pElems[i], &pPage);
+ }
+
+ if(SUCCEEDED(hr))
+ {
+ if(AddPage(pPage, lpUnk))
+ nPages++;
+ }
+ }
+
+ if(caGUID.pElems) CoTaskMemFree(caGUID.pElems);
+ lpUnk->Release();
+
+ return(nPages);
+}
+
+bool CComPropertySheet::AddPage(IPropertyPage* pPage, IUnknown* pUnk)
+{
+ if(!pPage || !pUnk) return false;
+
+ HRESULT hr;
+ hr = pPage->SetPageSite(m_pSite);
+ hr = pPage->SetObjects(1, &pUnk);
+ PROPPAGEINFO ppi;
+ hr = pPage->GetPageInfo(&ppi);
+ m_size.cx = max(m_size.cx, ppi.size.cx);
+ m_size.cy = max(m_size.cy, ppi.size.cy);
+ CAutoPtr<CComPropertyPage> p(new CComPropertyPage(pPage));
+ __super::AddPage(p);
+ m_pages.AddTail(p);
+
+ return true;
+}
+
+void CComPropertySheet::OnActivated(CPropertyPage* pPage)
+{
+ if(!pPage) return;
+
+ CRect bounds(30000,30000,-30000,-30000);
+
+ CRect wr, cr;
+ GetWindowRect(wr);
+ GetClientRect(cr);
+ CSize ws = wr.Size(), cs = cr.Size();
+
+ CRect twr, tcr;
+ CTabCtrl* pTC = (CTabCtrl*)GetDlgItem(AFX_IDC_TAB_CONTROL);
+ pTC->GetWindowRect(twr);
+ pTC->GetClientRect(tcr);
+ CSize tws = twr.Size(), tcs = tcr.Size();
+
+ if(CWnd* pChild = pPage->GetWindow(GW_CHILD))
+ {
+ pChild->ModifyStyle(WS_CAPTION|WS_THICKFRAME, 0);
+ pChild->ModifyStyleEx(WS_EX_DLGMODALFRAME, WS_EX_CONTROLPARENT);
+
+ for(CWnd* pGrandChild = pChild->GetWindow(GW_CHILD); pGrandChild; pGrandChild = pGrandChild->GetNextWindow())
+ {
+ if(!(pGrandChild->GetStyle()&WS_VISIBLE)) continue;
+
+ CRect r;
+ pGrandChild->GetWindowRect(&r);
+ pChild->ScreenToClient(r);
+ bounds |= r;
+ }
+ }
+
+ bounds |= CRect(0,0,0,0);
+ bounds.SetRect(0, 0, bounds.right + max(bounds.left, 4), bounds.bottom + max(bounds.top, 4));
+
+ CRect r = CRect(CPoint(0,0), bounds.Size());
+ pTC->AdjustRect(TRUE, r);
+ r.SetRect(twr.TopLeft(), twr.TopLeft() + r.Size());
+ ScreenToClient(r);
+ pTC->MoveWindow(r);
+ pTC->ModifyStyle(TCS_MULTILINE, TCS_SINGLELINE);
+
+ CSize diff = r.Size() - tws;
+
+ if(!bounds.IsRectEmpty())
+ {
+ if(CWnd* pChild = pPage->GetWindow(GW_CHILD))
+ pChild->MoveWindow(bounds);
+ CRect r = twr;
+ pTC->AdjustRect(FALSE, r);
+ ScreenToClient(r);
+ pPage->MoveWindow(CRect(r.TopLeft(), bounds.Size()));
+ }
+
+ int _afxPropSheetButtons[] = { IDOK, IDCANCEL, ID_APPLY_NOW, IDHELP };
+ for(int i = 0; i < countof(_afxPropSheetButtons); i++)
+ {
+ if(CWnd* pWnd = GetDlgItem(_afxPropSheetButtons[i]))
+ {
+ pWnd->GetWindowRect(r);
+ ScreenToClient(r);
+ pWnd->MoveWindow(CRect(r.TopLeft() + diff, r.Size()));
+ }
+ }
+
+ MoveWindow(CRect(wr.TopLeft(), ws + diff));
+
+ Invalidate();
+}
+
+
+BEGIN_MESSAGE_MAP(CComPropertySheet, CPropertySheet)
+END_MESSAGE_MAP()
+
+
+// CComPropertySheet message handlers
+
+BOOL CComPropertySheet::OnInitDialog()
+{
+ BOOL bResult = (BOOL)Default();//CPropertySheet::OnInitDialog();
+
+ if (!(GetStyle() & WS_CHILD))
+ CenterWindow();
+
+ return bResult;
+}
diff --git a/src/apps/mplayerc/ComPropertySheet.h b/src/apps/mplayerc/ComPropertySheet.h
new file mode 100644
index 000000000..faef4c89f
--- /dev/null
+++ b/src/apps/mplayerc/ComPropertySheet.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "ComPropertyPage.h"
+
+interface IComPropertyPageDirty
+{
+ virtual void OnSetDirty(bool fDirty) = 0;
+};
+
+// CComPropertySheet
+
+class CComPropertySheet : public CPropertySheet, public IComPropertyPageDirty
+{
+ DECLARE_DYNAMIC(CComPropertySheet)
+
+ CComPtr<IPropertyPageSite> m_pSite;
+ CInterfaceList<ISpecifyPropertyPages> m_spp;
+ CAutoPtrList<CComPropertyPage> m_pages;
+ CSize m_size;
+
+public:
+ CComPropertySheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
+ CComPropertySheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
+ virtual ~CComPropertySheet();
+
+ int AddPages(CComPtr<ISpecifyPropertyPages> pSPP);
+ bool AddPage(IPropertyPage* pPage, IUnknown* pUnk);
+
+ void OnActivated(CPropertyPage* pPage);
+
+ // IComPropertyPageDirty
+ void OnSetDirty(bool fDirty) {if(CPropertyPage* p = GetActivePage()) p->SetModified(fDirty);}
+
+ virtual BOOL OnInitDialog();
+
+protected:
+ DECLARE_MESSAGE_MAP()
+};
+
+
diff --git a/src/apps/mplayerc/ConvertChapDlg.cpp b/src/apps/mplayerc/ConvertChapDlg.cpp
new file mode 100644
index 000000000..b77c35bed
--- /dev/null
+++ b/src/apps/mplayerc/ConvertChapDlg.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// ConvertChapDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "ConvertChapDlg.h"
+
+// CConvertChapDlg dialog
+
+CConvertChapDlg::CConvertChapDlg(CWnd* pParent /*=NULL*/)
+ : CResizableDialog(CConvertChapDlg::IDD, pParent)
+ , m_time(_T(""))
+ , m_name(_T(""))
+{
+}
+
+CConvertChapDlg::~CConvertChapDlg()
+{
+}
+
+void CConvertChapDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Text(pDX, IDC_EDIT1, m_time);
+ DDX_Text(pDX, IDC_EDIT2, m_name);
+}
+
+BEGIN_MESSAGE_MAP(CConvertChapDlg, CResizableDialog)
+ ON_UPDATE_COMMAND_UI(IDOK, OnUpdateOK)
+END_MESSAGE_MAP()
+
+
+// CConvertChapDlg message handlers
+
+BOOL CConvertChapDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AddAnchor(IDC_EDIT1, TOP_LEFT);
+ AddAnchor(IDC_EDIT2, TOP_LEFT, TOP_RIGHT);
+ AddAnchor(IDOK, BOTTOM_CENTER);
+ AddAnchor(IDCANCEL, BOTTOM_CENTER);
+
+ CRect r;
+ GetWindowRect(r);
+ CSize s = r.Size();
+ SetMinTrackSize(s);
+ s.cx = 1000;
+ SetMaxTrackSize(s);
+
+ UpdateData(FALSE);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CConvertChapDlg::OnOK()
+{
+ UpdateData();
+
+ __super::OnOK();
+}
+
+void CConvertChapDlg::OnUpdateOK(CCmdUI* pCmdUI)
+{
+ CString str;
+ GetDlgItem(IDC_EDIT1)->GetWindowText(str);
+ int i;
+ pCmdUI->Enable(3 == _stscanf(str, _T("%d:%d:%d"), &i, &i, &i)
+ && GetDlgItem(IDC_EDIT2)->GetWindowTextLength() > 0);
+}
diff --git a/src/apps/mplayerc/ConvertChapDlg.h b/src/apps/mplayerc/ConvertChapDlg.h
new file mode 100644
index 000000000..71c989e89
--- /dev/null
+++ b/src/apps/mplayerc/ConvertChapDlg.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+// CConvertChapDlg dialog
+
+class CConvertChapDlg : public CResizableDialog
+{
+public:
+ CConvertChapDlg(CWnd* pParent = NULL); // standard constructor
+ virtual ~CConvertChapDlg();
+
+// Dialog Data
+ enum { IDD = IDD_CONVERTCHAP_DLG };
+ CString m_time;
+ CString m_name;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+
+ DECLARE_MESSAGE_MAP()
+public:
+ afx_msg void OnUpdateOK(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/ConvertDlg.cpp b/src/apps/mplayerc/ConvertDlg.cpp
new file mode 100644
index 000000000..1867dbfad
--- /dev/null
+++ b/src/apps/mplayerc/ConvertDlg.cpp
@@ -0,0 +1,1366 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// ConvertDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include <mmreg.h>
+#include "mplayerc.h"
+#include "..\..\filters\filters.h"
+#include "..\..\..\include\moreuuids.h"
+#include "FGManager.h"
+#include "ConvertPropsDlg.h"
+#include "ConvertResDlg.h"
+#include "ConvertChapDlg.h"
+#include "ConvertDlg.h"
+
+// TODO: subtitle source filter for vobsub
+
+// CConvertDlg dialog
+
+CConvertDlg::CConvertDlg(CWnd* pParent /*=NULL*/)
+ : CResizableDialog(CConvertDlg::IDD, pParent)
+ , m_fn(_T(""))
+{
+}
+
+CConvertDlg::~CConvertDlg()
+{
+}
+
+void CConvertDlg::AddFile(CString fn)
+{
+ CString protocol;
+
+ int i = fn.Find(_T("://"));
+ if(i > 0)
+ {
+ CString url = fn.Mid(i);
+ CPath path(fn.Left(i));
+ path.StripPath();
+ protocol = (LPCTSTR)path;
+ fn = (LPCTSTR)path + url;
+ }
+
+ CComPtr<IBaseFilter> pBF;
+ if(FAILED(m_pGB->AddSourceFilter(CStringW(fn), CStringW(fn), &pBF)))
+ return;
+
+ int nConnected = 0;
+ BeginEnumPins(pBF, pEP, pPin)
+ if(S_OK == m_pGB->ConnectFilter(pPin, m_pMux)) nConnected++;
+ EndEnumPins
+ if(!nConnected) {MessageBeep(-1); DeleteFilter(pBF); return;}
+
+ if(m_tree.GetCount() == 0)
+ {
+ if(CComQIPtr<IDSMPropertyBag> pPB = m_pMux)
+ pPB->DelAllProperties();
+
+ CString ext(_T(".dsm"));
+
+ if(!protocol.IsEmpty())
+ {
+ m_fn = protocol + ext;
+ }
+ else
+ {
+ CPath p(fn);
+ if(ext.CompareNoCase(p.GetExtension()) == 0)
+ ext = _T(" (remuxed)") + ext;
+ p.RemoveExtension();
+ m_fn = (LPCTSTR)p + ext;
+ }
+
+ UpdateData(FALSE);
+ }
+
+ CTreeItemFile* t = new CTreeItemFile(fn, pBF, m_tree, NULL);
+
+ AddFilter(*t, pBF);
+
+ m_tree.Expand(*t, TVE_EXPAND);
+ m_tree.EnsureVisible(*t);
+}
+
+bool CConvertDlg::ConvertFile(LPCTSTR fn, IPin* pPin)
+{
+ OAFilterState fs;
+ if(!m_pMC || FAILED(m_pMC->GetState(0, &fs)) || fs != State_Stopped)
+ return false;
+
+ m_pGB->NukeDownstream(m_pMux);
+
+ CComPtr<IBaseFilter> pFW;
+ pFW.CoCreateInstance(CLSID_FileWriter);
+ CComQIPtr<IFileSinkFilter2> pFSF = pFW;
+
+ if(pPin)
+ {
+ CComQIPtr<IBaseMuxerRelatedPin> pRP = pPin;
+ if(!pRP) return false;
+
+ pPin = pRP->GetRelatedPin();
+ }
+ else
+ {
+ pPin = GetFirstPin(m_pMux, PINDIR_OUTPUT);
+ }
+
+ if(!pPin || !pFSF
+ || FAILED(m_pGB->AddFilter(pFW, NULL))
+ || FAILED(pFSF->SetFileName(CStringW(fn), NULL))
+ || FAILED(pFSF->SetMode(AM_FILE_OVERWRITE))
+ || FAILED(m_pGB->ConnectDirect(pPin, GetFirstPin(pFW), NULL)))
+ {
+ m_pGB->RemoveFilter(pFW);
+ return false;
+ }
+
+ if(m_pMS)
+ {
+ LONGLONG pos = 0;
+ m_pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
+ }
+
+ if(CComQIPtr<IDSMPropertyBag> pPB = m_pMux)
+ {
+ pPB->SetProperty(L"APPL", L"Media Player Classic");
+ }
+
+ if(CComQIPtr<IDSMResourceBag> pRB = m_pMux)
+ {
+ pRB->ResRemoveAll(0);
+ POSITION pos = m_pTIs.GetHeadPosition();
+ while(pos)
+ {
+ if(CTreeItemResource* t2 = dynamic_cast<CTreeItemResource*>((CTreeItem*)m_pTIs.GetNext(pos)))
+ pRB->ResAppend(
+ t2->m_res.name, t2->m_res.desc, t2->m_res.mime,
+ t2->m_res.data.GetData(), t2->m_res.data.GetCount(),
+ NULL);
+ }
+ }
+
+ if(CComQIPtr<IDSMChapterBag> pCB = m_pMux)
+ {
+ pCB->ChapRemoveAll();
+ POSITION pos = m_pTIs.GetHeadPosition();
+ while(pos)
+ {
+ if(CTreeItemChapter* t2 = dynamic_cast<CTreeItemChapter*>((CTreeItem*)m_pTIs.GetNext(pos)))
+ pCB->ChapAppend(t2->m_chap.rt, t2->m_chap.name);
+ }
+ }
+
+ if(FAILED(m_pMC->Run()))
+ return false;
+
+ m_tree.EnableWindow(FALSE);
+
+ return true;
+}
+
+void CConvertDlg::AddFilter(HTREEITEM hTIParent, IBaseFilter* pBFParent)
+{
+ BeginEnumPins(pBFParent, pEP, pPin)
+ {
+ CComPtr<IPin> pPinTo;
+ CComPtr<IBaseFilter> pBF;
+ if(S_OK != m_pGB->IsPinDirection(pPin, PINDIR_OUTPUT)
+ || FAILED(pPin->ConnectedTo(&pPinTo)) || !pPinTo
+ || !(pBF = GetFilterFromPin(pPinTo)))
+ continue;
+
+ CTreeItem* t = NULL;
+
+ if(pBF == m_pMux)
+ {
+ t = new CTreeItemPin(pPin, m_tree, hTIParent);
+ }
+ else
+ {
+ t = new CTreeItemFilter(pBF, m_tree, hTIParent);
+ AddFilter(*t, pBF);
+ }
+ }
+ EndEnumPins
+
+ if(CComQIPtr<IDSMPropertyBag> pPB = pBFParent)
+ {
+ ULONG props;
+ if(FAILED(pPB->CountProperties(&props)))
+ props = 0;
+
+ for(ULONG i = 0; i < props; i++)
+ {
+ PROPBAG2 PropBag;
+ memset(&PropBag, 0, sizeof(PropBag));
+ ULONG cPropertiesReturned = 0;
+ if(FAILED(pPB->GetPropertyInfo(i, 1, &PropBag, &cPropertiesReturned)))
+ continue;
+
+ HRESULT hr;
+ CComVariant var;
+ if(SUCCEEDED(pPB->Read(1, &PropBag, NULL, &var, &hr)) && SUCCEEDED(hr))
+ {
+ CComQIPtr<IDSMPropertyBag> pPBMux = m_pMux;
+ CComBSTR value;
+ if(pPBMux && FAILED(pPBMux->GetProperty(PropBag.pstrName, &value)))
+ pPBMux->SetProperty(PropBag.pstrName, var.bstrVal);
+ }
+
+ CoTaskMemFree(PropBag.pstrName);
+ }
+ }
+
+ CTreeItem* t2 = new CTreeItemResourceFolder(m_tree, hTIParent);
+ if(CComQIPtr<IDSMResourceBag> pRB = pBFParent)
+ {
+ for(DWORD i = 0, cnt = pRB->ResGetCount(); i < cnt; i++)
+ {
+ CComBSTR name, mime, desc;
+ BYTE* pData = NULL;
+ DWORD len = 0;
+ if(FAILED(pRB->ResGet(i, &name, &desc, &mime, &pData, &len, NULL)))
+ continue;
+
+ if(len > 0)
+ {
+ m_pTIs.AddTail(new CTreeItemResource(CDSMResource(name, desc, mime, pData, len), m_tree, *t2));
+ }
+
+ CoTaskMemFree(pData);
+ }
+ }
+ m_tree.Expand(*t2, TVE_EXPAND);
+
+ CTreeItem* t3 = new CTreeItemChapterFolder(m_tree, hTIParent);
+ if(CComQIPtr<IDSMChapterBag> pCB = pBFParent)
+ {
+ for(DWORD i = 0, cnt = pCB->ChapGetCount(); i < cnt; i++)
+ {
+ REFERENCE_TIME rt;
+ CComBSTR name;
+ if(FAILED(pCB->ChapGet(i, &rt, &name)))
+ continue;
+
+ m_pTIs.AddTail(new CTreeItemChapter(CDSMChapter(rt, name), m_tree, *t3));
+ }
+ }
+ m_tree.Expand(*t3, TVE_EXPAND);
+
+ m_tree.Expand(hTIParent, TVE_EXPAND);
+}
+
+void CConvertDlg::DeleteFilter(IBaseFilter* pBF)
+{
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ CComPtr<IPin> pPinTo;
+ CComPtr<IBaseFilter> pBF;
+ if(S_OK != m_pGB->IsPinDirection(pPin, PINDIR_OUTPUT)
+ || FAILED(pPin->ConnectedTo(&pPinTo)) || !pPinTo
+ || !(pBF = GetFilterFromPin(pPinTo)))
+ continue;
+
+ if(pBF != m_pMux) DeleteFilter(pBF);
+ }
+ EndEnumPins
+
+ m_pGB->RemoveFilter(pBF);
+}
+
+void CConvertDlg::DeleteItem(HTREEITEM hTI)
+{
+ if(!hTI) return;
+
+ DeleteChildren(hTI);
+
+ CTreeItem* t = (CTreeItem*)m_tree.GetItemData(hTI);
+ if(POSITION pos = m_pTIs.Find(t)) m_pTIs.RemoveAt(pos);
+ delete t;
+ m_tree.DeleteItem(hTI);
+}
+
+void CConvertDlg::DeleteChildren(HTREEITEM hTI)
+{
+ if(!hTI) return;
+
+ if(m_tree.ItemHasChildren(hTI))
+ {
+ HTREEITEM hChildItem = m_tree.GetChildItem(hTI);
+
+ while(hChildItem != NULL)
+ {
+ HTREEITEM hNextItem = m_tree.GetNextItem(hChildItem, TVGN_NEXT);
+ DeleteItem(hChildItem);
+ hChildItem = hNextItem;
+ }
+ }
+}
+
+HTREEITEM CConvertDlg::HitTest(CPoint& sp, CPoint& cp)
+{
+ sp = CPoint((LPARAM)GetMessagePos());
+ cp = sp;
+ m_tree.ScreenToClient(&cp);
+ UINT flags = 0;
+ HTREEITEM hTI = m_tree.HitTest(cp, &flags);
+ return hTI && (flags&TVHT_ONITEM) ? hTI : NULL;
+}
+
+void CConvertDlg::ShowPopup(CPoint p)
+{
+ CMenu m;
+ m.CreatePopupMenu();
+
+ int i = 1;
+ m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_ADDFILE));
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_PROPERTIES));
+
+ switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
+ {
+ case 1:
+ {
+ CFileDialog fd(TRUE, NULL, m_fn,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_NOVALIDATE,
+ _T("Media files|*.*||"), this, 0);
+ if(fd.DoModal() == IDOK) AddFile(fd.GetPathName());
+ }
+ break;
+ case 2:
+ EditProperties(CComQIPtr<IDSMPropertyBag>(m_pMux));
+ break;
+ }
+}
+
+void CConvertDlg::ShowFilePopup(HTREEITEM hTI, CPoint p)
+{
+ CTreeItemFile* t = dynamic_cast<CTreeItemFile*>((CTreeItem*)m_tree.GetItemData(hTI));
+ ASSERT(t);
+
+ CMenu m;
+ m.CreatePopupMenu();
+
+ int i = 1;
+ m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_REMOVE));
+
+ switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
+ {
+ case 1:
+ DeleteFilter(t->m_pBF);
+ DeleteItem(hTI);
+ break;
+ }
+}
+
+void CConvertDlg::ShowPinPopup(HTREEITEM hTI, CPoint p)
+{
+ CTreeItemPin* t = dynamic_cast<CTreeItemPin*>((CTreeItem*)m_tree.GetItemData(hTI));
+ ASSERT(t);
+
+ if(!t->m_pPin) return;
+
+ CComPtr<IPin> pPinTo;
+ t->m_pPin->ConnectedTo(&pPinTo);
+
+ CMediaType mt;
+ if(pPinTo) t->m_pPin->ConnectionMediaType(&mt);
+
+ CAtlArray<CMediaType> mts;
+ BeginEnumMediaTypes(t->m_pPin, pEMT, pmt)
+ mts.Add(*pmt);
+ EndEnumMediaTypes(pmt)
+
+ CMenu m;
+ m.CreatePopupMenu();
+
+ int i = 1, mtbase = 1000, mti = mtbase;
+
+ m.AppendMenu(MF_STRING, i++, !pPinTo ? ResStr(IDS_CONVERT_ENABLESTREAM) : ResStr(IDS_CONVERT_DISABLESTREAM));
+ m.AppendMenu(MF_STRING | (!pPinTo ? MF_GRAYED : 0), i++, ResStr(IDS_CONVERT_DEMUXSTREAM));
+
+ if(mts.GetCount() > 1)
+ {
+ m.AppendMenu(MF_SEPARATOR);
+ for(int i = 0; i < mts.GetCount(); i++)
+ m.AppendMenu(MF_STRING | (mts[i] == mt ? MF_CHECKED : 0), mti++, CMediaTypeEx(mts[i]).ToString());
+ }
+
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING | (!pPinTo ? MF_GRAYED : 0), i++, ResStr(IDS_CONVERT_PINPROPERTIES));
+
+ switch(i = (int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
+ {
+ case 1:
+ if(pPinTo) {m_pGB->Disconnect(pPinTo); m_pGB->Disconnect(t->m_pPin);}
+ else if(pPinTo = GetFirstDisconnectedPin(m_pMux, PINDIR_INPUT)) m_pGB->ConnectDirect(t->m_pPin, pPinTo, NULL);
+ t->Update();
+ break;
+ case 2:
+ {
+ UpdateData();
+
+ CString ext = _T("raw");
+
+ if(mt.subtype == MEDIASUBTYPE_AAC) ext = _T("aac");
+ else if(mt.subtype == MEDIASUBTYPE_MP3) ext = _T("mp3");
+ else if(mt.subtype == FOURCCMap(WAVE_FORMAT_MPEG)) ext = _T("m1a");
+ else if(mt.subtype == MEDIASUBTYPE_MPEG2_AUDIO) ext = _T("m2a");
+ else if(mt.subtype == MEDIASUBTYPE_WAVE_DOLBY_AC3 || mt.subtype == MEDIASUBTYPE_DOLBY_AC3) ext = _T("ac3");
+ else if(mt.subtype == MEDIASUBTYPE_WAVE_DTS || mt.subtype == MEDIASUBTYPE_DTS) ext = _T("dts");
+ else if((mt.subtype == FOURCCMap('1CVA') || mt.subtype == FOURCCMap('1cva')) && mt.formattype == FORMAT_MPEG2_VIDEO) ext = _T("h264");
+ else if(mt.subtype == FOURCCMap('GEPJ') || mt.subtype == FOURCCMap('gepj')) ext = _T("jpg");
+ else if(mt.majortype == MEDIATYPE_Video && mt.subtype == MEDIASUBTYPE_MPEG2_VIDEO) ext = _T("m2v");
+ else if(mt.majortype == MEDIATYPE_Video && mt.subtype == MEDIASUBTYPE_MPEG1Payload) ext = _T("m1v");
+ else if(mt.subtype == MEDIASUBTYPE_UTF8 || mt.majortype == MEDIATYPE_Text) ext = _T("srt");
+ else if(mt.subtype == MEDIASUBTYPE_SSA) ext = _T("ssa");
+ else if(mt.subtype == MEDIASUBTYPE_ASS || mt.subtype == MEDIASUBTYPE_ASS2) ext = _T("ass");
+// else if(mt.subtype == MEDIASUBTYPE_SSF) ext = _T("ssf");
+ else if(mt.subtype == MEDIASUBTYPE_VOBSUB) ext = _T("sub");
+ else if(mt.subtype == MEDIASUBTYPE_PCM || mt.subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO || mt.subtype == FOURCCMap(WAVE_FORMAT_EXTENSIBLE) || mt.subtype == FOURCCMap(WAVE_FORMAT_IEEE_FLOAT)) ext = _T("wav");
+ // TODO: else if...
+
+ CPath path(m_fn);
+ path.RenameExtension('.' + ext);
+
+ CFileDialog fd(FALSE, NULL, (LPCTSTR)path,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY,
+ _T("Media files|*.*||"), this, 0);
+ if(fd.DoModal() == IDOK)
+ {
+ if(!ConvertFile(fd.GetPathName(), pPinTo))
+ {
+ AfxMessageBox(_T("Failed to start conversion"));
+ }
+ }
+ }
+ break;
+ case 3:
+ EditProperties(CComQIPtr<IDSMPropertyBag>(pPinTo));
+ break;
+ default:
+ i -= mtbase;
+ if(i >= 0 && i < mts.GetCount())
+ {
+ if(pPinTo) {m_pGB->Disconnect(pPinTo); m_pGB->Disconnect(t->m_pPin);}
+ else {pPinTo = GetFirstDisconnectedPin(m_pMux, PINDIR_INPUT);}
+ HRESULT hr = m_pGB->ConnectDirect(t->m_pPin, pPinTo, &mts[i]);
+ if(FAILED(hr))
+ {
+ AfxMessageBox(_T("Reconnection attempt failed!"));
+ if(mt.majortype != GUID_NULL)
+ hr = m_pGB->ConnectDirect(t->m_pPin, pPinTo, &mt);
+ }
+ t->Update();
+ }
+ break;
+ }
+}
+
+void CConvertDlg::ShowResourceFolderPopup(HTREEITEM hTI, CPoint p)
+{
+ CTreeItemResourceFolder* t = dynamic_cast<CTreeItemResourceFolder*>((CTreeItem*)m_tree.GetItemData(hTI));
+ ASSERT(t);
+
+ CMenu m;
+ m.CreatePopupMenu();
+
+ int i = 1;
+ m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_ADDRESOURCE));
+ if(m_tree.ItemHasChildren(*t))
+ {
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_REMOVEALL));
+ }
+
+ switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
+ {
+ case 1:
+ {
+ CFileDialog fd(TRUE, NULL, NULL,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY,
+ _T("All files|*.*||"), this, 0);
+ if(fd.DoModal() == IDOK)
+ {
+ CString fn = fd.GetPathName();
+ if(FILE* f = _tfopen(fn, _T("rb")))
+ {
+ CDSMResource res;
+
+ CPath path(fn);
+ path.StripPath();
+ res.name = (LPCTSTR)path;
+
+ CRegKey key;
+ TCHAR mime[256];
+ ULONG len = countof(mime);
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, path.GetExtension().MakeLower(), KEY_READ)
+ && ERROR_SUCCESS == key.QueryStringValue(_T("Content Type"), mime, &len))
+ res.mime = mime;
+
+ CTreeItemResource* t = new CTreeItemResource(res, m_tree, hTI);
+ m_pTIs.AddTail(t);
+
+ if(EditResource(t))
+ {
+ fseek(f, 0, 2);
+ long size = ftell(f);
+ fseek(f, 0, 0);
+ t->m_res.data.SetCount(size);
+ for(BYTE* ptr = t->m_res.data.GetData(),* end = ptr + size;
+ size > 0 && end - ptr >= size && fread(ptr, min(size, 1024), 1, f) > 0;
+ ptr += 1024, size -= 1024);
+ fclose(f);
+ }
+ else
+ {
+ DeleteItem(*t);
+ }
+ }
+ else
+ {
+ AfxMessageBox(_T("Cannot open file!"));
+ }
+ }
+ }
+ break;
+ case 2:
+ DeleteChildren(hTI);
+ break;
+ }
+}
+
+void CConvertDlg::ShowResourcePopup(HTREEITEM hTI, CPoint p)
+{
+ CTreeItemResource* t = dynamic_cast<CTreeItemResource*>((CTreeItem*)m_tree.GetItemData(hTI));
+ ASSERT(t);
+
+ CMenu m;
+ m.CreatePopupMenu();
+
+ int i = 1;
+ m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_REMOVE));
+ m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_SAVEAS));
+ if(AfxGetAppSettings().fEnableWebServer) m.AppendMenu(MF_STRING, 1000, ResStr(IDS_CONVERT_LAUNCHINBROWSER));
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_RESOURCEPROPERTIES));
+
+ switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
+ {
+ case 1:
+ DeleteItem(*t);
+ break;
+ case 2:
+ {
+ CFileDialog fd(FALSE, NULL, CString(t->m_res.name),
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
+ _T("All files|*.*||"), this, 0);
+ if(fd.DoModal() == IDOK)
+ {
+ if(FILE* f = _tfopen(fd.GetPathName(), _T("wb")))
+ {
+ fwrite(t->m_res.data.GetData(), 1, t->m_res.data.GetCount(), f);
+ fclose(f);
+ }
+ }
+ }
+ break;
+ case 3:
+ EditResource(t);
+ break;
+ case 1000:
+ {
+ CString url;
+ url.Format(_T("http://localhost:%d/convres.html?id=%x"), AfxGetAppSettings().nWebServerPort, (DWORD)&t->m_res);
+ ShellExecute(NULL, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT);
+ }
+ break;
+ }
+}
+
+bool CConvertDlg::EditProperties(IDSMPropertyBag* pPB)
+{
+ CConvertPropsDlg dlg(!!CComQIPtr<IPin>(pPB), this);
+
+ ULONG props;
+ if(FAILED(pPB->CountProperties(&props)))
+ props = 0;
+
+ for(ULONG i = 0; i < props; i++)
+ {
+ PROPBAG2 PropBag;
+ memset(&PropBag, 0, sizeof(PropBag));
+ ULONG cPropertiesReturned = 0;
+ if(FAILED(pPB->GetPropertyInfo(i, 1, &PropBag, &cPropertiesReturned)))
+ continue;
+
+ HRESULT hr;
+ CComVariant var;
+ if(SUCCEEDED(pPB->Read(1, &PropBag, NULL, &var, &hr)) && SUCCEEDED(hr))
+ dlg.m_props[CString(PropBag.pstrName)] = CString(var);
+
+ CoTaskMemFree(PropBag.pstrName);
+ }
+
+ if(IDOK != dlg.DoModal())
+ return false;
+
+ pPB->DelAllProperties();
+
+ POSITION pos = dlg.m_props.GetStartPosition();
+ while(pos)
+ {
+ CString key, value;
+ dlg.m_props.GetNextAssoc(pos, key, value);
+ pPB->SetProperty(CStringW(key), CStringW(value));
+ }
+
+ return true;
+}
+
+bool CConvertDlg::EditResource(CTreeItemResource* t)
+{
+ CConvertResDlg dlg(this);
+
+ dlg.m_name = t->m_res.name;
+ dlg.m_mime = t->m_res.mime;
+ dlg.m_desc = t->m_res.desc;
+
+ if(IDOK != dlg.DoModal())
+ return false;
+
+ t->m_res.name = dlg.m_name;
+ t->m_res.mime = dlg.m_mime;
+ t->m_res.desc = dlg.m_desc;
+
+ t->Update();
+
+ return true;
+}
+
+void CConvertDlg::ShowChapterFolderPopup(HTREEITEM hTI, CPoint p)
+{
+ CTreeItemChapterFolder* t = dynamic_cast<CTreeItemChapterFolder*>((CTreeItem*)m_tree.GetItemData(hTI));
+ ASSERT(t);
+
+ CMenu m;
+ m.CreatePopupMenu();
+
+ int i = 1;
+ m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_ADDCHAPTER));
+ if(m_tree.ItemHasChildren(*t))
+ {
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_REMOVEALL));
+ }
+
+ switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
+ {
+ case 1:
+ {
+ CDSMChapter chap;
+ CTreeItemChapter* t = new CTreeItemChapter(CDSMChapter(0, L""), m_tree, hTI);
+ m_pTIs.AddTail(t);
+ if(!EditChapter(t))
+ DeleteItem(*t);
+ }
+ break;
+ case 2:
+ DeleteChildren(hTI);
+ break;
+ }
+}
+
+void CConvertDlg::ShowChapterPopup(HTREEITEM hTI, CPoint p)
+{
+ CTreeItemChapter* t = dynamic_cast<CTreeItemChapter*>((CTreeItem*)m_tree.GetItemData(hTI));
+ ASSERT(t);
+
+ CMenu m;
+ m.CreatePopupMenu();
+
+ int i = 1;
+ m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_REMOVE));
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_CHAPTERPROPERTIES));
+
+ switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
+ {
+ case 1:
+ DeleteItem(hTI);
+ break;
+ case 2:
+ EditChapter(t);
+ break;
+ }
+}
+
+bool CConvertDlg::EditChapter(CTreeItemChapter* t)
+{
+ CConvertChapDlg dlg(this);
+
+ int h = (int)(t->m_chap.rt/10000000/60/60);
+ int m = (int)(t->m_chap.rt/10000000/60%60);
+ int s = (int)(t->m_chap.rt/10000000%60);
+ int ms = (int)(t->m_chap.rt/10000%1000);
+
+ dlg.m_name = t->m_chap.name;
+ dlg.m_time.Format(_T("%02d:%02d:%02d.%03d"), h, m, s, ms);
+
+ if(IDOK != dlg.DoModal())
+ return false;
+
+ TCHAR c;
+ if(_stscanf(dlg.m_time, _T("%d%c%d%c%d%c%d"), &h, &c, &m, &c, &s, &c, &ms) != 7)
+ return false;
+
+ t->m_chap.name = dlg.m_name;
+ t->m_chap.rt = ((((__int64)h*60+m)*60+s)*1000+ms)*10000;
+
+ t->Update();
+
+ return true;
+}
+
+void CConvertDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_TREE1, m_tree);
+ DDX_Text(pDX, IDC_EDIT1, m_fn);
+}
+
+BOOL CConvertDlg::PreTranslateMessage(MSG* pMsg)
+{
+ if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
+ return TRUE;
+
+ return __super::PreTranslateMessage(pMsg);
+}
+
+BOOL CConvertDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), TRUE);
+ SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), FALSE);
+
+ AddAnchor(IDC_TREE1, TOP_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_EDIT1, BOTTOM_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_BUTTON1, BOTTOM_RIGHT);
+ AddAnchor(IDC_HLINE, BOTTOM_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_BUTTON2, BOTTOM_CENTER);
+ AddAnchor(IDC_BUTTON3, BOTTOM_CENTER);
+ AddAnchor(IDC_BUTTON4, BOTTOM_CENTER);
+
+ CSize s(400, 200);
+ SetMinTrackSize(s);
+
+ m_streamtypesbm.LoadBitmap(IDB_STREAMTYPES);
+ m_streamtypes.Create(16, 18, ILC_MASK|ILC_COLOR32, 0, 4);
+ m_streamtypes.Add(&m_streamtypesbm, 0xffffff);
+ m_tree.SetImageList(&m_streamtypes, TVSIL_NORMAL);
+
+ GetWindowText(m_title);
+ m_nIDEventStatus = SetTimer(1, 1000, NULL);
+
+ HRESULT hr;
+ m_pMux = new CDSMMuxerFilter(NULL, &hr, false, false);
+
+ m_pGB = new CFGManagerMuxer(_T("CFGManagerMuxer"), NULL);
+ m_pGB->AddToROT();
+
+ if(FAILED(m_pGB->AddFilter(m_pMux, L"Mux"))
+ || !(m_pMC = m_pGB) || !(m_pME = m_pGB) || !(m_pMS = m_pMux)
+ || FAILED(m_pME->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0)))
+ {
+ MessageBeep(-1);
+ SendMessage(WM_CLOSE);
+ return TRUE;
+ }
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CConvertDlg::OnOK()
+{
+}
+
+BEGIN_MESSAGE_MAP(CConvertDlg, CResizableDialog)
+ ON_MESSAGE(WM_GRAPHNOTIFY, OnGraphNotify)
+ ON_WM_DROPFILES()
+ ON_WM_CLOSE()
+ ON_NOTIFY(NM_CLICK, IDC_TREE1, OnNMClickTree1)
+ ON_NOTIFY(NM_RCLICK, IDC_TREE1, OnNMRclickTree1)
+ ON_NOTIFY(NM_DBLCLK, IDC_TREE1, OnNMDblclkTree1)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateButton1)
+ ON_WM_TIMER()
+ ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateButton2)
+ ON_BN_CLICKED(IDC_BUTTON3, OnBnClickedButton3)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON3, OnUpdateButton3)
+ ON_BN_CLICKED(IDC_BUTTON4, OnBnClickedButton4)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON4, OnUpdateButton4)
+END_MESSAGE_MAP()
+
+// CConvertDlg message handlers
+
+LRESULT CConvertDlg::OnGraphNotify(WPARAM wParam, LPARAM lParam)
+{
+ HRESULT hr = S_OK;
+
+ LONG evCode, evParam1, evParam2;
+ while(m_pME && SUCCEEDED(m_pME->GetEvent(&evCode, (LONG_PTR*)&evParam1, (LONG_PTR*)&evParam2, 0)))
+ {
+ hr = m_pME->FreeEventParams(evCode, evParam1, evParam2);
+
+ bool fStop = false;
+
+ if(EC_COMPLETE == evCode)
+ {
+ fStop = true;
+ }
+ else if(EC_ERRORABORT == evCode)
+ {
+ fStop = true;
+
+ CString errmsg;
+ LPVOID lpMsgBuf;
+ if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL))
+ {
+ errmsg = (LPCTSTR)lpMsgBuf;
+ LocalFree(lpMsgBuf);
+ }
+
+ CString str;
+ str.Format(_T("Could not complete conversion, the output file is most likely unusable.\n\nError code: 0x%08x"), evParam1);
+ if(!errmsg.IsEmpty()) str += _T(" (") + errmsg + _T(")");
+ AfxMessageBox(str, MB_OK);
+ }
+
+ if(fStop && m_pMC)
+ {
+ m_pMC->Stop();
+ m_tree.EnableWindow(TRUE);
+ }
+ }
+
+ return hr;
+}
+
+void CConvertDlg::OnDropFiles(HDROP hDropInfo)
+{
+ for(int i = 0, j = DragQueryFile(hDropInfo, 0xffffffff, 0, 0); i < j; i++)
+ {
+ CString fn;
+ fn.ReleaseBufferSetLength(DragQueryFile(hDropInfo, i, fn.GetBuffer(MAX_PATH), MAX_PATH));
+
+ AddFile(fn);
+ }
+
+ __super::OnDropFiles(hDropInfo);
+}
+
+void CConvertDlg::OnClose()
+{
+ HTREEITEM hTI = m_tree.GetRootItem();
+ while(hTI)
+ {
+ HTREEITEM hTINext = m_tree.GetNextSiblingItem(hTI);
+ DeleteItem(hTI);
+ hTI = hTINext;
+ }
+
+ m_pGB->RemoveFromROT();
+ m_pGB = NULL;
+
+ __super::OnClose();
+}
+
+void CConvertDlg::OnNMClickTree1(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ CPoint sp, cp;
+ HTREEITEM hTI = HitTest(sp, cp);
+ if(!hTI) return;
+ m_tree.SelectItem(hTI);
+
+ *pResult = 0;
+}
+
+void CConvertDlg::OnNMRclickTree1(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ CPoint sp, cp;
+ HTREEITEM hTI = HitTest(sp, cp);
+
+ if(hTI)
+ {
+ m_tree.SelectItem(hTI);
+
+ CTreeItem* t = (CTreeItem*)m_tree.GetItemData(hTI);
+
+ if(dynamic_cast<CTreeItemPin*>(t))
+ ShowPinPopup(hTI, sp);
+ else if(dynamic_cast<CTreeItemFile*>(t))
+ ShowFilePopup(hTI, sp);
+ else if(dynamic_cast<CTreeItemResourceFolder*>(t))
+ ShowResourceFolderPopup(hTI, sp);
+ else if(dynamic_cast<CTreeItemResource*>(t))
+ ShowResourcePopup(hTI, sp);
+ else if(dynamic_cast<CTreeItemChapterFolder*>(t))
+ ShowChapterFolderPopup(hTI, sp);
+ else if(dynamic_cast<CTreeItemChapter*>(t))
+ ShowChapterPopup(hTI, sp);
+ }
+ else
+ {
+ ShowPopup(sp);
+ }
+
+ *pResult = 0;
+}
+
+void CConvertDlg::OnNMDblclkTree1(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ CPoint sp, cp;
+ HTREEITEM hTI = HitTest(sp, cp);
+
+ if(hTI)
+ {
+ CTreeItem* t = (CTreeItem*)m_tree.GetItemData(hTI);
+
+ if(CTreeItemPin* t2 = dynamic_cast<CTreeItemPin*>(t))
+ {
+ CComPtr<IPin> pPinTo;
+ t2->m_pPin->ConnectedTo(&pPinTo);
+
+ if(CComQIPtr<IDSMPropertyBag> pPB = pPinTo)
+ EditProperties(pPB);
+ }
+ else if(CTreeItemResource* t2 = dynamic_cast<CTreeItemResource*>(t))
+ {
+ EditResource(t2);
+ }
+ else if(CTreeItemChapter* t2 = dynamic_cast<CTreeItemChapter*>(t))
+ {
+ EditChapter(t2);
+ }
+ }
+
+ *pResult = 0;
+}
+
+void CConvertDlg::OnBnClickedButton1()
+{
+ UpdateData();
+
+ CFileDialog fd(FALSE, _T(".dsm"), m_fn,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
+ _T("DirectShow Media file|*.dsm|All files|*.*|"), this, 0);
+
+ if(fd.DoModal() == IDOK)
+ {
+ m_fn = fd.GetPathName();
+ UpdateData(FALSE);
+ }
+}
+
+void CConvertDlg::OnUpdateButton1(CCmdUI* pCmdUI)
+{
+ OAFilterState fs;
+ pCmdUI->Enable(m_pMC && SUCCEEDED(m_pMC->GetState(0, &fs)) && fs == State_Stopped);
+}
+
+void CConvertDlg::OnTimer(UINT nIDEvent)
+{
+ if(nIDEvent == m_nIDEventStatus && m_pMS && m_pMC)
+ {
+ OAFilterState fs;
+ if(SUCCEEDED(m_pMC->GetState(0, &fs)) && fs != State_Stopped)
+ {
+ GUID tf;
+ m_pMS->GetTimeFormat(&tf);
+
+ REFERENCE_TIME rtCur, rtDur;
+ HRESULT hr = m_pMS->GetDuration(&rtDur);
+ m_pMS->GetCurrentPosition(&rtCur);
+
+ CString str;
+ if(hr == S_OK && rtDur != 0) str.Format(_T("%.2f%%"), 1.0 * (rtCur * 100) / rtDur);
+ else if(hr == S_OK && rtDur == 0) str = _T("Live");
+ else if(tf == TIME_FORMAT_BYTE) str.Format(_T("%.2fKB"), 1.0 * rtCur / 1024);
+ else if(tf == TIME_FORMAT_MEDIA_TIME) str.Format(_T("%02d:%02d:%02d"), int(rtCur/3600000000)%60, int(rtCur/60000000)%60, int(rtCur/1000000)%60);
+ else str = _T("Please Wait");
+
+ SetWindowText(_T("Converting - ") + str);
+ }
+ else
+ {
+ SetWindowText(m_title);
+ }
+ }
+
+ __super::OnTimer(nIDEvent);
+}
+
+void CConvertDlg::OnBnClickedButton2()
+{
+ OAFilterState fs;
+ if(FAILED(m_pMC->GetState(0, &fs)))
+ return;
+
+ if(fs != State_Stopped)
+ {
+ m_pMC->Run();
+ return;
+ }
+
+ UpdateData();
+
+ if(!ConvertFile(m_fn))
+ {
+ AfxMessageBox(_T("Failed to start conversion"));
+ }
+}
+
+void CConvertDlg::OnUpdateButton2(CCmdUI* pCmdUI)
+{
+ int nIn, nOut, nInC, nOutC;
+ CountPins(m_pMux, nIn, nOut, nInC, nOutC);
+
+ OAFilterState fs;
+ pCmdUI->Enable(nInC > 0 && GetDlgItem(IDC_EDIT1)->GetWindowTextLength() > 0
+ && m_pMS && m_pMC && SUCCEEDED(m_pMC->GetState(0, &fs)) && fs != State_Running);
+}
+
+void CConvertDlg::OnBnClickedButton3()
+{
+ if(m_pMC) m_pMC->Pause();
+}
+
+void CConvertDlg::OnUpdateButton3(CCmdUI* pCmdUI)
+{
+ OAFilterState fs;
+ pCmdUI->Enable(m_pMC && SUCCEEDED(m_pMC->GetState(0, &fs)) && fs == State_Running);
+}
+
+void CConvertDlg::OnBnClickedButton4()
+{
+ if(m_pMC) m_pMC->Stop();
+ m_tree.EnableWindow(TRUE);
+}
+
+void CConvertDlg::OnUpdateButton4(CCmdUI* pCmdUI)
+{
+ OAFilterState fs;
+ pCmdUI->Enable(m_pMC && SUCCEEDED(m_pMC->GetState(0, &fs)) && fs != State_Stopped);
+}
+
+//
+// CFilterTreeCtrl
+//
+
+CFilterTreeCtrl::CFilterTreeCtrl()
+{
+}
+
+void CFilterTreeCtrl::PreSubclassWindow()
+{
+ EnableToolTips(TRUE);
+
+ __super::PreSubclassWindow();
+}
+
+INT_PTR CFilterTreeCtrl::OnToolHitTest(CPoint p, TOOLINFO* pTI) const
+{
+ UINT nFlags;
+ HTREEITEM hTI = HitTest(p, &nFlags);
+ if(nFlags & TVHT_ONITEM)
+ {
+ CRect r;
+ GetItemRect(hTI, r, TRUE);
+ pTI->hwnd = m_hWnd;
+ pTI->uId = (UINT)hTI;
+ pTI->lpszText = LPSTR_TEXTCALLBACK;
+ pTI->rect = r;
+ return pTI->uId;
+ }
+
+ return -1;
+}
+
+BEGIN_MESSAGE_MAP(CFilterTreeCtrl, CTreeCtrl)
+ ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
+ ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
+END_MESSAGE_MAP()
+
+BOOL CFilterTreeCtrl::OnToolTipText(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
+{
+ TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
+ TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
+
+ UINT nID = pNMHDR->idFrom;
+
+ if(nID == (UINT)m_hWnd
+ && (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND)
+ || pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND)))
+ return FALSE;
+
+ ::SendMessage(pNMHDR->hwndFrom, TTM_SETMAXTIPWIDTH, 0, (LPARAM)(INT)1000);
+
+ HTREEITEM hTI = (HTREEITEM)nID;
+
+ CString str;
+ static CStringA m_strTipTextA;
+ static CStringW m_strTipTextW;
+
+ CConvertDlg::CTreeItem* t = (CConvertDlg::CTreeItem*)GetItemData(hTI);
+ if(!t || !t->ToolTip(str)) return FALSE;
+
+ m_strTipTextA = str;
+ m_strTipTextW = str;
+
+ if(pNMHDR->code == TTN_NEEDTEXTA) pTTTA->lpszText = (LPSTR)(LPCSTR)m_strTipTextA;
+ else pTTTW->lpszText = (LPWSTR)(LPCWSTR)m_strTipTextW;
+
+ *pResult = 0;
+
+ return TRUE; // message was handled
+}
+
+//
+// CConvertDlg::CTreeItem*
+//
+
+CConvertDlg::CTreeItem::CTreeItem(CTreeCtrl& tree, HTREEITEM hTIParent)
+ : m_tree(tree)
+{
+ m_hTI = m_tree.InsertItem(_T(""), hTIParent);
+ m_tree.SetItemData(m_hTI, (DWORD_PTR)this);
+ Update();
+}
+
+CConvertDlg::CTreeItem::~CTreeItem()
+{
+}
+
+void CConvertDlg::CTreeItem::SetLabel(LPCTSTR label)
+{
+ m_tree.SetItemText(m_hTI, label);
+}
+
+void CConvertDlg::CTreeItem::SetImage(int nImage, int nSelectedImage)
+{
+ m_tree.SetItemImage(m_hTI, nImage, nSelectedImage);
+}
+
+//
+
+CConvertDlg::CTreeItemFilter::CTreeItemFilter(IBaseFilter* pBF, CTreeCtrl& tree, HTREEITEM hTIParent)
+ : CTreeItem(tree, hTIParent)
+ , m_pBF(pBF)
+{
+ Update();
+}
+
+void CConvertDlg::CTreeItemFilter::Update()
+{
+ SetLabel(CString(GetFilterName(m_pBF)));
+}
+
+//
+
+CConvertDlg::CTreeItemFile::CTreeItemFile(CString fn, IBaseFilter* pBF, CTreeCtrl& tree, HTREEITEM hTIParent)
+ : CTreeItemFilter(pBF, tree, hTIParent)
+ , m_fn(fn)
+{
+ Update();
+}
+
+void CConvertDlg::CTreeItemFile::Update()
+{
+ CPath path = m_fn;
+ path.StripPath();
+ SetLabel(path);
+}
+
+bool CConvertDlg::CTreeItemFile::ToolTip(CString& str)
+{
+ str = m_fn;
+ return true;
+}
+
+//
+
+CConvertDlg::CTreeItemPin::CTreeItemPin(IPin* pPin, CTreeCtrl& tree, HTREEITEM hTIParent)
+ : CTreeItem(tree, hTIParent)
+ , m_pPin(pPin)
+{
+ Update();
+}
+
+void CConvertDlg::CTreeItemPin::Update()
+{
+ if(!m_pPin) {ASSERT(0); return;}
+
+ CString label = GetPinName(m_pPin);
+ if(!IsConnected()) label = _T("[D] ") + label;
+ SetLabel(label);
+
+ CMediaType mt;
+ if(S_OK == m_pPin->ConnectionMediaType(&mt))
+ {
+ if(mt.majortype == MEDIATYPE_Video) SetImage(1, 1);
+ else if(mt.majortype == MEDIATYPE_Audio) SetImage(2, 2);
+ else if(mt.majortype == MEDIATYPE_Text || mt.majortype == MEDIATYPE_Subtitle) SetImage(3, 3);
+ }
+}
+
+bool CConvertDlg::CTreeItemPin::ToolTip(CString& str)
+{
+ CMediaTypeEx mt;
+ if(FAILED(m_pPin->ConnectionMediaType(&mt))) return false;
+ str = mt.ToString(m_pPin);
+ return true;
+}
+
+bool CConvertDlg::CTreeItemPin::IsConnected()
+{
+ CComPtr<IPin> pPinTo;
+ return m_pPin && SUCCEEDED(m_pPin->ConnectedTo(&pPinTo)) && pPinTo;
+}
+
+//
+
+CConvertDlg::CTreeItemResourceFolder::CTreeItemResourceFolder(CTreeCtrl& tree, HTREEITEM hTIParent)
+ : CTreeItem(tree, hTIParent)
+{
+ Update();
+}
+
+void CConvertDlg::CTreeItemResourceFolder::Update()
+{
+ SetLabel(_T("Resources"));
+}
+
+bool CConvertDlg::CTreeItemResourceFolder::ToolTip(CString& str)
+{
+ if(!m_tree.ItemHasChildren(m_hTI))
+ return false;
+
+ int files = 0;
+ float size = 0;
+
+ HTREEITEM hChildItem = m_tree.GetChildItem(m_hTI);
+
+ while(hChildItem != NULL)
+ {
+ HTREEITEM hNextItem = m_tree.GetNextItem(hChildItem, TVGN_NEXT);
+ if(CTreeItemResource* t = dynamic_cast<CTreeItemResource*>((CTreeItem*)m_tree.GetItemData(hChildItem)))
+ size += t->m_res.data.GetCount(), files++;
+ hChildItem = hNextItem;
+ }
+
+ size /= 1024;
+ if(size < 1024) str.Format(_T("%d file(s), %.2f KB"), files, size);
+ else str.Format(_T("%d file(s), %.2f MB"), files, size/1024);
+
+ return true;
+}
+
+//
+
+CConvertDlg::CTreeItemResource::CTreeItemResource(const CDSMResource& res, CTreeCtrl& tree, HTREEITEM hTIParent)
+ : CTreeItem(tree, hTIParent)
+{
+ m_res = res;
+ Update();
+}
+
+CConvertDlg::CTreeItemResource::~CTreeItemResource()
+{
+}
+
+void CConvertDlg::CTreeItemResource::Update()
+{
+ SetLabel(CString(m_res.name));
+
+ CStringW mime = m_res.mime;
+ mime.Trim();
+ mime.MakeLower();
+ if(mime == L"application/x-truetype-font") SetImage(4, 4);
+ else if(mime.Find(L"text/") == 0) SetImage(5, 5);
+ else SetImage(6, 6);
+}
+
+bool CConvertDlg::CTreeItemResource::ToolTip(CString& str)
+{
+ if(!m_res.mime.IsEmpty()) str = CString(m_res.mime) + _T("\r\n\r\n");
+ if(!m_res.desc.IsEmpty()) str += CString(m_res.desc);
+ str.Trim();
+ return true;
+}
+
+//
+
+CConvertDlg::CTreeItemChapterFolder::CTreeItemChapterFolder(CTreeCtrl& tree, HTREEITEM hTIParent)
+ : CTreeItem(tree, hTIParent)
+{
+ Update();
+}
+
+void CConvertDlg::CTreeItemChapterFolder::Update()
+{
+ SetLabel(_T("Chapters"));
+}
+
+//
+
+CConvertDlg::CTreeItemChapter::CTreeItemChapter(const CDSMChapter& chap, CTreeCtrl& tree, HTREEITEM hTIParent)
+ : CTreeItem(tree, hTIParent)
+{
+ m_chap = chap;
+ Update();
+}
+
+void CConvertDlg::CTreeItemChapter::Update()
+{
+ REFERENCE_TIME rt = m_chap.rt;
+ rt /= 10000;
+ int ms = (int)(rt%1000);
+ rt /= 1000;
+ int s = (int)(rt%60);
+ rt /= 60;
+ int m = (int)(rt%60);
+ rt /= 60;
+ int h = (int)(rt);
+
+ CString label;
+ label.Format(_T("%02d:%02d:%02d.%03d - %s"), h, m, s, ms, CString(m_chap.name));
+ SetLabel(label);
+
+ SetImage(7, 7);
+}
diff --git a/src/apps/mplayerc/ConvertDlg.h b/src/apps/mplayerc/ConvertDlg.h
new file mode 100644
index 000000000..72bf7a271
--- /dev/null
+++ b/src/apps/mplayerc/ConvertDlg.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "IGraphBuilder2.h"
+#include "..\..\DSUtil\DSMPropertyBag.h"
+
+class CFilterTreeCtrl : public CTreeCtrl
+{
+public:
+ CFilterTreeCtrl();
+
+protected:
+ virtual INT_PTR OnToolHitTest(CPoint point, TOOLINFO* pTI) const;
+ virtual void PreSubclassWindow();
+
+public:
+ DECLARE_MESSAGE_MAP()
+ afx_msg BOOL OnToolTipText(UINT nID, NMHDR* pNMHDR, LRESULT* pResult);
+};
+
+// CConvertDlg dialog
+
+class CConvertDlg : public CResizableDialog
+{
+public:
+ class CTreeItem
+ {
+ protected:
+ CTreeCtrl& m_tree;
+ HTREEITEM m_hTI;
+
+ public:
+ CTreeItem(CTreeCtrl& tree, HTREEITEM hTIParent);
+ virtual ~CTreeItem();
+ virtual void Update() {}
+ virtual bool ToolTip(CString& str) {return false;}
+ void SetLabel(LPCTSTR label);
+ void SetImage(int nImage, int nSelectedImage);
+ operator HTREEITEM() {return m_hTI;}
+ };
+
+ class CTreeItemFilter : public CTreeItem
+ {
+ public:
+ CComPtr<IBaseFilter> m_pBF;
+ CTreeItemFilter(IBaseFilter* pBF, CTreeCtrl& tree, HTREEITEM hTIParent);
+ void Update();
+ };
+
+ class CTreeItemFile : public CTreeItemFilter
+ {
+ public:
+ CString m_fn;
+ CTreeItemFile(CString fn, IBaseFilter* pBF, CTreeCtrl& tree, HTREEITEM hTIParent);
+ void Update();
+ bool ToolTip(CString& str);
+ };
+
+ class CTreeItemPin : public CTreeItem
+ {
+ public:
+ CComPtr<IPin> m_pPin;
+ CTreeItemPin(IPin* pPin, CTreeCtrl& tree, HTREEITEM hTIParent);
+ void Update();
+ bool ToolTip(CString& str);
+ bool IsConnected();
+ };
+
+ class CTreeItemResourceFolder : public CTreeItem
+ {
+ public:
+ CTreeItemResourceFolder(CTreeCtrl& tree, HTREEITEM hTIParent);
+ void Update();
+ bool ToolTip(CString& str);
+ };
+
+ class CTreeItemResource : public CTreeItem
+ {
+ public:
+ CDSMResource m_res;
+ CTreeItemResource(const CDSMResource& res, CTreeCtrl& tree, HTREEITEM hTIParent);
+ ~CTreeItemResource();
+ void Update();
+ bool ToolTip(CString& str);
+ };
+
+ class CTreeItemChapterFolder : public CTreeItem
+ {
+ public:
+ CTreeItemChapterFolder(CTreeCtrl& tree, HTREEITEM hTIParent);
+ void Update();
+ };
+
+ class CTreeItemChapter : public CTreeItem
+ {
+ public:
+ CDSMChapter m_chap;
+ CTreeItemChapter(const CDSMChapter& chap, CTreeCtrl& tree, HTREEITEM hTIParent);
+ void Update();
+ };
+
+private:
+ CComPtr<IGraphBuilder2> m_pGB;
+ CComPtr<IBaseFilter> m_pMux;
+ CComQIPtr<IMediaControl> m_pMC;
+ CComQIPtr<IMediaEventEx> m_pME;
+ CComQIPtr<IMediaSeeking> m_pMS;
+
+ CString m_title;
+ UINT m_nIDEventStatus;
+
+ CBitmap m_streamtypesbm;
+ CImageList m_streamtypes;
+
+ CList<CTreeItem*> m_pTIs;
+
+ void AddFile(CString fn);
+ bool ConvertFile(LPCTSTR fn, IPin* pPin = NULL);
+ void AddFilter(HTREEITEM hTI, IBaseFilter* pBF);
+ void DeleteFilter(IBaseFilter* pBF);
+ void DeleteItem(HTREEITEM hTI);
+ void DeleteChildren(HTREEITEM hTI);
+
+ HTREEITEM HitTest(CPoint& sp, CPoint& cp);
+
+ void ShowPopup(CPoint p);
+ void ShowFilePopup(HTREEITEM hTI, CPoint p);
+ void ShowPinPopup(HTREEITEM hTI, CPoint p);
+ void ShowResourceFolderPopup(HTREEITEM hTI, CPoint p);
+ void ShowResourcePopup(HTREEITEM hTI, CPoint p);
+ void ShowChapterFolderPopup(HTREEITEM hTI, CPoint p);
+ void ShowChapterPopup(HTREEITEM hTI, CPoint p);
+
+ bool EditProperties(IDSMPropertyBag* pPB);
+ bool EditResource(CTreeItemResource* t);
+ bool EditChapter(CTreeItemChapter* t);
+
+public:
+ CConvertDlg(CWnd* pParent = NULL); // standard constructor
+ virtual ~CConvertDlg();
+
+// Dialog Data
+ enum { IDD = IDD_CONVERT_DLG };
+ CFilterTreeCtrl m_tree;
+ CString m_fn;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg LRESULT OnGraphNotify(WPARAM wParam, LPARAM lParam);
+ afx_msg void OnDropFiles(HDROP hDropInfo);
+ afx_msg void OnClose();
+ afx_msg void OnNMClickTree1(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnNMRclickTree1(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnNMDblclkTree1(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnUpdateButton1(CCmdUI* pCmdUI);
+ afx_msg void OnTimer(UINT nIDEvent);
+ afx_msg void OnBnClickedButton2();
+ afx_msg void OnBnClickedButton3();
+ afx_msg void OnBnClickedButton4();
+ afx_msg void OnUpdateButton2(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateButton3(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateButton4(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/ConvertPropsDlg.cpp b/src/apps/mplayerc/ConvertPropsDlg.cpp
new file mode 100644
index 000000000..da420438f
--- /dev/null
+++ b/src/apps/mplayerc/ConvertPropsDlg.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// ConvertPropsDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "ConvertPropsDlg.h"
+
+
+// CConvertPropsDlg dialog
+
+CConvertPropsDlg::CConvertPropsDlg(bool fPin, CWnd* pParent /*=NULL*/)
+ : CResizableDialog(CConvertPropsDlg::IDD, pParent)
+ , m_fPin(fPin)
+{
+}
+
+CConvertPropsDlg::~CConvertPropsDlg()
+{
+}
+
+void CConvertPropsDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_COMBO1, m_fcc);
+ DDX_Control(pDX, IDC_EDIT1, m_text);
+ DDX_Control(pDX, IDC_LIST1, m_list);
+}
+
+
+BEGIN_MESSAGE_MAP(CConvertPropsDlg, CResizableDialog)
+ ON_NOTIFY(NM_CLICK, IDC_LIST1, OnNMClickList1)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateButton1)
+ ON_CBN_EDITCHANGE(IDC_COMBO1, OnCbnEditchangeCombo1)
+ ON_CBN_SELCHANGE(IDC_COMBO1, OnCbnSelchangeCombo1)
+ ON_NOTIFY(LVN_KEYDOWN, IDC_LIST1, OnLvnKeydownList1)
+END_MESSAGE_MAP()
+
+
+// CConvertPropsDlg message handlers
+
+BOOL CConvertPropsDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AddAnchor(IDC_COMBO1, TOP_LEFT);
+ AddAnchor(IDC_EDIT1, TOP_LEFT, TOP_RIGHT);
+ AddAnchor(IDC_BUTTON1, TOP_RIGHT);
+ AddAnchor(IDC_LIST1, TOP_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDOK, BOTTOM_CENTER);
+ AddAnchor(IDCANCEL, BOTTOM_CENTER);
+
+ if(m_fPin)
+ {
+ m_fcc.AddString(_T("NAME"));
+ m_fcc.AddString(_T("LANG"));
+ m_fcc.AddString(_T("DESC"));
+ m_fcc.AddString(_T("SGRP"));
+ }
+ else
+ {
+ m_fcc.AddString(_T("TITL"));
+ m_fcc.AddString(_T("AUTH"));
+ m_fcc.AddString(_T("RTNG"));
+ m_fcc.AddString(_T("CPYR"));
+ m_fcc.AddString(_T("DESC"));
+ }
+
+ m_list.InsertColumn(0, _T("ID"), LVCFMT_LEFT, 75);
+ m_list.InsertColumn(1, _T("Text"), LVCFMT_LEFT, 280);
+
+ m_list.SetExtendedStyle(m_list.GetExtendedStyle()|LVS_EX_FULLROWSELECT);
+
+ POSITION pos = m_props.GetStartPosition();
+ while(pos)
+ {
+ CString key, value;
+ m_props.GetNextAssoc(pos, key, value);
+ SetItem(key, value);
+ }
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CConvertPropsDlg::SetItem(CString key, CString value)
+{
+ LVFINDINFO fi;
+ fi.flags = LVFI_STRING;
+ fi.psz = key;
+
+ int i = m_list.FindItem(&fi);
+ if(i < 0) i = m_list.InsertItem(m_list.GetItemCount(), _T(""));
+
+ key.Trim();
+ value.Trim();
+
+ if(value.IsEmpty())
+ {
+ m_list.DeleteItem(i);
+ return;
+ }
+
+ if(key == _T("LANG") && value.GetLength() != 3)
+ {
+ m_list.DeleteItem(i);
+ AfxMessageBox(_T("LANG has to be a three letter ISO 639-2 language code."), MB_OK);
+ return;
+ }
+
+ m_list.SetItemText(i, 0, key);
+ m_list.SetItemText(i, 1, value);
+}
+
+void CConvertPropsDlg::OnOK()
+{
+ m_props.RemoveAll();
+
+ for(int i = 0; i < m_list.GetItemCount(); i++)
+ m_props[m_list.GetItemText(i, 0)] = m_list.GetItemText(i, 1);
+
+ __super::OnOK();
+}
+
+void CConvertPropsDlg::OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)pNMHDR;
+
+ if(lpnmlv->iItem >= 0)
+ {
+ m_fcc.SetWindowText(m_list.GetItemText(lpnmlv->iItem, 0));
+ m_text.SetWindowText(m_list.GetItemText(lpnmlv->iItem, 1));
+ }
+
+ *pResult = 0;
+}
+
+void CConvertPropsDlg::OnBnClickedButton1()
+{
+ CString key, value;
+ m_fcc.GetWindowText(key);
+ m_text.GetWindowText(value);
+ if(key.GetLength() != 4) {AfxMessageBox(_T("ID must be 4 characters long!"), MB_OK); return;}
+ SetItem(key, value);
+}
+
+void CConvertPropsDlg::OnUpdateButton1(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(GetDlgItem(IDC_EDIT1)->GetWindowTextLength() > 0);
+}
+
+void CConvertPropsDlg::OnCbnEditchangeCombo1()
+{
+ int i = m_fcc.GetCurSel();
+ if(i < 0) return;
+
+ CString key;
+ m_fcc.GetLBText(i, key);
+
+ LVFINDINFO fi;
+ fi.flags = LVFI_STRING;
+ fi.psz = key;
+
+ i = m_list.FindItem(&fi);
+ if(i > 0) m_text.SetWindowText(m_list.GetItemText(i, 1));
+}
+
+void CConvertPropsDlg::OnCbnSelchangeCombo1()
+{
+ OnCbnEditchangeCombo1();
+}
+
+void CConvertPropsDlg::OnLvnKeydownList1(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMLVKEYDOWN pLVKeyDow = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);
+
+ int i = m_fcc.GetCurSel();
+ if(i >= 0) m_list.DeleteItem(i);
+
+ *pResult = 0;
+}
diff --git a/src/apps/mplayerc/ConvertPropsDlg.h b/src/apps/mplayerc/ConvertPropsDlg.h
new file mode 100644
index 000000000..53824eed6
--- /dev/null
+++ b/src/apps/mplayerc/ConvertPropsDlg.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "..\..\DSUtil\DSMPropertyBag.h"
+#include "afxwin.h"
+#include "afxcmn.h"
+
+// CConvertPropsDlg dialog
+
+class CConvertPropsDlg : public CResizableDialog
+{
+private:
+ bool m_fPin;
+ void SetItem(CString key, CString value);
+
+public:
+ CConvertPropsDlg(bool fPin, CWnd* pParent = NULL); // standard constructor
+ virtual ~CConvertPropsDlg();
+
+ CAtlStringMap<> m_props;
+
+// Dialog Data
+ enum { IDD = IDD_CONVERTPROPS_DLG };
+ CComboBox m_fcc;
+ CEdit m_text;
+ CListCtrl m_list;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+
+ DECLARE_MESSAGE_MAP()
+public:
+ afx_msg void OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnUpdateButton1(CCmdUI* pCmdUI);
+ afx_msg void OnCbnEditchangeCombo1();
+ afx_msg void OnCbnSelchangeCombo1();
+ afx_msg void OnLvnKeydownList1(NMHDR *pNMHDR, LRESULT *pResult);
+};
diff --git a/src/apps/mplayerc/ConvertResDlg.cpp b/src/apps/mplayerc/ConvertResDlg.cpp
new file mode 100644
index 000000000..37d632801
--- /dev/null
+++ b/src/apps/mplayerc/ConvertResDlg.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// ConvertResDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "ConvertResDlg.h"
+
+// CConvertResDlg dialog
+
+CConvertResDlg::CConvertResDlg(CWnd* pParent /*=NULL*/)
+ : CResizableDialog(CConvertResDlg::IDD, pParent)
+ , m_name(_T(""))
+ , m_desc(_T(""))
+{
+}
+
+CConvertResDlg::~CConvertResDlg()
+{
+}
+
+void CConvertResDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Text(pDX, IDC_EDIT3, m_name);
+ DDX_Text(pDX, IDC_COMBO1, m_mime);
+ DDX_Control(pDX, IDC_COMBO1, m_mimectrl);
+ DDX_Text(pDX, IDC_EDIT2, m_desc);
+}
+
+BOOL CConvertResDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AddAnchor(IDC_EDIT3, TOP_LEFT, TOP_RIGHT);
+ AddAnchor(IDC_COMBO1, TOP_LEFT, TOP_RIGHT);
+ AddAnchor(IDC_EDIT2, TOP_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDOK, BOTTOM_CENTER);
+ AddAnchor(IDCANCEL, BOTTOM_CENTER);
+
+ CRegKey key;
+ CString str(_T("MIME\\Database\\Content Type"));
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, str, KEY_READ))
+ {
+ CAtlStringMap<bool> mimes;
+
+ TCHAR buff[256];
+ DWORD len = countof(buff);
+ for(int i = 0; ERROR_SUCCESS == key.EnumKey(i, buff, &len); i++, len = countof(buff))
+ {
+ CRegKey mime;
+ TCHAR ext[64];
+ ULONG len = countof(ext);
+ if(ERROR_SUCCESS == mime.Open(HKEY_CLASSES_ROOT, str + _T("\\") + buff, KEY_READ)
+ && ERROR_SUCCESS == mime.QueryStringValue(_T("Extension"), ext, &len))
+ {
+ CString mime = CString(buff).MakeLower();
+ mimes[mime] = true;
+ m_mimectrl.AddString(mime);
+ }
+ }
+
+ static TCHAR* moremimes[] =
+ {
+ _T("application/octet-stream"),
+ _T("application/zip"),
+ _T("application/rar"),
+ _T("application/x-truetype-font"),
+ };
+
+ for(int i = 0; i < countof(moremimes); i++)
+ if(!mimes.Lookup(moremimes[i]))
+ m_mimectrl.AddString(moremimes[i]);
+ }
+
+ m_desc.Replace(_T("\n"), _T("\r\n"));
+
+ UpdateData(FALSE);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CConvertResDlg::OnOK()
+{
+ UpdateData();
+
+ m_name.Trim();
+ m_mime.Trim();
+ m_desc.Replace(_T("\r\n"), _T("\r"));
+ m_desc.Trim();
+
+ __super::OnOK();
+}
+
+BEGIN_MESSAGE_MAP(CConvertResDlg, CResizableDialog)
+ ON_UPDATE_COMMAND_UI(IDOK, OnUpdateOK)
+END_MESSAGE_MAP()
+
+// CConvertResDlg message handlers
+
+void CConvertResDlg::OnUpdateOK(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(GetDlgItem(IDC_EDIT3)->GetWindowTextLength() > 0 && GetDlgItem(IDC_COMBO1)->GetWindowTextLength() > 0);
+}
diff --git a/src/apps/mplayerc/ConvertResDlg.h b/src/apps/mplayerc/ConvertResDlg.h
new file mode 100644
index 000000000..45d54b946
--- /dev/null
+++ b/src/apps/mplayerc/ConvertResDlg.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "afxwin.h"
+
+
+// CConvertResDlg dialog
+
+class CConvertResDlg : public CResizableDialog
+{
+public:
+ CConvertResDlg(CWnd* pParent = NULL); // standard constructor
+ virtual ~CConvertResDlg();
+
+// Dialog Data
+ enum { IDD = IDD_CONVERTRES_DLG };
+ CString m_name;
+ CString m_mime;
+ CComboBox m_mimectrl;
+ CString m_desc;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+
+ DECLARE_MESSAGE_MAP()
+public:
+ afx_msg void OnUpdateOK(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/D3DFont.cpp b/src/apps/mplayerc/D3DFont.cpp
new file mode 100644
index 000000000..494797a0b
--- /dev/null
+++ b/src/apps/mplayerc/D3DFont.cpp
@@ -0,0 +1,881 @@
+#include "stdafx.h"
+#include <stdio.h>
+#include <tchar.h>
+#include <D3DX9.h>
+#include "D3DFont.h"
+//#include "D3DUtil.h"
+//#include "DXUtil.h"
+
+//-----------------------------------------------------------------------------
+// Miscellaneous helper functions
+//-----------------------------------------------------------------------------
+#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
+#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
+#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
+
+
+
+//-----------------------------------------------------------------------------
+// Custom vertex types for rendering text
+//-----------------------------------------------------------------------------
+#define MAX_NUM_VERTICES 50*6
+
+struct FONT2DVERTEX { D3DXVECTOR4 p; DWORD color; FLOAT tu, tv; };
+struct FONT3DVERTEX { D3DXVECTOR3 p; D3DXVECTOR3 n; FLOAT tu, tv; };
+
+#define D3DFVF_FONT2DVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
+#define D3DFVF_FONT3DVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)
+
+inline FONT2DVERTEX InitFont2DVertex( const D3DXVECTOR4& p, D3DCOLOR color,
+ FLOAT tu, FLOAT tv )
+{
+ FONT2DVERTEX v; v.p = p; v.color = color; v.tu = tu; v.tv = tv;
+ return v;
+}
+
+inline FONT3DVERTEX InitFont3DVertex( const D3DXVECTOR3& p, const D3DXVECTOR3& n,
+ FLOAT tu, FLOAT tv )
+{
+ FONT3DVERTEX v; v.p = p; v.n = n; v.tu = tu; v.tv = tv;
+ return v;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: CD3DFont()
+// Desc: Font class constructor
+//-----------------------------------------------------------------------------
+CD3DFont::CD3DFont( const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags )
+{
+ _tcsncpy( m_strFontName, strFontName, sizeof(m_strFontName) / sizeof(TCHAR) );
+ m_strFontName[sizeof(m_strFontName) / sizeof(TCHAR) - 1] = _T('\0');
+ m_dwFontHeight = dwHeight;
+ m_dwFontFlags = dwFlags;
+ m_dwSpacing = 0;
+
+ m_pd3dDevice = NULL;
+ m_pTexture = NULL;
+ m_pVB = NULL;
+
+ m_pStateBlockSaved = NULL;
+ m_pStateBlockDrawText = NULL;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: ~CD3DFont()
+// Desc: Font class destructor
+//-----------------------------------------------------------------------------
+CD3DFont::~CD3DFont()
+{
+ InvalidateDeviceObjects();
+ DeleteDeviceObjects();
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: CreateGDIFont
+// Desc: Create a font based on the current state of related member variables
+// and return the handle (or null on error)
+//-----------------------------------------------------------------------------
+HRESULT CD3DFont::CreateGDIFont( HDC hDC, HFONT* pFont )
+{
+ // Create a font. By specifying ANTIALIASED_QUALITY, we might get an
+ // antialiased font, but this is not guaranteed.
+ INT nHeight = -MulDiv( m_dwFontHeight,
+ (INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale),
+ 72 );
+ DWORD dwBold = (m_dwFontFlags & D3DFONT_BOLD) ? FW_BOLD : FW_NORMAL;
+ DWORD dwItalic = (m_dwFontFlags & D3DFONT_ITALIC) ? TRUE : FALSE;
+ *pFont = CreateFont( nHeight, 0, 0, 0, dwBold, dwItalic,
+ FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
+ VARIABLE_PITCH, m_strFontName );
+
+ if( *pFont == NULL )
+ return E_FAIL;
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: PaintAlphabet
+// Desc: Paint the printable characters for the given GDI font onto the
+// provided device context. If the bMeasureOnly flag is set, no drawing
+// will occur.
+//-----------------------------------------------------------------------------
+HRESULT CD3DFont::PaintAlphabet( HDC hDC, BOOL bMeasureOnly )
+{
+ SIZE size;
+ TCHAR str[2] = _T("x"); // One-character, null-terminated string
+
+ // Calculate the spacing between characters based on line height
+ if( 0 == GetTextExtentPoint32( hDC, str, 1, &size ) )
+ return E_FAIL;
+ m_dwSpacing = (DWORD) ceil(size.cy * 0.3f);
+
+ // Set the starting point for the drawing
+ DWORD x = m_dwSpacing;
+ DWORD y = 0;
+
+ // For each character, draw text on the DC and advance the current position
+ for( char c = 32; c < 127; c++ )
+ {
+ str[0] = c;
+ if( 0 == GetTextExtentPoint32( hDC, str, 1, &size ) )
+ return E_FAIL;
+
+ if( (DWORD)(x + size.cx + m_dwSpacing) > m_dwTexWidth )
+ {
+ x = m_dwSpacing;
+ y += size.cy + 1;
+ }
+
+ // Check to see if there's room to write the character here
+ if( y + size.cy > m_dwTexHeight )
+ return D3DERR_MOREDATA;
+
+ if( !bMeasureOnly )
+ {
+ // Perform the actual drawing
+ if( 0 == ExtTextOut( hDC, x+0, y+0, ETO_OPAQUE, NULL, str, 1, NULL ) )
+ return E_FAIL;
+
+ m_fTexCoords[c-32][0] = ((FLOAT)(x + 0 - m_dwSpacing))/m_dwTexWidth;
+ m_fTexCoords[c-32][1] = ((FLOAT)(y + 0 + 0 ))/m_dwTexHeight;
+ m_fTexCoords[c-32][2] = ((FLOAT)(x + size.cx + m_dwSpacing))/m_dwTexWidth;
+ m_fTexCoords[c-32][3] = ((FLOAT)(y + size.cy + 0 ))/m_dwTexHeight;
+ }
+
+ x += size.cx + (2 * m_dwSpacing);
+ }
+
+ return S_OK;
+}
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: InitDeviceObjects()
+// Desc: Initializes device-dependent objects, including the vertex buffer used
+// for rendering text and the texture map which stores the font image.
+//-----------------------------------------------------------------------------
+HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice )
+{
+ HRESULT hr = S_OK;
+ HFONT hFont = NULL;
+ HFONT hFontOld = NULL;
+ HDC hDC = NULL;
+ HBITMAP hbmBitmap = NULL;
+ HGDIOBJ hbmOld = NULL;
+
+ // Keep a local copy of the device
+ m_pd3dDevice = pd3dDevice;
+
+ // Assume we will draw fonts into texture without scaling unless the
+ // required texture size is found to be larger than the device max
+ m_fTextScale = 1.0f;
+
+ hDC = CreateCompatibleDC( NULL );
+ SetMapMode( hDC, MM_TEXT );
+
+ hr = CreateGDIFont( hDC, &hFont );
+ if( FAILED(hr) )
+ goto LCleanReturn;
+
+ hFontOld = (HFONT) SelectObject( hDC, hFont );
+
+ // Calculate the dimensions for the smallest power-of-two texture which
+ // can hold all the printable characters
+ m_dwTexWidth = m_dwTexHeight = 128;
+ while( D3DERR_MOREDATA == ( hr = PaintAlphabet( hDC, true ) ) )
+ {
+ m_dwTexWidth *= 2;
+ m_dwTexHeight *= 2;
+ }
+
+ if( FAILED(hr) )
+ goto LCleanReturn;
+
+ // If requested texture is too big, use a smaller texture and smaller font,
+ // and scale up when rendering.
+ D3DCAPS9 d3dCaps;
+ m_pd3dDevice->GetDeviceCaps( &d3dCaps );
+
+ if( m_dwTexWidth > d3dCaps.MaxTextureWidth )
+ {
+ m_fTextScale = (FLOAT)d3dCaps.MaxTextureWidth / (FLOAT)m_dwTexWidth;
+ m_dwTexWidth = m_dwTexHeight = d3dCaps.MaxTextureWidth;
+
+ bool bFirstRun = true; // Flag clear after first run
+
+ do
+ {
+ // If we've already tried fitting the new text, the scale is still
+ // too large. Reduce and try again.
+ if( !bFirstRun)
+ m_fTextScale *= 0.9f;
+
+ // The font has to be scaled to fit on the maximum texture size; our
+ // current font is too big and needs to be recreated to scale.
+ DeleteObject( SelectObject( hDC, hFontOld ) );
+
+ hr = CreateGDIFont( hDC, &hFont );
+ if( FAILED(hr) )
+ goto LCleanReturn;
+
+ hFontOld = (HFONT) SelectObject( hDC, hFont );
+
+ bFirstRun = false;
+ }
+ while( D3DERR_MOREDATA == ( hr = PaintAlphabet( hDC, true ) ) );
+ }
+
+
+ // Create a new texture for the font
+ hr = m_pd3dDevice->CreateTexture( m_dwTexWidth, m_dwTexHeight, 1,
+ 0, D3DFMT_A4R4G4B4,
+ D3DPOOL_MANAGED, &m_pTexture, NULL );
+ if( FAILED(hr) )
+ goto LCleanReturn;
+
+ // Prepare to create a bitmap
+ DWORD* pBitmapBits;
+ BITMAPINFO bmi;
+ ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) );
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
+ bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biBitCount = 32;
+
+ // Create a bitmap for the font
+ hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS,
+ (void**)&pBitmapBits, NULL, 0 );
+
+ hbmOld = SelectObject( hDC, hbmBitmap );
+
+ // Set text properties
+ SetTextColor( hDC, RGB(255,255,255) );
+ SetBkColor( hDC, 0x00000000 );
+ SetTextAlign( hDC, TA_TOP );
+
+ // Paint the alphabet onto the selected bitmap
+ hr = PaintAlphabet( hDC, false );
+ if( FAILED(hr) )
+ goto LCleanReturn;
+
+ // Lock the surface and write the alpha values for the set pixels
+ D3DLOCKED_RECT d3dlr;
+ m_pTexture->LockRect( 0, &d3dlr, 0, 0 );
+ BYTE* pDstRow;
+ pDstRow = (BYTE*)d3dlr.pBits;
+ WORD* pDst16;
+ BYTE bAlpha; // 4-bit measure of pixel intensity
+ DWORD x, y;
+
+ for( y=0; y < m_dwTexHeight; y++ )
+ {
+ pDst16 = (WORD*)pDstRow;
+ for( x=0; x < m_dwTexWidth; x++ )
+ {
+ bAlpha = (BYTE)((pBitmapBits[m_dwTexWidth*y + x] & 0xff) >> 4);
+ if (bAlpha > 0)
+ {
+ *pDst16++ = (WORD) ((bAlpha << 12) | 0x0fff);
+ }
+ else
+ {
+ *pDst16++ = 0x0000;
+ }
+ }
+ pDstRow += d3dlr.Pitch;
+ }
+
+ hr = S_OK;
+
+ // Done updating texture, so clean up used objects
+LCleanReturn:
+ if( m_pTexture )
+ m_pTexture->UnlockRect(0);
+
+ SelectObject( hDC, hbmOld );
+ SelectObject( hDC, hFontOld );
+ DeleteObject( hbmBitmap );
+ DeleteObject( hFont );
+ DeleteDC( hDC );
+
+ return hr;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: RestoreDeviceObjects()
+// Desc:
+//-----------------------------------------------------------------------------
+HRESULT CD3DFont::RestoreDeviceObjects()
+{
+ HRESULT hr;
+
+ // Create vertex buffer for the letters
+ int vertexSize = max( sizeof(FONT2DVERTEX), sizeof(FONT3DVERTEX ) );
+ if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer( MAX_NUM_VERTICES * vertexSize,
+ D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0,
+ D3DPOOL_DEFAULT, &m_pVB, NULL ) ) )
+ {
+ return hr;
+ }
+
+ bool bSupportsAlphaBlend = true;
+ LPDIRECT3D9 pd3d9 = NULL;
+ if( SUCCEEDED( m_pd3dDevice->GetDirect3D( &pd3d9 ) ) )
+ {
+ D3DCAPS9 Caps;
+ D3DDISPLAYMODE Mode;
+ LPDIRECT3DSURFACE9 pSurf = NULL;
+ D3DSURFACE_DESC Desc;
+ m_pd3dDevice->GetDeviceCaps( &Caps );
+ m_pd3dDevice->GetDisplayMode( 0, &Mode );
+ if( SUCCEEDED( m_pd3dDevice->GetRenderTarget( 0, &pSurf ) ) )
+ {
+ pSurf->GetDesc( &Desc );
+ if( FAILED( pd3d9->CheckDeviceFormat( Caps.AdapterOrdinal, Caps.DeviceType, Mode.Format,
+ D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_SURFACE,
+ Desc.Format ) ) )
+ {
+ bSupportsAlphaBlend = false;
+ }
+ SAFE_RELEASE( pSurf );
+ }
+ SAFE_RELEASE( pd3d9 );
+ }
+
+ // Create the state blocks for rendering text
+ for( UINT which=0; which<2; which++ )
+ {
+ m_pd3dDevice->BeginStateBlock();
+ m_pd3dDevice->SetTexture( 0, m_pTexture );
+
+ if ( D3DFONT_ZENABLE & m_dwFontFlags )
+ m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
+ else
+ m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
+
+ if( bSupportsAlphaBlend )
+ {
+ m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
+ m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
+ m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
+ }
+ else
+ {
+ m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
+ }
+ m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
+ m_pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 0x08 );
+ m_pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
+ m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
+ m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
+ m_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE );
+ m_pd3dDevice->SetRenderState( D3DRS_CLIPPING, TRUE );
+ m_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, FALSE );
+ m_pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND, D3DVBF_DISABLE );
+ m_pd3dDevice->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE );
+ m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
+ m_pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE,
+ D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN |
+ D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA );
+ m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
+ m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
+ m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
+ m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
+ m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
+ m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
+ m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
+ m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
+ m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
+ m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
+ m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT );
+ m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
+ m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE );
+
+ if( which==0 )
+ m_pd3dDevice->EndStateBlock( &m_pStateBlockSaved );
+ else
+ m_pd3dDevice->EndStateBlock( &m_pStateBlockDrawText );
+ }
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: InvalidateDeviceObjects()
+// Desc: Destroys all device-dependent objects
+//-----------------------------------------------------------------------------
+HRESULT CD3DFont::InvalidateDeviceObjects()
+{
+ SAFE_RELEASE( m_pVB );
+ SAFE_RELEASE( m_pStateBlockSaved );
+ SAFE_RELEASE( m_pStateBlockDrawText );
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: DeleteDeviceObjects()
+// Desc: Destroys all device-dependent objects
+//-----------------------------------------------------------------------------
+HRESULT CD3DFont::DeleteDeviceObjects()
+{
+ SAFE_RELEASE( m_pTexture );
+ m_pd3dDevice = NULL;
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: GetTextExtent()
+// Desc: Get the dimensions of a text string
+//-----------------------------------------------------------------------------
+HRESULT CD3DFont::GetTextExtent( const TCHAR* strText, SIZE* pSize )
+{
+ if( NULL==strText || NULL==pSize )
+ return E_FAIL;
+
+ FLOAT fRowWidth = 0.0f;
+ FLOAT fRowHeight = (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight;
+ FLOAT fWidth = 0.0f;
+ FLOAT fHeight = fRowHeight;
+
+ while( *strText )
+ {
+ TCHAR c = *strText++;
+
+ if( c == _T('\n') )
+ {
+ fRowWidth = 0.0f;
+ fHeight += fRowHeight;
+ }
+
+ if( (c-32) < 0 || (c-32) >= 128-32 )
+ continue;
+
+ FLOAT tx1 = m_fTexCoords[c-32][0];
+ FLOAT tx2 = m_fTexCoords[c-32][2];
+
+ fRowWidth += (tx2-tx1)*m_dwTexWidth - 2*m_dwSpacing;
+
+ if( fRowWidth > fWidth )
+ fWidth = fRowWidth;
+ }
+
+ pSize->cx = (int)fWidth;
+ pSize->cy = (int)fHeight;
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: DrawTextScaled()
+// Desc: Draws scaled 2D text. Note that x and y are in viewport coordinates
+// (ranging from -1 to +1). fXScale and fYScale are the size fraction
+// relative to the entire viewport. For example, a fXScale of 0.25 is
+// 1/8th of the screen width. This allows you to output text at a fixed
+// fraction of the viewport, even if the screen or window size changes.
+//-----------------------------------------------------------------------------
+HRESULT CD3DFont::DrawTextScaled( FLOAT x, FLOAT y, FLOAT z,
+ FLOAT fXScale, FLOAT fYScale, DWORD dwColor,
+ const TCHAR* strText, DWORD dwFlags )
+{
+ if( m_pd3dDevice == NULL )
+ return E_FAIL;
+
+ // Set up renderstate
+ m_pStateBlockSaved->Capture();
+ m_pStateBlockDrawText->Apply();
+ m_pd3dDevice->SetFVF( D3DFVF_FONT2DVERTEX );
+ m_pd3dDevice->SetPixelShader( NULL );
+ m_pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(FONT2DVERTEX) );
+
+ // Set filter states
+ if( dwFlags & D3DFONT_FILTERED )
+ {
+ m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
+ m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
+ }
+
+ D3DVIEWPORT9 vp;
+ m_pd3dDevice->GetViewport( &vp );
+ FLOAT fLineHeight = ( m_fTexCoords[0][3] - m_fTexCoords[0][1] ) * m_dwTexHeight;
+
+ // Center the text block in the viewport
+ if( dwFlags & D3DFONT_CENTERED_X )
+ {
+ const TCHAR* strTextTmp = strText;
+ float xFinal = 0.0f;
+
+ while( *strTextTmp )
+ {
+ TCHAR c = *strTextTmp++;
+
+ if( c == _T('\n') )
+ break; // Isn't supported.
+ if( (c-32) < 0 || (c-32) >= 128-32 )
+ continue;
+
+ FLOAT tx1 = m_fTexCoords[c-32][0];
+ FLOAT tx2 = m_fTexCoords[c-32][2];
+
+ FLOAT w = (tx2-tx1)*m_dwTexWidth;
+
+ w *= (fXScale*vp.Height)/fLineHeight;
+
+ xFinal += w - (2 * m_dwSpacing) * (fXScale*vp.Height)/fLineHeight;
+ }
+
+ x = -xFinal/vp.Width;
+ }
+ if( dwFlags & D3DFONT_CENTERED_Y )
+ {
+ y = -fLineHeight/vp.Height;
+ }
+
+ FLOAT sx = (x+1.0f)*vp.Width/2;
+ FLOAT sy = (y+1.0f)*vp.Height/2;
+ FLOAT sz = z;
+ FLOAT rhw = 1.0f;
+
+ // Adjust for character spacing
+ sx -= m_dwSpacing * (fXScale*vp.Height)/fLineHeight;
+ FLOAT fStartX = sx;
+
+ // Fill vertex buffer
+ FONT2DVERTEX* pVertices;
+ DWORD dwNumTriangles = 0L;
+ m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
+
+ while( *strText )
+ {
+ TCHAR c = *strText++;
+
+ if( c == _T('\n') )
+ {
+ sx = fStartX;
+ sy += fYScale*vp.Height;
+ }
+
+ if( (c-32) < 0 || (c-32) >= 128-32 )
+ continue;
+
+ FLOAT tx1 = m_fTexCoords[c-32][0];
+ FLOAT ty1 = m_fTexCoords[c-32][1];
+ FLOAT tx2 = m_fTexCoords[c-32][2];
+ FLOAT ty2 = m_fTexCoords[c-32][3];
+
+ FLOAT w = (tx2-tx1)*m_dwTexWidth;
+ FLOAT h = (ty2-ty1)*m_dwTexHeight;
+
+ w *= (fXScale*vp.Height)/fLineHeight;
+ h *= (fYScale*vp.Height)/fLineHeight;
+
+ if( c != _T(' ') )
+ {
+ *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx1, ty2 );
+ *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+0-0.5f,sz,rhw), dwColor, tx1, ty1 );
+ *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx2, ty2 );
+ *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+0-0.5f,sz,rhw), dwColor, tx2, ty1 );
+ *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx2, ty2 );
+ *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+0-0.5f,sz,rhw), dwColor, tx1, ty1 );
+ dwNumTriangles += 2;
+
+ if( dwNumTriangles*3 > (MAX_NUM_VERTICES-6) )
+ {
+ // Unlock, render, and relock the vertex buffer
+ m_pVB->Unlock();
+ m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
+ m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
+ dwNumTriangles = 0L;
+ }
+ }
+
+ sx += w - (2 * m_dwSpacing) * (fXScale*vp.Height)/fLineHeight;
+ }
+
+ // Unlock and render the vertex buffer
+ m_pVB->Unlock();
+ if( dwNumTriangles > 0 )
+ m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
+
+ // Restore the modified renderstates
+ m_pStateBlockSaved->Apply();
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: DrawText()
+// Desc: Draws 2D text. Note that sx and sy are in pixels
+//-----------------------------------------------------------------------------
+HRESULT CD3DFont::DrawText( FLOAT sx, FLOAT sy, DWORD dwColor,
+ const TCHAR* strText, DWORD dwFlags )
+{
+ if( m_pd3dDevice == NULL )
+ return E_FAIL;
+
+ // Setup renderstate
+ m_pStateBlockSaved->Capture();
+ m_pStateBlockDrawText->Apply();
+ m_pd3dDevice->SetFVF( D3DFVF_FONT2DVERTEX );
+ m_pd3dDevice->SetPixelShader( NULL );
+ m_pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(FONT2DVERTEX) );
+
+ // Set filter states
+ if( dwFlags & D3DFONT_FILTERED )
+ {
+ m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
+ m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
+ }
+
+ // Center the text block in the viewport
+ if( dwFlags & D3DFONT_CENTERED_X )
+ {
+ D3DVIEWPORT9 vp;
+ m_pd3dDevice->GetViewport( &vp );
+ const TCHAR* strTextTmp = strText;
+ float xFinal = 0.0f;
+
+ while( *strTextTmp )
+ {
+ TCHAR c = *strTextTmp++;
+
+ if( c == _T('\n') )
+ break; // Isn't supported.
+ if( (c-32) < 0 || (c-32) >= 128-32 )
+ continue;
+
+ FLOAT tx1 = m_fTexCoords[c-32][0];
+ FLOAT tx2 = m_fTexCoords[c-32][2];
+
+ FLOAT w = (tx2-tx1) * m_dwTexWidth / m_fTextScale;
+
+ xFinal += w - (2 * m_dwSpacing);
+ }
+
+ sx = (vp.Width-xFinal)/2.0f;
+ }
+ if( dwFlags & D3DFONT_CENTERED_Y )
+ {
+ D3DVIEWPORT9 vp;
+ m_pd3dDevice->GetViewport( &vp );
+ float fLineHeight = ((m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight);
+ sy = (vp.Height-fLineHeight)/2;
+ }
+
+ // Adjust for character spacing
+ sx -= m_dwSpacing;
+ FLOAT fStartX = sx;
+
+ // Fill vertex buffer
+ FONT2DVERTEX* pVertices = NULL;
+ DWORD dwNumTriangles = 0;
+ m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
+
+ while( *strText )
+ {
+ TCHAR c = *strText++;
+
+ if( c == _T('\n') )
+ {
+ sx = fStartX;
+ sy += (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight;
+ }
+
+ if( (c-32) < 0 || (c-32) >= 128-32 )
+ continue;
+
+ FLOAT tx1 = m_fTexCoords[c-32][0];
+ FLOAT ty1 = m_fTexCoords[c-32][1];
+ FLOAT tx2 = m_fTexCoords[c-32][2];
+ FLOAT ty2 = m_fTexCoords[c-32][3];
+
+ FLOAT w = (tx2-tx1) * m_dwTexWidth / m_fTextScale;
+ FLOAT h = (ty2-ty1) * m_dwTexHeight / m_fTextScale;
+
+ if( c != _T(' ') )
+ {
+ *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx1, ty2 );
+ *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 );
+ *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 );
+ *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+0-0.5f,0.9f,1.0f), dwColor, tx2, ty1 );
+ *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 );
+ *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 );
+ dwNumTriangles += 2;
+
+ if( dwNumTriangles*3 > (MAX_NUM_VERTICES-6) )
+ {
+ // Unlock, render, and relock the vertex buffer
+ m_pVB->Unlock();
+ m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
+ pVertices = NULL;
+ m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
+ dwNumTriangles = 0L;
+ }
+ }
+
+ sx += w - (2 * m_dwSpacing);
+ }
+
+ // Unlock and render the vertex buffer
+ m_pVB->Unlock();
+ if( dwNumTriangles > 0 )
+ m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
+
+ // Restore the modified renderstates
+ m_pStateBlockSaved->Apply();
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: Render3DText()
+// Desc: Renders 3D text
+//-----------------------------------------------------------------------------
+HRESULT CD3DFont::Render3DText( const TCHAR* strText, DWORD dwFlags )
+{
+ if( m_pd3dDevice == NULL )
+ return E_FAIL;
+
+ // Setup renderstate
+ m_pStateBlockSaved->Capture();
+ m_pStateBlockDrawText->Apply();
+ m_pd3dDevice->SetFVF( D3DFVF_FONT3DVERTEX );
+ m_pd3dDevice->SetPixelShader( NULL );
+ m_pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(FONT3DVERTEX) );
+
+ // Set filter states
+ if( dwFlags & D3DFONT_FILTERED )
+ {
+ m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
+ m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
+ }
+
+ // Position for each text element
+ FLOAT x = 0.0f;
+ FLOAT y = 0.0f;
+
+ // Center the text block at the origin (not the viewport)
+ if( dwFlags & D3DFONT_CENTERED_X )
+ {
+ SIZE sz;
+ GetTextExtent( strText, &sz );
+ x = -(((FLOAT)sz.cx)/10.0f)/2.0f;
+ }
+ if( dwFlags & D3DFONT_CENTERED_Y )
+ {
+ SIZE sz;
+ GetTextExtent( strText, &sz );
+ y = -(((FLOAT)sz.cy)/10.0f)/2.0f;
+ }
+
+ // Turn off culling for two-sided text
+ if( dwFlags & D3DFONT_TWOSIDED )
+ m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
+
+ // Adjust for character spacing
+ x -= m_dwSpacing / 10.0f;
+ FLOAT fStartX = x;
+ TCHAR c;
+
+ // Fill vertex buffer
+ FONT3DVERTEX* pVertices;
+ DWORD dwNumTriangles = 0L;
+ m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
+
+ while( (c = *strText++) != 0 )
+ {
+ if( c == '\n' )
+ {
+ x = fStartX;
+ y -= (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight/10.0f;
+ }
+
+ if( (c-32) < 0 || (c-32) >= 128-32 )
+ continue;
+
+ FLOAT tx1 = m_fTexCoords[c-32][0];
+ FLOAT ty1 = m_fTexCoords[c-32][1];
+ FLOAT tx2 = m_fTexCoords[c-32][2];
+ FLOAT ty2 = m_fTexCoords[c-32][3];
+
+ FLOAT w = (tx2-tx1) * m_dwTexWidth / ( 10.0f * m_fTextScale );
+ FLOAT h = (ty2-ty1) * m_dwTexHeight / ( 10.0f * m_fTextScale );
+
+ if( c != _T(' ') )
+ {
+ *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0,y+0,0), D3DXVECTOR3(0,0,-1), tx1, ty2 );
+ *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0,y+h,0), D3DXVECTOR3(0,0,-1), tx1, ty1 );
+ *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w,y+0,0), D3DXVECTOR3(0,0,-1), tx2, ty2 );
+ *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w,y+h,0), D3DXVECTOR3(0,0,-1), tx2, ty1 );
+ *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w,y+0,0), D3DXVECTOR3(0,0,-1), tx2, ty2 );
+ *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0,y+h,0), D3DXVECTOR3(0,0,-1), tx1, ty1 );
+ dwNumTriangles += 2;
+
+ if( dwNumTriangles*3 > (MAX_NUM_VERTICES-6) )
+ {
+ // Unlock, render, and relock the vertex buffer
+ m_pVB->Unlock();
+ m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
+ m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
+ dwNumTriangles = 0L;
+ }
+ }
+
+ x += w - (2 * m_dwSpacing) / 10.0f;
+ }
+
+ // Unlock and render the vertex buffer
+ m_pVB->Unlock();
+ if( dwNumTriangles > 0 )
+ m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
+
+ // Restore the modified renderstates
+ m_pStateBlockSaved->Apply();
+
+ return S_OK;
+}
+
+
+
+
diff --git a/src/apps/mplayerc/D3DFont.h b/src/apps/mplayerc/D3DFont.h
new file mode 100644
index 000000000..751181959
--- /dev/null
+++ b/src/apps/mplayerc/D3DFont.h
@@ -0,0 +1,58 @@
+#pragma once
+
+// Font creation flags
+#define D3DFONT_BOLD 0x0001
+#define D3DFONT_ITALIC 0x0002
+#define D3DFONT_ZENABLE 0x0004
+
+// Font rendering flags
+#define D3DFONT_CENTERED_X 0x0001
+#define D3DFONT_CENTERED_Y 0x0002
+#define D3DFONT_TWOSIDED 0x0004
+#define D3DFONT_FILTERED 0x0008
+
+
+class CD3DFont
+{
+ TCHAR m_strFontName[80]; // Font properties
+ DWORD m_dwFontHeight;
+ DWORD m_dwFontFlags;
+
+ LPDIRECT3DDEVICE9 m_pd3dDevice; // A D3DDevice used for rendering
+ LPDIRECT3DTEXTURE9 m_pTexture; // The d3d texture for this font
+ LPDIRECT3DVERTEXBUFFER9 m_pVB; // VertexBuffer for rendering text
+ DWORD m_dwTexWidth; // Texture dimensions
+ DWORD m_dwTexHeight;
+ FLOAT m_fTextScale;
+ FLOAT m_fTexCoords[128-32][4];
+ DWORD m_dwSpacing; // Character pixel spacing per side
+
+ // Stateblocks for setting and restoring render states
+ LPDIRECT3DSTATEBLOCK9 m_pStateBlockSaved;
+ LPDIRECT3DSTATEBLOCK9 m_pStateBlockDrawText;
+
+ HRESULT CreateGDIFont( HDC hDC, HFONT* pFont );
+ HRESULT PaintAlphabet( HDC hDC, BOOL bMeasureOnly=FALSE );
+
+public:
+ // 2D and 3D text drawing functions
+ HRESULT DrawText( FLOAT x, FLOAT y, DWORD dwColor,
+ const TCHAR* strText, DWORD dwFlags=0L );
+ HRESULT DrawTextScaled( FLOAT x, FLOAT y, FLOAT z,
+ FLOAT fXScale, FLOAT fYScale, DWORD dwColor,
+ const TCHAR* strText, DWORD dwFlags=0L );
+ HRESULT Render3DText( const TCHAR* strText, DWORD dwFlags=0L );
+
+ // Function to get extent of text
+ HRESULT GetTextExtent( const TCHAR* strText, SIZE* pSize );
+
+ // Initializing and destroying device-dependent objects
+ HRESULT InitDeviceObjects( IDirect3DDevice9* pd3dDevice );
+ HRESULT RestoreDeviceObjects();
+ HRESULT InvalidateDeviceObjects();
+ HRESULT DeleteDeviceObjects();
+
+ // Constructor / destructor
+ CD3DFont( const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L );
+ ~CD3DFont();
+};
diff --git a/src/apps/mplayerc/DX7AllocatorPresenter.cpp b/src/apps/mplayerc/DX7AllocatorPresenter.cpp
new file mode 100644
index 000000000..9b57feee0
--- /dev/null
+++ b/src/apps/mplayerc/DX7AllocatorPresenter.cpp
@@ -0,0 +1,1321 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include <atlbase.h>
+#include <atlcoll.h>
+#include "..\..\DSUtil\DSUtil.h"
+
+#include <initguid.h>
+#include "DX7AllocatorPresenter.h"
+#include <ddraw.h>
+#include <d3d.h>
+#include "..\..\SubPic\DX7SubPic.h"
+#include "..\..\..\include\RealMedia\pntypes.h"
+#include "..\..\..\include\RealMedia\pnwintyp.h"
+#include "..\..\..\include\RealMedia\pncom.h"
+#include "..\..\..\include\RealMedia\rmavsurf.h"
+#include "IQTVideoSurface.h"
+
+#include "IPinHook.h"
+
+bool IsVMR7InGraph(IFilterGraph* pFG)
+{
+ BeginEnumFilters(pFG, pEF, pBF)
+ if(CComQIPtr<IVMRWindowlessControl>(pBF)) return(true);
+ EndEnumFilters
+ return(false);
+}
+
+namespace DSObjects
+{
+
+class CDX7AllocatorPresenter
+ : public ISubPicAllocatorPresenterImpl
+{
+protected:
+ CSize m_ScreenSize;
+
+ CComPtr<IDirectDraw7> m_pDD;
+ CComQIPtr<IDirect3D7, &IID_IDirect3D7> m_pD3D;
+ CComPtr<IDirect3DDevice7> m_pD3DDev;
+
+ CComPtr<IDirectDrawSurface7> m_pPrimary, m_pBackBuffer;
+ CComPtr<IDirectDrawSurface7> m_pVideoTexture, m_pVideoSurface;
+
+ virtual HRESULT CreateDevice();
+ virtual HRESULT AllocSurfaces();
+ virtual void DeleteSurfaces();
+
+public:
+ CDX7AllocatorPresenter(HWND hWnd, HRESULT& hr);
+
+ // ISubPicAllocatorPresenter
+ STDMETHODIMP CreateRenderer(IUnknown** ppRenderer);
+ STDMETHODIMP_(bool) Paint(bool fAll);
+ STDMETHODIMP GetDIB(BYTE* lpDib, DWORD* size);
+};
+
+class CVMR7AllocatorPresenter
+ : public CDX7AllocatorPresenter
+ , public IVMRSurfaceAllocator
+ , public IVMRImagePresenter
+ , public IVMRWindowlessControl
+{
+ CComPtr<IVMRSurfaceAllocatorNotify> m_pIVMRSurfAllocNotify;
+ CComPtr<IVMRSurfaceAllocator> m_pSA;
+
+ HRESULT CreateDevice();
+ void DeleteSurfaces();
+
+ bool m_fUseInternalTimer;
+
+public:
+ CVMR7AllocatorPresenter(HWND hWnd, HRESULT& hr);
+
+ DECLARE_IUNKNOWN
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ // ISubPicAllocatorPresenter
+ STDMETHODIMP CreateRenderer(IUnknown** ppRenderer);
+ STDMETHODIMP_(void) SetTime(REFERENCE_TIME rtNow);
+
+ // IVMRSurfaceAllocator
+ STDMETHODIMP AllocateSurface(DWORD_PTR dwUserID, VMRALLOCATIONINFO* lpAllocInfo, DWORD* lpdwBuffer, LPDIRECTDRAWSURFACE7* lplpSurface);
+ STDMETHODIMP FreeSurface(DWORD_PTR dwUserID);
+ STDMETHODIMP PrepareSurface(DWORD_PTR dwUserID, IDirectDrawSurface7* lpSurface, DWORD dwSurfaceFlags);
+ STDMETHODIMP AdviseNotify(IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify);
+
+ // IVMRImagePresenter
+ STDMETHODIMP StartPresenting(DWORD_PTR dwUserID);
+ STDMETHODIMP StopPresenting(DWORD_PTR dwUserID);
+ STDMETHODIMP PresentImage(DWORD_PTR dwUserID, VMRPRESENTATIONINFO* lpPresInfo);
+
+ // IVMRWindowlessControl
+ STDMETHODIMP GetNativeVideoSize(LONG* lpWidth, LONG* lpHeight, LONG* lpARWidth, LONG* lpARHeight);
+ STDMETHODIMP GetMinIdealVideoSize(LONG* lpWidth, LONG* lpHeight);
+ STDMETHODIMP GetMaxIdealVideoSize(LONG* lpWidth, LONG* lpHeight);
+ STDMETHODIMP SetVideoPosition(const LPRECT lpSRCRect, const LPRECT lpDSTRect);
+ STDMETHODIMP GetVideoPosition(LPRECT lpSRCRect, LPRECT lpDSTRect);
+ STDMETHODIMP GetAspectRatioMode(DWORD* lpAspectRatioMode);
+ STDMETHODIMP SetAspectRatioMode(DWORD AspectRatioMode);
+ STDMETHODIMP SetVideoClippingWindow(HWND hwnd);
+ STDMETHODIMP RepaintVideo(HWND hwnd, HDC hdc);
+ STDMETHODIMP DisplayModeChanged();
+ STDMETHODIMP GetCurrentImage(BYTE** lpDib);
+ STDMETHODIMP SetBorderColor(COLORREF Clr);
+ STDMETHODIMP GetBorderColor(COLORREF* lpClr);
+ STDMETHODIMP SetColorKey(COLORREF Clr);
+ STDMETHODIMP GetColorKey(COLORREF* lpClr);
+};
+
+class CRM7AllocatorPresenter
+ : public CDX7AllocatorPresenter
+ , public IRMAVideoSurface
+{
+ CComPtr<IDirectDrawSurface7> m_pVideoSurfaceOff;
+ CComPtr<IDirectDrawSurface7> m_pVideoSurfaceYUY2;
+
+ RMABitmapInfoHeader m_bitmapInfo;
+ RMABitmapInfoHeader m_lastBitmapInfo;
+
+protected:
+ HRESULT AllocSurfaces();
+ void DeleteSurfaces();
+
+public:
+ CRM7AllocatorPresenter(HWND hWnd, HRESULT& hr);
+
+ DECLARE_IUNKNOWN
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ // IRMAVideoSurface
+ STDMETHODIMP Blt(UCHAR* pImageData, RMABitmapInfoHeader* pBitmapInfo, REF(PNxRect) inDestRect, REF(PNxRect) inSrcRect);
+ STDMETHODIMP BeginOptimizedBlt(RMABitmapInfoHeader* pBitmapInfo);
+ STDMETHODIMP OptimizedBlt(UCHAR* pImageBits, REF(PNxRect) rDestRect, REF(PNxRect) rSrcRect);
+ STDMETHODIMP EndOptimizedBlt();
+ STDMETHODIMP GetOptimizedFormat(REF(RMA_COMPRESSION_TYPE) ulType);
+ STDMETHODIMP GetPreferredFormat(REF(RMA_COMPRESSION_TYPE) ulType);
+};
+
+class CQT7AllocatorPresenter
+ : public CDX7AllocatorPresenter
+ , public IQTVideoSurface
+{
+ CComPtr<IDirectDrawSurface7> m_pVideoSurfaceOff;
+
+protected:
+ HRESULT AllocSurfaces();
+ void DeleteSurfaces();
+
+public:
+ CQT7AllocatorPresenter(HWND hWnd, HRESULT& hr);
+
+ DECLARE_IUNKNOWN
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ // IQTVideoSurface
+ STDMETHODIMP BeginBlt(const BITMAP& bm);
+ STDMETHODIMP DoBlt(const BITMAP& bm);
+};
+
+}
+using namespace DSObjects;
+
+//
+
+HRESULT CreateAP7(const CLSID& clsid, HWND hWnd, ISubPicAllocatorPresenter** ppAP)
+{
+ CheckPointer(ppAP, E_POINTER);
+
+ *ppAP = NULL;
+
+ HRESULT hr;
+ if(clsid == CLSID_VMR7AllocatorPresenter && !(*ppAP = new CVMR7AllocatorPresenter(hWnd, hr))
+ || clsid == CLSID_RM7AllocatorPresenter && !(*ppAP = new CRM7AllocatorPresenter(hWnd, hr))
+ || clsid == CLSID_QT7AllocatorPresenter && !(*ppAP = new CQT7AllocatorPresenter(hWnd, hr)))
+ return E_OUTOFMEMORY;
+
+ if(*ppAP == NULL)
+ return E_FAIL;
+
+ (*ppAP)->AddRef();
+
+ if(FAILED(hr))
+ {
+ (*ppAP)->Release();
+ *ppAP = NULL;
+ }
+
+ return hr;
+}
+
+//
+
+static HRESULT TextureBlt(CComPtr<IDirect3DDevice7> pD3DDev, CComPtr<IDirectDrawSurface7> pTexture, Vector dst[4], CRect src)
+{
+ if(!pTexture)
+ return E_POINTER;
+
+ HRESULT hr;
+
+ do
+ {
+ DDSURFACEDESC2 ddsd;
+ INITDDSTRUCT(ddsd);
+ if(FAILED(hr = pTexture->GetSurfaceDesc(&ddsd)))
+ break;
+
+ float w = (float)ddsd.dwWidth;
+ float h = (float)ddsd.dwHeight;
+
+ struct
+ {
+ float x, y, z, rhw;
+ float tu, tv;
+ }
+ pVertices[] =
+ {
+ {(float)dst[0].x, (float)dst[0].y, (float)dst[0].z, 1.0f/(float)dst[0].z, (float)src.left / w, (float)src.top / h},
+ {(float)dst[1].x, (float)dst[1].y, (float)dst[1].z, 1.0f/(float)dst[1].z, (float)src.right / w, (float)src.top / h},
+ {(float)dst[2].x, (float)dst[2].y, (float)dst[2].z, 1.0f/(float)dst[2].z, (float)src.left / w, (float)src.bottom / h},
+ {(float)dst[3].x, (float)dst[3].y, (float)dst[3].z, 1.0f/(float)dst[3].z, (float)src.right / w, (float)src.bottom / h},
+ };
+
+ for(int i = 0; i < countof(pVertices); i++)
+ {
+ pVertices[i].x -= 0.5;
+ pVertices[i].y -= 0.5;
+ }
+
+ hr = pD3DDev->SetTexture(0, pTexture);
+
+ pD3DDev->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
+ pD3DDev->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE);
+ pD3DDev->SetRenderState(D3DRENDERSTATE_BLENDENABLE, FALSE);
+ pD3DDev->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
+
+ pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR);
+ pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR);
+ pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_LINEAR);
+
+ pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);
+
+ //
+
+ if(FAILED(hr = pD3DDev->BeginScene()))
+ break;
+
+ hr = pD3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP,
+ D3DFVF_XYZRHW | D3DFVF_TEX1,
+ pVertices, 4, D3DDP_WAIT);
+ pD3DDev->EndScene();
+
+ //
+
+ pD3DDev->SetTexture(0, NULL);
+
+ return S_OK;
+ }
+ while(0);
+
+ return E_FAIL;
+}
+
+//
+// CDX7AllocatorPresenter
+//
+
+CDX7AllocatorPresenter::CDX7AllocatorPresenter(HWND hWnd, HRESULT& hr)
+ : ISubPicAllocatorPresenterImpl(hWnd, hr)
+ , m_ScreenSize(0, 0)
+{
+ if(FAILED(hr)) return;
+
+ if(FAILED(hr = DirectDrawCreateEx(NULL, (VOID**)&m_pDD, IID_IDirectDraw7, NULL))
+ || FAILED(hr = m_pDD->SetCooperativeLevel(AfxGetMainWnd()->GetSafeHwnd(), DDSCL_NORMAL)))
+ return;
+
+ if(!(m_pD3D = m_pDD)) {hr = E_NOINTERFACE; return;}
+
+ hr = CreateDevice();
+}
+
+HRESULT CDX7AllocatorPresenter::CreateDevice()
+{
+ m_pD3DDev = NULL;
+
+ m_pPrimary = NULL;
+ m_pBackBuffer = NULL;
+
+ DDSURFACEDESC2 ddsd;
+ INITDDSTRUCT(ddsd);
+ if(FAILED(m_pDD->GetDisplayMode(&ddsd))
+ || ddsd.ddpfPixelFormat.dwRGBBitCount <= 8)
+ return DDERR_INVALIDMODE;
+
+ m_ScreenSize.SetSize(ddsd.dwWidth, ddsd.dwHeight);
+
+ HRESULT hr;
+
+ // m_pPrimary
+
+ INITDDSTRUCT(ddsd);
+ ddsd.dwFlags = DDSD_CAPS;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ if(FAILED(hr = m_pDD->CreateSurface(&ddsd, &m_pPrimary, NULL)))
+ return hr;
+
+ CComPtr<IDirectDrawClipper> pcClipper;
+ if(FAILED(hr = m_pDD->CreateClipper(0, &pcClipper, NULL)))
+ return hr;
+ pcClipper->SetHWnd(0, m_hWnd);
+ m_pPrimary->SetClipper(pcClipper);
+
+ // m_pBackBuffer
+
+ INITDDSTRUCT(ddsd);
+ ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ ddsd.ddsCaps.dwCaps = /*DDSCAPS_OFFSCREENPLAIN |*/ DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE;
+ ddsd.dwWidth = m_ScreenSize.cx;
+ ddsd.dwHeight = m_ScreenSize.cy;
+ if(FAILED(hr = m_pDD->CreateSurface(&ddsd, &m_pBackBuffer, NULL)))
+ return hr;
+
+ pcClipper = NULL;
+ if(FAILED(hr = m_pDD->CreateClipper(0, &pcClipper, NULL)))
+ return hr;
+ BYTE rgnDataBuffer[1024];
+ HRGN hrgn = CreateRectRgn(0, 0, ddsd.dwWidth, ddsd.dwHeight);
+ GetRegionData(hrgn, sizeof(rgnDataBuffer), (RGNDATA*)rgnDataBuffer);
+ DeleteObject(hrgn);
+ pcClipper->SetClipList((RGNDATA*)rgnDataBuffer, 0);
+ m_pBackBuffer->SetClipper(pcClipper);
+
+ // m_pD3DDev
+
+ if(FAILED(hr = m_pD3D->CreateDevice(IID_IDirect3DHALDevice, m_pBackBuffer, &m_pD3DDev))) // this seems to fail if the desktop size is too large (width or height >2048)
+ return hr;
+
+ //
+
+ CComPtr<ISubPicProvider> pSubPicProvider;
+ if(m_pSubPicQueue) m_pSubPicQueue->GetSubPicProvider(&pSubPicProvider);
+
+ CSize size;
+ switch(AfxGetAppSettings().nSPCMaxRes)
+ {
+ case 0: default: size = m_ScreenSize; break;
+ case 1: size.SetSize(1024, 768); break;
+ case 2: size.SetSize(800, 600); break;
+ case 3: size.SetSize(640, 480); break;
+ case 4: size.SetSize(512, 384); break;
+ case 5: size.SetSize(384, 288); break;
+ }
+
+ if(m_pAllocator)
+ {
+ m_pAllocator->ChangeDevice(m_pD3DDev);
+ }
+ else
+ {
+ m_pAllocator = new CDX7SubPicAllocator(m_pD3DDev, size, AfxGetAppSettings().fSPCPow2Tex);
+ if(!m_pAllocator || FAILED(hr))
+ return E_FAIL;
+ }
+
+ hr = S_OK;
+ m_pSubPicQueue = AfxGetAppSettings().nSPCSize > 0
+ ? (ISubPicQueue*)new CSubPicQueue(AfxGetAppSettings().nSPCSize, m_pAllocator, &hr)
+ : (ISubPicQueue*)new CSubPicQueueNoThread(m_pAllocator, &hr);
+ if(!m_pSubPicQueue || FAILED(hr))
+ return E_FAIL;
+
+ if(pSubPicProvider) m_pSubPicQueue->SetSubPicProvider(pSubPicProvider);
+
+ return S_OK;
+}
+
+HRESULT CDX7AllocatorPresenter::AllocSurfaces()
+{
+ CAutoLock cAutoLock(this);
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_pVideoTexture = NULL;
+ m_pVideoSurface = NULL;
+
+ DDSURFACEDESC2 ddsd;
+ INITDDSTRUCT(ddsd);
+ ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
+ ddsd.dwWidth = m_NativeVideoSize.cx;
+ ddsd.dwHeight = m_NativeVideoSize.cy;
+ ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+ ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
+ ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
+ ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
+ ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
+ ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FF;
+
+ if(s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE2D || s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE3D)
+ {
+ ddsd.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
+// ddsd.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS;
+// ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xFF000000;
+ }
+
+ HRESULT hr = m_pDD->CreateSurface(&ddsd, &m_pVideoSurface, NULL);
+ if(FAILED(hr))
+ {
+ // FIXME: eh, dx9 has no problem creating a 32bpp surface under a 16bpp desktop, but dx7 fails here (textures are ok)
+ DDSURFACEDESC2 ddsd2;
+ INITDDSTRUCT(ddsd2);
+ if(!(s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE2D || s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE3D)
+ && SUCCEEDED(m_pDD->GetDisplayMode(&ddsd2))
+ && ddsd2.ddpfPixelFormat.dwRGBBitCount == 16)
+ {
+ ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
+ ddsd.ddpfPixelFormat.dwRBitMask = 0x0000F800;
+ ddsd.ddpfPixelFormat.dwGBitMask = 0x000007E0;
+ ddsd.ddpfPixelFormat.dwBBitMask = 0x0000001F;
+ hr = m_pDD->CreateSurface(&ddsd, &m_pVideoSurface, NULL);
+ }
+
+ if(FAILED(hr))
+ return hr;
+ }
+
+ if(s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE3D)
+ m_pVideoTexture = m_pVideoSurface;
+
+ DDBLTFX fx;
+ INITDDSTRUCT(fx);
+ fx.dwFillColor = 0;
+ hr = m_pVideoSurface->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
+
+ return S_OK;
+}
+
+void CDX7AllocatorPresenter::DeleteSurfaces()
+{
+ CAutoLock cAutoLock(this);
+
+ m_pVideoTexture = NULL;
+ m_pVideoSurface = NULL;
+}
+
+// ISubPicAllocatorPresenter
+
+STDMETHODIMP CDX7AllocatorPresenter::CreateRenderer(IUnknown** ppRenderer)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP_(bool) CDX7AllocatorPresenter::Paint(bool fAll)
+{
+ CAutoLock cAutoLock(this);
+
+ if(m_WindowRect.right <= m_WindowRect.left || m_WindowRect.bottom <= m_WindowRect.top
+ || m_NativeVideoSize.cx <= 0 || m_NativeVideoSize.cy <= 0
+ || !m_pPrimary || !m_pBackBuffer || !m_pVideoSurface)
+ return(false);
+
+ HRESULT hr;
+
+ CRect rSrcVid(CPoint(0, 0), m_NativeVideoSize);
+ CRect rDstVid(m_VideoRect);
+
+ CRect rSrcPri(CPoint(0, 0), m_WindowRect.Size());
+ CRect rDstPri(m_WindowRect);
+ MapWindowRect(m_hWnd, HWND_DESKTOP, &rDstPri);
+
+ if(fAll)
+ {
+ // clear the backbuffer
+
+ CRect rl(0, 0, rDstVid.left, rSrcPri.bottom);
+ CRect rr(rDstVid.right, 0, rSrcPri.right, rSrcPri.bottom);
+ CRect rt(0, 0, rSrcPri.right, rDstVid.top);
+ CRect rb(0, rDstVid.bottom, rSrcPri.right, rSrcPri.bottom);
+
+ DDBLTFX fx;
+ INITDDSTRUCT(fx);
+ fx.dwFillColor = 0;
+ hr = m_pBackBuffer->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
+
+ // paint the video on the backbuffer
+
+ if(!rDstVid.IsRectEmpty())
+ {
+ if(m_pVideoTexture)
+ {
+ Vector v[4];
+ Transform(rDstVid, v);
+ hr = TextureBlt(m_pD3DDev, m_pVideoTexture, v, rSrcVid);
+ }
+ else
+ {
+ hr = m_pBackBuffer->Blt(rDstVid, m_pVideoSurface, rSrcVid, DDBLT_WAIT, NULL);
+ }
+ }
+
+ // paint the text on the backbuffer
+
+ AlphaBltSubPic(rSrcPri.Size());
+ }
+
+ // wait vsync
+
+ m_pDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
+
+ // blt to the primary surface
+
+ hr = m_pPrimary->Blt(rDstPri, m_pBackBuffer, rSrcPri, DDBLT_WAIT, NULL);
+
+ if(hr == DDERR_SURFACELOST)
+ {
+ HRESULT hr = DDERR_WRONGMODE; // m_pDD->TestCooperativeLevel();
+
+ if(hr == DDERR_WRONGMODE)
+ {
+ DeleteSurfaces();
+ if(SUCCEEDED(CreateDevice()) || FAILED(hr = AllocSurfaces()))
+ return(true);
+ }
+
+ hr = S_OK;
+ }
+
+ return(true);
+}
+
+STDMETHODIMP CDX7AllocatorPresenter::GetDIB(BYTE* lpDib, DWORD* size)
+{
+ CheckPointer(size, E_POINTER);
+
+ HRESULT hr;
+
+ DDSURFACEDESC2 ddsd;
+ INITDDSTRUCT(ddsd);
+ if(FAILED(m_pVideoSurface->GetSurfaceDesc(&ddsd)))
+ return E_FAIL;
+
+ if(ddsd.ddpfPixelFormat.dwRGBBitCount != 16 && ddsd.ddpfPixelFormat.dwRGBBitCount != 32)
+ return E_FAIL;
+
+ DWORD required = sizeof(BITMAPINFOHEADER) + (ddsd.dwWidth*ddsd.dwHeight*32>>3);
+ if(!lpDib) {*size = required; return S_OK;}
+ if(*size < required) return E_OUTOFMEMORY;
+ *size = required;
+
+ INITDDSTRUCT(ddsd);
+ if(FAILED(hr = m_pVideoSurface->Lock(NULL, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_READONLY|DDLOCK_NOSYSLOCK, NULL)))
+ {
+ // TODO
+ return hr;
+ }
+
+ BITMAPINFOHEADER* bih = (BITMAPINFOHEADER*)lpDib;
+ memset(bih, 0, sizeof(BITMAPINFOHEADER));
+ bih->biSize = sizeof(BITMAPINFOHEADER);
+ bih->biWidth = ddsd.dwWidth;
+ bih->biHeight = ddsd.dwHeight;
+ bih->biBitCount = 32;
+ bih->biPlanes = 1;
+ bih->biSizeImage = bih->biWidth*bih->biHeight*bih->biBitCount>>3;
+
+ BitBltFromRGBToRGB(
+ bih->biWidth, bih->biHeight,
+ (BYTE*)(bih + 1), bih->biWidth*bih->biBitCount>>3, bih->biBitCount,
+ (BYTE*)ddsd.lpSurface + ddsd.lPitch*(ddsd.dwHeight-1), -(int)ddsd.lPitch, ddsd.ddpfPixelFormat.dwRGBBitCount);
+
+ m_pVideoSurface->Unlock(NULL);
+
+/*
+ BitBltFromRGBToRGB(
+ w, h,
+ (BYTE*)ddsd.lpSurface, ddsd.lPitch, ddsd.ddpfPixelFormat.dwRGBBitCount,
+ (BYTE*)bm.bmBits, bm.bmWidthBytes, bm.bmBitsPixel);
+ m_pVideoSurfaceOff->Unlock(NULL);
+ fOk = true;
+ }
+*/
+
+ return S_OK;
+}
+
+//
+// CVMR7AllocatorPresenter
+//
+
+#define MY_USER_ID 0x6ABE51
+
+CVMR7AllocatorPresenter::CVMR7AllocatorPresenter(HWND hWnd, HRESULT& hr)
+ : CDX7AllocatorPresenter(hWnd, hr)
+ , m_fUseInternalTimer(false)
+{
+ if(FAILED(hr))
+ return;
+
+ if(FAILED(hr = m_pSA.CoCreateInstance(CLSID_AllocPresenter)))
+ {
+ hr = E_FAIL;
+ return;
+ }
+}
+
+STDMETHODIMP CVMR7AllocatorPresenter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ CheckPointer(ppv, E_POINTER);
+
+ return
+ QI(IVMRSurfaceAllocator)
+ QI(IVMRImagePresenter)
+ QI(IVMRWindowlessControl)
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+HRESULT CVMR7AllocatorPresenter::CreateDevice()
+{
+ HRESULT hr = __super::CreateDevice();
+ if(FAILED(hr)) return hr;
+
+ if(m_pIVMRSurfAllocNotify)
+ {
+ HMONITOR hMonitor = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
+ if(FAILED(hr = m_pIVMRSurfAllocNotify->ChangeDDrawDevice(m_pDD, hMonitor)))
+ return(false);
+ }
+
+ return hr;
+}
+
+void CVMR7AllocatorPresenter::DeleteSurfaces()
+{
+ CAutoLock cAutoLock(this);
+
+ m_pSA->FreeSurface(MY_USER_ID);
+
+ __super::DeleteSurfaces();
+}
+
+// ISubPicAllocatorPresenter
+
+STDMETHODIMP CVMR7AllocatorPresenter::CreateRenderer(IUnknown** ppRenderer)
+{
+ CheckPointer(ppRenderer, E_POINTER);
+
+ *ppRenderer = NULL;
+
+ HRESULT hr;
+
+ do
+ {
+ CComPtr<IBaseFilter> pBF;
+
+ if(FAILED(hr = pBF.CoCreateInstance(CLSID_VideoMixingRenderer)))
+ break;
+
+ CComQIPtr<IVMRFilterConfig> pConfig = pBF;
+ if(!pConfig)
+ break;
+
+ if(FAILED(hr = pConfig->SetRenderingMode(VMRMode_Renderless)))
+ break;
+
+ CComQIPtr<IVMRSurfaceAllocatorNotify> pSAN = pBF;
+ if(!pSAN)
+ break;
+
+ if(FAILED(hr = pSAN->AdviseSurfaceAllocator(MY_USER_ID, static_cast<IVMRSurfaceAllocator*>(this)))
+ || FAILED(hr = AdviseNotify(pSAN)))
+ break;
+
+ CComPtr<IPin> pPin = GetFirstPin(pBF);
+ CComQIPtr<IMemInputPin> pMemInputPin = pPin;
+ m_fUseInternalTimer = HookNewSegmentAndReceive((IPinC*)(IPin*)pPin, (IMemInputPinC*)(IMemInputPin*)pMemInputPin);
+
+ *ppRenderer = (IUnknown*)pBF.Detach();
+
+ return S_OK;
+ }
+ while(0);
+
+ return E_FAIL;
+}
+
+STDMETHODIMP_(void) CVMR7AllocatorPresenter::SetTime(REFERENCE_TIME rtNow)
+{
+ __super::SetTime(rtNow);
+ m_fUseInternalTimer = false;
+}
+
+// IVMRSurfaceAllocator
+
+STDMETHODIMP CVMR7AllocatorPresenter::AllocateSurface(DWORD_PTR dwUserID, VMRALLOCATIONINFO* lpAllocInfo, DWORD* lpdwBuffer, LPDIRECTDRAWSURFACE7* lplpSurface)
+{
+ if(!lpAllocInfo || !lpdwBuffer || !lplpSurface)
+ return E_POINTER;
+
+ if(!m_pIVMRSurfAllocNotify)
+ return E_FAIL;
+
+ HRESULT hr;
+
+ DeleteSurfaces();
+
+ // HACK: yv12 will fail to blt onto the backbuffer anyway, but if we first
+ // allocate it and then let our FreeSurface callback call m_pSA->FreeSurface,
+ // then that might stall for about 30 seconds because of some unknown buggy code
+ // behind <ddraw surface>->Release()
+
+ if(lpAllocInfo->lpHdr->biBitCount < 16)
+ return E_FAIL;
+
+ hr = m_pSA->AllocateSurface(dwUserID, lpAllocInfo, lpdwBuffer, lplpSurface);
+ if(FAILED(hr))
+ return hr;
+
+ m_NativeVideoSize = CSize(abs(lpAllocInfo->lpHdr->biWidth), abs(lpAllocInfo->lpHdr->biHeight));
+ m_AspectRatio = m_NativeVideoSize;
+ int arx = lpAllocInfo->szAspectRatio.cx, ary = lpAllocInfo->szAspectRatio.cy;
+ if(arx > 0 && ary > 0) m_AspectRatio.SetSize(arx, ary);
+
+ if(FAILED(hr = AllocSurfaces()))
+ return hr;
+
+ // test if the colorspace is acceptable
+ if(FAILED(hr = m_pVideoSurface->Blt(NULL, *lplpSurface, NULL, DDBLT_WAIT, NULL)))
+ {
+ DeleteSurfaces();
+ return hr;
+ }
+
+ DDBLTFX fx;
+ INITDDSTRUCT(fx);
+ fx.dwFillColor = 0;
+ m_pVideoSurface->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
+
+ return hr;
+}
+
+STDMETHODIMP CVMR7AllocatorPresenter::FreeSurface(DWORD_PTR dwUserID)
+{
+ DeleteSurfaces();
+ return S_OK;
+}
+
+STDMETHODIMP CVMR7AllocatorPresenter::PrepareSurface(DWORD_PTR dwUserID, IDirectDrawSurface7* lpSurface, DWORD dwSurfaceFlags)
+{
+ if(!lpSurface)
+ return E_POINTER;
+
+ // FIXME: sometimes the msmpeg4/divx3/wmv decoder wants to reuse our
+ // surface (expects it to point to the same mem every time), and to avoid
+ // problems we can't call m_pSA->PrepareSurface (flips? clears?).
+ return S_OK;
+/*
+ return m_pSA->PrepareSurface(dwUserID, lpSurface, dwSurfaceFlags);
+*/
+}
+
+STDMETHODIMP CVMR7AllocatorPresenter::AdviseNotify(IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify)
+{
+ CAutoLock cAutoLock(this);
+
+ m_pIVMRSurfAllocNotify = lpIVMRSurfAllocNotify;
+
+ HRESULT hr;
+ HMONITOR hMonitor = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
+ if(FAILED(hr = m_pIVMRSurfAllocNotify->SetDDrawDevice(m_pDD, hMonitor)))
+ return hr;
+
+ return m_pSA->AdviseNotify(lpIVMRSurfAllocNotify);
+}
+
+// IVMRImagePresenter
+
+STDMETHODIMP CVMR7AllocatorPresenter::StartPresenting(DWORD_PTR dwUserID)
+{
+ CAutoLock cAutoLock(this);
+
+ ASSERT(m_pD3DDev);
+
+ return m_pD3DDev ? S_OK : E_FAIL;
+}
+
+STDMETHODIMP CVMR7AllocatorPresenter::StopPresenting(DWORD_PTR dwUserID)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CVMR7AllocatorPresenter::PresentImage(DWORD_PTR dwUserID, VMRPRESENTATIONINFO* lpPresInfo)
+{
+ HRESULT hr;
+
+ {
+ if(!lpPresInfo || !lpPresInfo->lpSurf)
+ return E_POINTER;
+
+ CAutoLock cAutoLock(this);
+
+ hr = m_pVideoSurface->Blt(NULL, lpPresInfo->lpSurf, NULL, DDBLT_WAIT, NULL);
+
+ if(lpPresInfo->rtEnd > lpPresInfo->rtStart)
+ {
+ REFERENCE_TIME rtTimePerFrame = lpPresInfo->rtEnd - lpPresInfo->rtStart;
+ m_fps = 10000000.0 / rtTimePerFrame;
+
+ if(m_pSubPicQueue)
+ {
+ m_pSubPicQueue->SetFPS(m_fps);
+
+ if(m_fUseInternalTimer)
+ {
+ __super::SetTime(g_tSegmentStart + g_tSampleStart);
+ }
+ }
+ }
+
+ CSize VideoSize = m_NativeVideoSize;
+ int arx = lpPresInfo->szAspectRatio.cx, ary = lpPresInfo->szAspectRatio.cy;
+ if(arx > 0 && ary > 0) VideoSize.cx = VideoSize.cy*arx/ary;
+ if(VideoSize != GetVideoSize())
+ {
+ m_AspectRatio.SetSize(arx, ary);
+ AfxGetApp()->m_pMainWnd->PostMessage(WM_REARRANGERENDERLESS);
+ }
+
+ Paint(true);
+
+ hr = S_OK;
+ }
+
+ return S_OK;
+}
+
+// IVMRWindowlessControl
+//
+// It is only implemented (partially) for the dvd navigator's
+// menu handling, which needs to know a few things about the
+// location of our window.
+
+STDMETHODIMP CVMR7AllocatorPresenter::GetNativeVideoSize(LONG* lpWidth, LONG* lpHeight, LONG* lpARWidth, LONG* lpARHeight)
+{
+ CSize vs = m_NativeVideoSize, ar = m_AspectRatio;
+ // DVD Nav. bug workaround fix
+ vs.cx = vs.cy * ar.cx / ar.cy;
+ if(lpWidth) *lpWidth = vs.cx;
+ if(lpHeight) *lpHeight = vs.cy;
+ if(lpARWidth) *lpARWidth = ar.cx;
+ if(lpARHeight) *lpARHeight = ar.cy;
+ return S_OK;
+}
+
+STDMETHODIMP CVMR7AllocatorPresenter::GetMinIdealVideoSize(LONG* lpWidth, LONG* lpHeight) {return E_NOTIMPL;}
+STDMETHODIMP CVMR7AllocatorPresenter::GetMaxIdealVideoSize(LONG* lpWidth, LONG* lpHeight) {return E_NOTIMPL;}
+STDMETHODIMP CVMR7AllocatorPresenter::SetVideoPosition(const LPRECT lpSRCRect, const LPRECT lpDSTRect) {return E_NOTIMPL;} // we have our own method for this
+
+STDMETHODIMP CVMR7AllocatorPresenter::GetVideoPosition(LPRECT lpSRCRect, LPRECT lpDSTRect)
+{
+ CopyRect(lpSRCRect, CRect(CPoint(0, 0), m_NativeVideoSize));
+ CopyRect(lpDSTRect, &m_VideoRect);
+ // DVD Nav. bug workaround fix
+ GetNativeVideoSize(&lpSRCRect->right, &lpSRCRect->bottom, NULL, NULL);
+ return S_OK;
+}
+
+STDMETHODIMP CVMR7AllocatorPresenter::GetAspectRatioMode(DWORD* lpAspectRatioMode)
+{
+ if(lpAspectRatioMode) *lpAspectRatioMode = AM_ARMODE_STRETCHED;
+ return S_OK;
+}
+
+STDMETHODIMP CVMR7AllocatorPresenter::SetAspectRatioMode(DWORD AspectRatioMode) {return E_NOTIMPL;}
+STDMETHODIMP CVMR7AllocatorPresenter::SetVideoClippingWindow(HWND hwnd) {return E_NOTIMPL;}
+STDMETHODIMP CVMR7AllocatorPresenter::RepaintVideo(HWND hwnd, HDC hdc) {return E_NOTIMPL;}
+STDMETHODIMP CVMR7AllocatorPresenter::DisplayModeChanged() {return E_NOTIMPL;}
+STDMETHODIMP CVMR7AllocatorPresenter::GetCurrentImage(BYTE** lpDib) {return E_NOTIMPL;}
+STDMETHODIMP CVMR7AllocatorPresenter::SetBorderColor(COLORREF Clr) {return E_NOTIMPL;}
+
+STDMETHODIMP CVMR7AllocatorPresenter::GetBorderColor(COLORREF* lpClr)
+{
+ if(lpClr) *lpClr = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CVMR7AllocatorPresenter::SetColorKey(COLORREF Clr) {return E_NOTIMPL;}
+STDMETHODIMP CVMR7AllocatorPresenter::GetColorKey(COLORREF* lpClr) {return E_NOTIMPL;}
+
+//
+
+static HRESULT AllocDX7Surface(IDirectDraw7* pDD, CSize size, DWORD compression, int bpp, IDirectDrawSurface7** pSurface)
+{
+ if(!pDD || !pSurface || size.cx <= 0 || size.cy <= 0)
+ return E_POINTER;
+
+ *pSurface = NULL;
+
+ DDSURFACEDESC2 ddsd;
+ INITDDSTRUCT(ddsd);
+ ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY;
+ ddsd.dwWidth = size.cx;
+ ddsd.dwHeight = size.cy;
+ ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+
+ if(compression >= 0x1000)
+ {
+ ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+ ddsd.ddpfPixelFormat.dwFourCC = compression;
+ }
+ else if((compression == 0 || compression == 3) && (bpp == 15 || bpp == 16 || bpp == 24 || bpp == 32))
+ {
+ ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
+ ddsd.ddpfPixelFormat.dwRGBBitCount = max(bpp, 16);
+ ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = (bpp == 16) ? 0x0000 : (bpp == 15) ? 0x8000 : 0xFF000000;
+ ddsd.ddpfPixelFormat.dwRBitMask = (bpp == 16) ? 0xf800 : (bpp == 15) ? 0x7c00 : 0x00FF0000;
+ ddsd.ddpfPixelFormat.dwGBitMask = (bpp == 16) ? 0x07e0 : (bpp == 15) ? 0x03e0 : 0x0000FF00;
+ ddsd.ddpfPixelFormat.dwBBitMask = (bpp == 16) ? 0x001F : (bpp == 15) ? 0x001F : 0x000000FF;
+ }
+
+ return pDD->CreateSurface(&ddsd, pSurface, NULL);
+}
+
+//
+// CRM7AllocatorPresenter
+//
+
+CRM7AllocatorPresenter::CRM7AllocatorPresenter(HWND hWnd, HRESULT& hr)
+ : CDX7AllocatorPresenter(hWnd, hr)
+{
+}
+
+STDMETHODIMP CRM7AllocatorPresenter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ CheckPointer(ppv, E_POINTER);
+
+ return
+ QI2(IRMAVideoSurface)
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+HRESULT CRM7AllocatorPresenter::AllocSurfaces()
+{
+ CAutoLock cAutoLock(this);
+
+ m_pVideoSurfaceOff = NULL;
+ m_pVideoSurfaceYUY2 = NULL;
+
+ DDSURFACEDESC2 ddsd;
+ DDBLTFX fx;
+
+ INITDDSTRUCT(ddsd);
+ ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ ddsd.dwWidth = m_NativeVideoSize.cx;
+ ddsd.dwHeight = m_NativeVideoSize.cy;
+ ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+ ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
+ ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
+ ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xFF000000;
+ ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
+ ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
+ ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FF;
+
+ HRESULT hr = m_pDD->CreateSurface(&ddsd, &m_pVideoSurfaceOff, NULL);
+ if(FAILED(hr)) return E_FAIL;
+
+ INITDDSTRUCT(fx);
+ fx.dwFillColor = 0;
+ m_pVideoSurfaceOff->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
+
+ INITDDSTRUCT(ddsd);
+ ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ ddsd.dwWidth = m_NativeVideoSize.cx;
+ ddsd.dwHeight = m_NativeVideoSize.cy;
+ ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+ ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+ ddsd.ddpfPixelFormat.dwYUVBitCount = 16;
+ ddsd.ddpfPixelFormat.dwFourCC = '2YUY';
+
+ hr = m_pDD->CreateSurface(&ddsd, &m_pVideoSurfaceYUY2, NULL);
+
+ if(FAILED(m_pVideoSurfaceOff->Blt(NULL, m_pVideoSurfaceYUY2, NULL, DDBLT_WAIT, NULL)))
+ m_pVideoSurfaceYUY2 = NULL;
+
+ if(m_pVideoSurfaceYUY2)
+ {
+ INITDDSTRUCT(fx);
+ fx.dwFillColor = 0x80108010;
+ m_pVideoSurfaceYUY2->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
+ }
+
+ return __super::AllocSurfaces();
+}
+
+void CRM7AllocatorPresenter::DeleteSurfaces()
+{
+ CAutoLock cAutoLock(this);
+
+ m_pVideoSurfaceOff = NULL;
+ m_pVideoSurfaceYUY2 = NULL;
+
+ __super::DeleteSurfaces();
+}
+
+// IRMAVideoSurface
+
+STDMETHODIMP CRM7AllocatorPresenter::Blt(UCHAR* pImageData, RMABitmapInfoHeader* pBitmapInfo, REF(PNxRect) inDestRect, REF(PNxRect) inSrcRect)
+{
+ if(!m_pVideoSurface || !m_pVideoSurfaceOff)
+ return E_FAIL;
+
+ bool fRGB = false;
+ bool fYUY2 = false;
+
+ CRect src((RECT*)&inSrcRect), dst((RECT*)&inDestRect), src2(CPoint(0,0), src.Size());
+ if(src.Width() > dst.Width() || src.Height() > dst.Height())
+ return E_FAIL;
+
+ DDSURFACEDESC2 ddsd;
+
+ if(pBitmapInfo->biCompression == '024I')
+ {
+ DWORD pitch = pBitmapInfo->biWidth;
+ DWORD size = pitch*abs(pBitmapInfo->biHeight);
+
+ BYTE* y = pImageData + src.top*pitch + src.left;
+ BYTE* u = pImageData + size + src.top*(pitch/2) + src.left/2;
+ BYTE* v = pImageData + size + size/4 + src.top*(pitch/2) + src.left/2;
+
+ if(m_pVideoSurfaceYUY2)
+ {
+ INITDDSTRUCT(ddsd);
+ if(SUCCEEDED(m_pVideoSurfaceYUY2->Lock(src2, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, NULL)))
+ {
+ BitBltFromI420ToYUY2(src.Width(), src.Height(), (BYTE*)ddsd.lpSurface, ddsd.lPitch, y, u, v, pitch);
+ m_pVideoSurfaceYUY2->Unlock(src2);
+ fYUY2 = true;
+ }
+ }
+ else
+ {
+ INITDDSTRUCT(ddsd);
+ if(SUCCEEDED(m_pVideoSurfaceOff->Lock(src2, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, NULL)))
+ {
+ BitBltFromI420ToRGB(src.Width(), src.Height(), (BYTE*)ddsd.lpSurface, ddsd.lPitch, ddsd.ddpfPixelFormat.dwRGBBitCount, y, u, v, pitch);
+ m_pVideoSurfaceOff->Unlock(src2);
+ fRGB = true;
+ }
+ }
+ }
+ else if(pBitmapInfo->biCompression == '2YUY')
+ {
+ DWORD w = pBitmapInfo->biWidth;
+ DWORD h = abs(pBitmapInfo->biHeight);
+ DWORD pitch = pBitmapInfo->biWidth*2;
+
+ BYTE* yvyu = pImageData + src.top*pitch + src.left*2;
+
+ if(m_pVideoSurfaceYUY2)
+ {
+ INITDDSTRUCT(ddsd);
+ if(SUCCEEDED(m_pVideoSurfaceYUY2->Lock(src2, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, NULL)))
+ {
+ BitBltFromYUY2ToYUY2(src.Width(), src.Height(), (BYTE*)ddsd.lpSurface, ddsd.lPitch, yvyu, pitch);
+ m_pVideoSurfaceYUY2->Unlock(src2);
+ fYUY2 = true;
+ }
+ }
+ else
+ {
+ INITDDSTRUCT(ddsd);
+ if(SUCCEEDED(m_pVideoSurfaceOff->Lock(src2, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, NULL)))
+ {
+ BitBltFromYUY2ToRGB(src.Width(), src.Height(), (BYTE*)ddsd.lpSurface, ddsd.lPitch, ddsd.ddpfPixelFormat.dwRGBBitCount, yvyu, pitch);
+ m_pVideoSurfaceOff->Unlock(src2);
+ fRGB = true;
+ }
+ }
+ }
+ else if(pBitmapInfo->biCompression == 0 || pBitmapInfo->biCompression == 3
+ || pBitmapInfo->biCompression == 'BGRA')
+ {
+ DWORD w = pBitmapInfo->biWidth;
+ DWORD h = abs(pBitmapInfo->biHeight);
+ DWORD pitch = pBitmapInfo->biWidth*pBitmapInfo->biBitCount>>3;
+
+ BYTE* rgb = pImageData + src.top*pitch + src.left*(pBitmapInfo->biBitCount>>3);
+
+ INITDDSTRUCT(ddsd);
+ if(SUCCEEDED(m_pVideoSurfaceOff->Lock(src2, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, NULL)))
+ {
+ BYTE* lpSurface = (BYTE*)ddsd.lpSurface;
+ if(pBitmapInfo->biHeight > 0) {lpSurface += ddsd.lPitch*(src.Height()-1); ddsd.lPitch = -ddsd.lPitch;}
+ BitBltFromRGBToRGB(src.Width(), src.Height(), lpSurface, ddsd.lPitch, ddsd.ddpfPixelFormat.dwRGBBitCount, rgb, pitch, pBitmapInfo->biBitCount);
+ fRGB = true;
+ m_pVideoSurfaceOff->Unlock(src2);
+ }
+ }
+
+ if(!fRGB && !fYUY2)
+ {
+ DDBLTFX fx;
+ INITDDSTRUCT(fx);
+ fx.dwFillColor = 0;
+ m_pVideoSurfaceOff->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
+
+ HDC hDC;
+ if(SUCCEEDED(m_pVideoSurfaceOff->GetDC(&hDC)))
+ {
+ CString str;
+ str.Format(_T("Sorry, this format is not supported"));
+
+ SetBkColor(hDC, 0);
+ SetTextColor(hDC, 0x404040);
+ TextOut(hDC, 10, 10, str, str.GetLength());
+
+ m_pVideoSurfaceOff->ReleaseDC(hDC);
+
+ fRGB = true;
+ }
+ }
+
+
+ HRESULT hr;
+
+ if(fRGB)
+ hr = m_pVideoSurface->Blt(dst, m_pVideoSurfaceOff, src2, DDBLT_WAIT, NULL);
+ if(fYUY2)
+ hr = m_pVideoSurface->Blt(dst, m_pVideoSurfaceYUY2, src2, DDBLT_WAIT, NULL);
+
+ Paint(true);
+
+ return PNR_OK;
+}
+
+STDMETHODIMP CRM7AllocatorPresenter::BeginOptimizedBlt(RMABitmapInfoHeader* pBitmapInfo)
+{
+ CAutoLock cAutoLock(this);
+ DeleteSurfaces();
+ m_NativeVideoSize = m_AspectRatio = CSize(pBitmapInfo->biWidth, abs(pBitmapInfo->biHeight));
+ if(FAILED(AllocSurfaces())) return E_FAIL;
+ return PNR_NOTIMPL;
+}
+
+STDMETHODIMP CRM7AllocatorPresenter::OptimizedBlt(UCHAR* pImageBits, REF(PNxRect) rDestRect, REF(PNxRect) rSrcRect)
+{
+ return PNR_NOTIMPL;
+}
+
+STDMETHODIMP CRM7AllocatorPresenter::EndOptimizedBlt()
+{
+ return PNR_NOTIMPL;
+}
+
+STDMETHODIMP CRM7AllocatorPresenter::GetOptimizedFormat(REF(RMA_COMPRESSION_TYPE) ulType)
+{
+ return PNR_NOTIMPL;
+}
+
+STDMETHODIMP CRM7AllocatorPresenter::GetPreferredFormat(REF(RMA_COMPRESSION_TYPE) ulType)
+{
+ ulType = RMA_I420;
+ return PNR_OK;
+}
+
+//
+// CQT7AllocatorPresenter
+//
+
+CQT7AllocatorPresenter::CQT7AllocatorPresenter(HWND hWnd, HRESULT& hr)
+ : CDX7AllocatorPresenter(hWnd, hr)
+{
+}
+
+STDMETHODIMP CQT7AllocatorPresenter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ CheckPointer(ppv, E_POINTER);
+
+ return
+ QI(IQTVideoSurface)
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+HRESULT CQT7AllocatorPresenter::AllocSurfaces()
+{
+ CAutoLock cAutoLock(this);
+
+ m_pVideoSurfaceOff = NULL;
+
+ DDSURFACEDESC2 ddsd;
+ INITDDSTRUCT(ddsd);
+ ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ ddsd.dwWidth = m_NativeVideoSize.cx;
+ ddsd.dwHeight = m_NativeVideoSize.cy;
+ ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+ ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
+ ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
+ ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xFF000000;
+ ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
+ ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
+ ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FF;
+
+ HRESULT hr = m_pDD->CreateSurface(&ddsd, &m_pVideoSurfaceOff, NULL);
+ if(FAILED(hr)) return E_FAIL;
+
+ DDBLTFX fx;
+ INITDDSTRUCT(fx);
+ fx.dwFillColor = 0;
+ m_pVideoSurfaceOff->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
+
+ return __super::AllocSurfaces();
+}
+
+void CQT7AllocatorPresenter::DeleteSurfaces()
+{
+ CAutoLock cAutoLock(this);
+
+ m_pVideoSurfaceOff = NULL;
+
+ __super::DeleteSurfaces();
+}
+
+// IQTVideoSurface
+
+STDMETHODIMP CQT7AllocatorPresenter::BeginBlt(const BITMAP& bm)
+{
+ CAutoLock cAutoLock(this);
+
+ DeleteSurfaces();
+
+ m_NativeVideoSize = m_AspectRatio = CSize(bm.bmWidth, abs(bm.bmHeight));
+
+ HRESULT hr;
+ if(FAILED(hr = AllocSurfaces()))
+ return hr;
+
+ return S_OK;
+}
+
+STDMETHODIMP CQT7AllocatorPresenter::DoBlt(const BITMAP& bm)
+{
+ if(!m_pVideoSurface || !m_pVideoSurfaceOff)
+ return E_FAIL;
+
+ bool fOk = false;
+
+ DDSURFACEDESC2 ddsd;
+ INITDDSTRUCT(ddsd);
+ if(FAILED(m_pVideoSurfaceOff->GetSurfaceDesc(&ddsd)))
+ return E_FAIL;
+
+ int w = bm.bmWidth;
+ int h = abs(bm.bmHeight);
+ int bpp = bm.bmBitsPixel;
+
+ if((bpp == 16 || bpp == 24 || bpp == 32) && w == ddsd.dwWidth && h == ddsd.dwHeight)
+ {
+ INITDDSTRUCT(ddsd);
+ if(SUCCEEDED(m_pVideoSurfaceOff->Lock(NULL, &ddsd, DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY, NULL)))
+ {
+ BitBltFromRGBToRGB(
+ w, h,
+ (BYTE*)ddsd.lpSurface, ddsd.lPitch, ddsd.ddpfPixelFormat.dwRGBBitCount,
+ (BYTE*)bm.bmBits, bm.bmWidthBytes, bm.bmBitsPixel);
+ m_pVideoSurfaceOff->Unlock(NULL);
+ fOk = true;
+ }
+ }
+
+ if(!fOk)
+ {
+ DDBLTFX fx;
+ INITDDSTRUCT(fx);
+ fx.dwFillColor = 0;
+ m_pVideoSurfaceOff->Blt(NULL, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
+
+ HDC hDC;
+ if(SUCCEEDED(m_pVideoSurfaceOff->GetDC(&hDC)))
+ {
+ CString str;
+ str.Format(_T("Sorry, this format is not supported"));
+
+ SetBkColor(hDC, 0);
+ SetTextColor(hDC, 0x404040);
+ TextOut(hDC, 10, 10, str, str.GetLength());
+
+ m_pVideoSurfaceOff->ReleaseDC(hDC);
+
+ }
+ }
+
+ m_pVideoSurface->Blt(NULL, m_pVideoSurfaceOff, NULL, DDBLT_WAIT, NULL);
+
+ Paint(true);
+
+ return S_OK;
+}
diff --git a/src/apps/mplayerc/DX7AllocatorPresenter.h b/src/apps/mplayerc/DX7AllocatorPresenter.h
new file mode 100644
index 000000000..f209a257d
--- /dev/null
+++ b/src/apps/mplayerc/DX7AllocatorPresenter.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "..\..\SubPic\ISubPic.h"
+
+// {495CF191-810D-44c7-92C5-E7D46AE00F44}
+DEFINE_GUID(CLSID_VMR7AllocatorPresenter,
+0x495cf191, 0x810d, 0x44c7, 0x92, 0xc5, 0xe7, 0xd4, 0x6a, 0xe0, 0xf, 0x44);
+
+// {97B3462E-1752-4dfb-A038-271060BC7A94}
+DEFINE_GUID(CLSID_RM7AllocatorPresenter,
+0x97b3462e, 0x1752, 0x4dfb, 0xa0, 0x38, 0x27, 0x10, 0x60, 0xbc, 0x7a, 0x94);
+
+// {36CC5A71-441C-462a-9D10-48A19485938D}
+DEFINE_GUID(CLSID_QT7AllocatorPresenter,
+0x36cc5a71, 0x441c, 0x462a, 0x9d, 0x10, 0x48, 0xa1, 0x94, 0x85, 0x93, 0x8d);
+
+extern HRESULT CreateAP7(const CLSID& clsid, HWND hWnd, ISubPicAllocatorPresenter** ppAP);
+
+extern bool IsVMR7InGraph(IFilterGraph* pFG);
diff --git a/src/apps/mplayerc/DX9AllocatorPresenter.cpp b/src/apps/mplayerc/DX9AllocatorPresenter.cpp
new file mode 100644
index 000000000..3daf39d25
--- /dev/null
+++ b/src/apps/mplayerc/DX9AllocatorPresenter.cpp
@@ -0,0 +1,2447 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include <atlbase.h>
+#include <atlcoll.h>
+#include "..\..\DSUtil\DSUtil.h"
+
+#include <Videoacc.h>
+
+#include <initguid.h>
+#include "DX9AllocatorPresenter.h"
+#include <d3d9.h>
+#include <d3dx9.h>
+#include <Vmr9.h>
+#include "..\..\SubPic\DX9SubPic.h"
+#include "..\..\..\include\RealMedia\pntypes.h"
+#include "..\..\..\include\RealMedia\pnwintyp.h"
+#include "..\..\..\include\RealMedia\pncom.h"
+#include "..\..\..\include\RealMedia\rmavsurf.h"
+#include "IQTVideoSurface.h"
+#include "..\..\..\include\moreuuids.h"
+
+#include "MacrovisionKicker.h"
+#include "IPinHook.h"
+
+#include "PixelShaderCompiler.h"
+#include "MainFrm.h"
+
+#define VMRBITMAP_UPDATE 0x80000000
+
+bool IsVMR9InGraph(IFilterGraph* pFG)
+{
+ BeginEnumFilters(pFG, pEF, pBF)
+ if(CComQIPtr<IVMRWindowlessControl9>(pBF)) return(true);
+ EndEnumFilters
+ return(false);
+}
+
+namespace DSObjects
+{
+
+class CDX9AllocatorPresenter
+ : public ISubPicAllocatorPresenterImpl
+{
+protected:
+ CSize m_ScreenSize;
+ bool m_fVMRSyncFix;
+
+ CComPtr<IDirect3D9> m_pD3D;
+ CComPtr<IDirect3DDevice9> m_pD3DDev;
+ CComPtr<IDirect3DTexture9> m_pVideoTexture[3];
+ CComPtr<IDirect3DSurface9> m_pVideoSurface[3];
+ CComPtr<IDirect3DTexture9> m_pOSDTexture;
+ CComPtr<IDirect3DSurface9> m_pOSDSurface;
+ CInterfaceList<IDirect3DPixelShader9> m_pPixelShaders;
+ CComPtr<IDirect3DPixelShader9> m_pResizerPixelShader[3]; // bl, bc1, bc2
+ CComPtr<IDirect3DTexture9> m_pResizerBicubic1stPass;
+ D3DTEXTUREFILTERTYPE m_filter;
+ D3DCAPS9 m_caps;
+
+ CAutoPtr<CPixelShaderCompiler> m_pPSC;
+
+ virtual HRESULT CreateDevice();
+ virtual HRESULT AllocSurfaces();
+ virtual void DeleteSurfaces();
+
+ UINT GetAdapter(IDirect3D9 *pD3D);
+
+ float m_bicubicA;
+ HRESULT InitResizers(float bicubicA);
+
+ HRESULT TextureCopy(CComPtr<IDirect3DTexture9> pTexture);
+ HRESULT TextureResize(CComPtr<IDirect3DTexture9> pTexture, Vector dst[4], D3DTEXTUREFILTERTYPE filter);
+ HRESULT TextureResizeBilinear(CComPtr<IDirect3DTexture9> pTexture, Vector dst[4]);
+ HRESULT TextureResizeBicubic1pass(CComPtr<IDirect3DTexture9> pTexture, Vector dst[4]);
+ HRESULT TextureResizeBicubic2pass(CComPtr<IDirect3DTexture9> pTexture, Vector dst[4]);
+
+ // Casimir666
+ int m_nTearingPos;
+ VMR9AlphaBitmap m_VMR9AlphaBitmap;
+ HRESULT AlphaBlt(RECT* pSrc, RECT* pDst, CComPtr<IDirect3DTexture9> pTexture);
+
+public:
+ CDX9AllocatorPresenter(HWND hWnd, HRESULT& hr);
+ ~CDX9AllocatorPresenter();
+
+ // ISubPicAllocatorPresenter
+ STDMETHODIMP CreateRenderer(IUnknown** ppRenderer);
+ STDMETHODIMP_(bool) Paint(bool fAll);
+ STDMETHODIMP GetDIB(BYTE* lpDib, DWORD* size);
+ STDMETHODIMP SetPixelShader(LPCSTR pSrcData, LPCSTR pTarget);
+};
+
+class CVMR9AllocatorPresenter
+ : public CDX9AllocatorPresenter
+ , public IVMRSurfaceAllocator9
+ , public IVMRImagePresenter9
+ , public IVMRWindowlessControl9
+{
+protected:
+ CComPtr<IVMRSurfaceAllocatorNotify9> m_pIVMRSurfAllocNotify;
+ CInterfaceArray<IDirect3DSurface9> m_pSurfaces;
+
+ HRESULT CreateDevice();
+ void DeleteSurfaces();
+
+ bool m_fUseInternalTimer;
+ REFERENCE_TIME m_rtPrevStart;
+
+public:
+ CVMR9AllocatorPresenter(HWND hWnd, HRESULT& hr);
+
+ DECLARE_IUNKNOWN
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ // ISubPicAllocatorPresenter
+ STDMETHODIMP CreateRenderer(IUnknown** ppRenderer);
+ STDMETHODIMP_(void) SetTime(REFERENCE_TIME rtNow);
+
+ // IVMRSurfaceAllocator9
+ STDMETHODIMP InitializeDevice(DWORD_PTR dwUserID, VMR9AllocationInfo* lpAllocInfo, DWORD* lpNumBuffers);
+ STDMETHODIMP TerminateDevice(DWORD_PTR dwID);
+ STDMETHODIMP GetSurface(DWORD_PTR dwUserID, DWORD SurfaceIndex, DWORD SurfaceFlags, IDirect3DSurface9** lplpSurface);
+ STDMETHODIMP AdviseNotify(IVMRSurfaceAllocatorNotify9* lpIVMRSurfAllocNotify);
+
+ // IVMRImagePresenter9
+ STDMETHODIMP StartPresenting(DWORD_PTR dwUserID);
+ STDMETHODIMP StopPresenting(DWORD_PTR dwUserID);
+ STDMETHODIMP PresentImage(DWORD_PTR dwUserID, VMR9PresentationInfo* lpPresInfo);
+
+ // IVMRWindowlessControl9
+ STDMETHODIMP GetNativeVideoSize(LONG* lpWidth, LONG* lpHeight, LONG* lpARWidth, LONG* lpARHeight);
+ STDMETHODIMP GetMinIdealVideoSize(LONG* lpWidth, LONG* lpHeight);
+ STDMETHODIMP GetMaxIdealVideoSize(LONG* lpWidth, LONG* lpHeight);
+ STDMETHODIMP SetVideoPosition(const LPRECT lpSRCRect, const LPRECT lpDSTRect);
+ STDMETHODIMP GetVideoPosition(LPRECT lpSRCRect, LPRECT lpDSTRect);
+ STDMETHODIMP GetAspectRatioMode(DWORD* lpAspectRatioMode);
+ STDMETHODIMP SetAspectRatioMode(DWORD AspectRatioMode);
+ STDMETHODIMP SetVideoClippingWindow(HWND hwnd);
+ STDMETHODIMP RepaintVideo(HWND hwnd, HDC hdc);
+ STDMETHODIMP DisplayModeChanged();
+ STDMETHODIMP GetCurrentImage(BYTE** lpDib);
+ STDMETHODIMP SetBorderColor(COLORREF Clr);
+ STDMETHODIMP GetBorderColor(COLORREF* lpClr);
+};
+
+class CRM9AllocatorPresenter
+ : public CDX9AllocatorPresenter
+ , public IRMAVideoSurface
+{
+ CComPtr<IDirect3DSurface9> m_pVideoSurfaceOff;
+ CComPtr<IDirect3DSurface9> m_pVideoSurfaceYUY2;
+
+ RMABitmapInfoHeader m_bitmapInfo;
+ RMABitmapInfoHeader m_lastBitmapInfo;
+
+protected:
+ HRESULT AllocSurfaces();
+ void DeleteSurfaces();
+
+public:
+ CRM9AllocatorPresenter(HWND hWnd, HRESULT& hr);
+
+ DECLARE_IUNKNOWN
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ // IRMAVideoSurface
+ STDMETHODIMP Blt(UCHAR* pImageData, RMABitmapInfoHeader* pBitmapInfo, REF(PNxRect) inDestRect, REF(PNxRect) inSrcRect);
+ STDMETHODIMP BeginOptimizedBlt(RMABitmapInfoHeader* pBitmapInfo);
+ STDMETHODIMP OptimizedBlt(UCHAR* pImageBits, REF(PNxRect) rDestRect, REF(PNxRect) rSrcRect);
+ STDMETHODIMP EndOptimizedBlt();
+ STDMETHODIMP GetOptimizedFormat(REF(RMA_COMPRESSION_TYPE) ulType);
+ STDMETHODIMP GetPreferredFormat(REF(RMA_COMPRESSION_TYPE) ulType);
+};
+
+class CQT9AllocatorPresenter
+ : public CDX9AllocatorPresenter
+ , public IQTVideoSurface
+{
+ CComPtr<IDirect3DSurface9> m_pVideoSurfaceOff;
+
+protected:
+ HRESULT AllocSurfaces();
+ void DeleteSurfaces();
+
+public:
+ CQT9AllocatorPresenter(HWND hWnd, HRESULT& hr);
+
+ DECLARE_IUNKNOWN
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ // IQTVideoSurface
+ STDMETHODIMP BeginBlt(const BITMAP& bm);
+ STDMETHODIMP DoBlt(const BITMAP& bm);
+};
+
+class CDXRAllocatorPresenter
+ : public ISubPicAllocatorPresenterImpl
+{
+ class CSubRenderCallback : public CUnknown, public ISubRenderCallback, public CCritSec
+ {
+ CDXRAllocatorPresenter* m_pDXRAP;
+
+ public:
+ CSubRenderCallback(CDXRAllocatorPresenter* pDXRAP)
+ : CUnknown(_T("CSubRender"), NULL)
+ , m_pDXRAP(pDXRAP)
+ {
+ }
+
+ DECLARE_IUNKNOWN
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv)
+ {
+ return
+ QI(ISubRenderCallback)
+ __super::NonDelegatingQueryInterface(riid, ppv);
+ }
+
+ void SetDXRAP(CDXRAllocatorPresenter* pDXRAP)
+ {
+ CAutoLock cAutoLock(this);
+ m_pDXRAP = pDXRAP;
+ }
+
+ // ISubRenderCallback
+
+ STDMETHODIMP SetDevice(IDirect3DDevice9* pD3DDev)
+ {
+ CAutoLock cAutoLock(this);
+ return m_pDXRAP ? m_pDXRAP->SetDevice(pD3DDev) : E_UNEXPECTED;
+ }
+
+ STDMETHODIMP Render(REFERENCE_TIME rtStart, int left, int top, int right, int bottom, int width, int height)
+ {
+ CAutoLock cAutoLock(this);
+ return m_pDXRAP ? m_pDXRAP->Render(rtStart, 0, 0, left, top, right, bottom, width, height) : E_UNEXPECTED;
+ }
+
+ // ISubRendererCallback2
+
+ STDMETHODIMP RenderEx(REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, REFERENCE_TIME AvgTimePerFrame, int left, int top, int right, int bottom, int width, int height)
+ {
+ CAutoLock cAutoLock(this);
+ return m_pDXRAP ? m_pDXRAP->Render(rtStart, rtStop, AvgTimePerFrame, left, top, right, bottom, width, height) : E_UNEXPECTED;
+ }
+ };
+
+ CComPtr<IUnknown> m_pDXR;
+ CComPtr<ISubRenderCallback> m_pSRCB;
+
+public:
+ CDXRAllocatorPresenter(HWND hWnd, HRESULT& hr);
+ virtual ~CDXRAllocatorPresenter();
+
+ DECLARE_IUNKNOWN
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ HRESULT SetDevice(IDirect3DDevice9* pD3DDev);
+ HRESULT Render(
+ REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, REFERENCE_TIME atpf,
+ int left, int top, int bottom, int right, int width, int height);
+
+ // ISubPicAllocatorPresenter
+ STDMETHODIMP CreateRenderer(IUnknown** ppRenderer);
+ STDMETHODIMP_(void) SetPosition(RECT w, RECT v);
+ STDMETHODIMP_(SIZE) GetVideoSize(bool fCorrectAR);
+ STDMETHODIMP_(bool) Paint(bool fAll);
+ STDMETHODIMP GetDIB(BYTE* lpDib, DWORD* size);
+ STDMETHODIMP SetPixelShader(LPCSTR pSrcData, LPCSTR pTarget);
+};
+
+}
+using namespace DSObjects;
+
+//
+
+HRESULT CreateAP9(const CLSID& clsid, HWND hWnd, ISubPicAllocatorPresenter** ppAP)
+{
+ CheckPointer(ppAP, E_POINTER);
+
+ *ppAP = NULL;
+
+ HRESULT hr = E_FAIL;
+ if(clsid == CLSID_VMR9AllocatorPresenter && !(*ppAP = new CVMR9AllocatorPresenter(hWnd, hr))
+ || clsid == CLSID_RM9AllocatorPresenter && !(*ppAP = new CRM9AllocatorPresenter(hWnd, hr))
+ || clsid == CLSID_QT9AllocatorPresenter && !(*ppAP = new CQT9AllocatorPresenter(hWnd, hr))
+ || clsid == CLSID_DXRAllocatorPresenter && !(*ppAP = new CDXRAllocatorPresenter(hWnd, hr)))
+ return E_OUTOFMEMORY;
+
+ if(*ppAP == NULL)
+ return E_FAIL;
+
+ (*ppAP)->AddRef();
+
+ if(FAILED(hr))
+ {
+ (*ppAP)->Release();
+ *ppAP = NULL;
+ }
+
+ return hr;
+}
+
+//
+
+#pragma pack(push, 1)
+template<int texcoords>
+struct MYD3DVERTEX {float x, y, z, rhw; struct {float u, v;} t[texcoords];};
+#pragma pack(pop)
+
+template<int texcoords>
+static void AdjustQuad(MYD3DVERTEX<texcoords>* v, float dx, float dy)
+{
+ float offset = 0.5f;
+
+ for(int i = 0; i < 4; i++)
+ {
+ v[i].x -= offset;
+ v[i].y -= offset;
+
+ for(int j = 0; j < texcoords-1; j++)
+ {
+ v[i].t[j].u -= offset*dx;
+ v[i].t[j].v -= offset*dy;
+ }
+
+ if(texcoords > 1)
+ {
+ v[i].t[texcoords-1].u -= offset;
+ v[i].t[texcoords-1].v -= offset;
+ }
+ }
+}
+
+template<int texcoords>
+static HRESULT TextureBlt(CComPtr<IDirect3DDevice9> pD3DDev, MYD3DVERTEX<texcoords> v[4], D3DTEXTUREFILTERTYPE filter = D3DTEXF_LINEAR)
+{
+ if(!pD3DDev)
+ return E_POINTER;
+
+ DWORD FVF = 0;
+
+ switch(texcoords)
+ {
+ case 1: FVF = D3DFVF_TEX1; break;
+ case 2: FVF = D3DFVF_TEX2; break;
+ case 3: FVF = D3DFVF_TEX3; break;
+ case 4: FVF = D3DFVF_TEX4; break;
+ case 5: FVF = D3DFVF_TEX5; break;
+ case 6: FVF = D3DFVF_TEX6; break;
+ case 7: FVF = D3DFVF_TEX7; break;
+ case 8: FVF = D3DFVF_TEX8; break;
+ default: return E_FAIL;
+ }
+
+ HRESULT hr;
+
+ do
+ {
+ hr = pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ hr = pD3DDev->SetRenderState(D3DRS_LIGHTING, FALSE);
+ hr = pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE);
+ hr = pD3DDev->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+ hr = pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ hr = pD3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+ hr = pD3DDev->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
+ hr = pD3DDev->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED);
+
+ for(int i = 0; i < texcoords; i++)
+ {
+ hr = pD3DDev->SetSamplerState(i, D3DSAMP_MAGFILTER, filter);
+ hr = pD3DDev->SetSamplerState(i, D3DSAMP_MINFILTER, filter);
+ hr = pD3DDev->SetSamplerState(i, D3DSAMP_MIPFILTER, filter);
+
+ hr = pD3DDev->SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
+ hr = pD3DDev->SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
+ }
+
+ //
+
+ if(FAILED(hr = pD3DDev->BeginScene()))
+ break;
+
+ hr = pD3DDev->SetFVF(D3DFVF_XYZRHW | FVF);
+ // hr = pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(v[0]));
+
+ MYD3DVERTEX<texcoords> tmp = v[2]; v[2] = v[3]; v[3] = tmp;
+ hr = pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, v, sizeof(v[0]));
+
+ hr = pD3DDev->EndScene();
+
+ //
+
+ for(int i = 0; i < texcoords; i++)
+ {
+ pD3DDev->SetTexture(i, NULL);
+ }
+
+ return S_OK;
+ }
+ while(0);
+
+ return E_FAIL;
+}
+
+// CDX9AllocatorPresenter
+
+CDX9AllocatorPresenter::CDX9AllocatorPresenter(HWND hWnd, HRESULT& hr)
+ : ISubPicAllocatorPresenterImpl(hWnd, hr)
+ , m_ScreenSize(0, 0)
+ , m_bicubicA(0)
+ , m_nTearingPos(0)
+{
+ if(FAILED(hr)) return;
+ m_pD3D.Attach(Direct3DCreate9(D3D_SDK_VERSION));
+ if(!m_pD3D) m_pD3D.Attach(Direct3DCreate9(D3D9b_SDK_VERSION));
+ if(!m_pD3D) {hr = E_FAIL; return;}
+
+ ZeroMemory(&m_VMR9AlphaBitmap, sizeof(m_VMR9AlphaBitmap));
+ hr = CreateDevice();
+}
+
+CDX9AllocatorPresenter::~CDX9AllocatorPresenter()
+{
+}
+
+HRESULT CDX9AllocatorPresenter::CreateDevice()
+{
+ m_pPSC.Free();
+ m_pD3DDev = NULL;
+
+ D3DDISPLAYMODE d3ddm;
+ HRESULT hr;
+ ZeroMemory(&d3ddm, sizeof(d3ddm));
+ if(FAILED(m_pD3D->GetAdapterDisplayMode(GetAdapter(m_pD3D), &d3ddm)))
+ return E_UNEXPECTED;
+
+ m_ScreenSize.SetSize(d3ddm.Width, d3ddm.Height);
+
+ D3DPRESENT_PARAMETERS pp;
+ ZeroMemory(&pp, sizeof(pp));
+
+
+ if (AfxGetAppSettings().fD3DFullscreen)
+ {
+ pp.Windowed = false;
+ pp.BackBufferWidth = d3ddm.Width;
+ pp.BackBufferHeight = d3ddm.Height;
+// pp.BackBufferCount = 3;
+ pp.SwapEffect = D3DSWAPEFFECT_COPY;
+ pp.Flags = D3DPRESENTFLAG_VIDEO;
+ pp.BackBufferFormat = d3ddm.Format;
+ pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
+
+ hr = m_pD3D->CreateDevice(
+ GetAdapter(m_pD3D), D3DDEVTYPE_HAL, m_hWnd,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_MULTITHREADED, //D3DCREATE_MANAGED
+ &pp, &m_pD3DDev);
+ ASSERT (SUCCEEDED (hr));
+ }
+ else
+ {
+ pp.Windowed = TRUE;
+ pp.hDeviceWindow = m_hWnd;
+ pp.SwapEffect = D3DSWAPEFFECT_COPY;
+ pp.Flags = D3DPRESENTFLAG_VIDEO;
+ pp.BackBufferWidth = d3ddm.Width;
+ pp.BackBufferHeight = d3ddm.Height;
+ pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
+
+ if(m_fVMRSyncFix = AfxGetMyApp()->m_s.fVMRSyncFix)
+ pp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
+
+ hr = m_pD3D->CreateDevice(
+ GetAdapter(m_pD3D), D3DDEVTYPE_HAL, m_hWnd,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_MULTITHREADED, //D3DCREATE_MANAGED
+ &pp, &m_pD3DDev);
+ }
+/*
+ HRESULT hr = m_pD3D->CreateDevice(
+ m_pD3D->GetAdapterCount()-1, D3DDEVTYPE_REF, m_hWnd,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_MULTITHREADED, //D3DCREATE_MANAGED
+ &pp, &m_pD3DDev);
+*/
+ if(FAILED(hr))
+ return hr;
+
+ m_pPSC.Attach(new CPixelShaderCompiler(m_pD3DDev, true));
+
+ //
+
+ m_filter = D3DTEXF_NONE;
+
+ ZeroMemory(&m_caps, sizeof(m_caps));
+ m_pD3DDev->GetDeviceCaps(&m_caps);
+
+ if((m_caps.StretchRectFilterCaps&D3DPTFILTERCAPS_MINFLINEAR)
+ && (m_caps.StretchRectFilterCaps&D3DPTFILTERCAPS_MAGFLINEAR))
+ m_filter = D3DTEXF_LINEAR;
+
+ //
+
+ m_bicubicA = 0;
+
+ //
+
+ CComPtr<ISubPicProvider> pSubPicProvider;
+ if(m_pSubPicQueue) m_pSubPicQueue->GetSubPicProvider(&pSubPicProvider);
+
+ CSize size;
+ switch(AfxGetAppSettings().nSPCMaxRes)
+ {
+ case 0: default: size = m_ScreenSize; break;
+ case 1: size.SetSize(1024, 768); break;
+ case 2: size.SetSize(800, 600); break;
+ case 3: size.SetSize(640, 480); break;
+ case 4: size.SetSize(512, 384); break;
+ case 5: size.SetSize(384, 288); break;
+ }
+
+ if(m_pAllocator)
+ {
+ m_pAllocator->ChangeDevice(m_pD3DDev);
+ }
+ else
+ {
+ m_pAllocator = new CDX9SubPicAllocator(m_pD3DDev, size, AfxGetAppSettings().fSPCPow2Tex);
+ if(!m_pAllocator)
+ return E_FAIL;
+ }
+
+ hr = S_OK;
+ m_pSubPicQueue = AfxGetAppSettings().nSPCSize > 0
+ ? (ISubPicQueue*)new CSubPicQueue(AfxGetAppSettings().nSPCSize, m_pAllocator, &hr)
+ : (ISubPicQueue*)new CSubPicQueueNoThread(m_pAllocator, &hr);
+ if(!m_pSubPicQueue || FAILED(hr))
+ return E_FAIL;
+
+ if(pSubPicProvider) m_pSubPicQueue->SetSubPicProvider(pSubPicProvider);
+
+ return S_OK;
+}
+
+HRESULT CDX9AllocatorPresenter::AllocSurfaces()
+{
+ CAutoLock cAutoLock(this);
+
+ AppSettings& s = AfxGetAppSettings();
+
+ for(int i = 0; i < countof(m_pVideoTexture); i++)
+ {
+ m_pVideoTexture[i] = NULL;
+ m_pVideoSurface[i] = NULL;
+ }
+
+ m_pResizerBicubic1stPass = NULL;
+
+ HRESULT hr;
+
+ if(s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE2D || s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE3D)
+ {
+ int nTexturesNeeded = s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE3D ? countof(m_pVideoTexture) : 1;
+
+ for(int i = 0; i < nTexturesNeeded; i++)
+ {
+ if(FAILED(hr = m_pD3DDev->CreateTexture(
+ m_NativeVideoSize.cx, m_NativeVideoSize.cy, 1,
+ D3DUSAGE_RENDERTARGET, /*D3DFMT_X8R8G8B8*/D3DFMT_A8R8G8B8,
+ D3DPOOL_DEFAULT, &m_pVideoTexture[i], NULL)))
+ return hr;
+
+ if(FAILED(hr = m_pVideoTexture[i]->GetSurfaceLevel(0, &m_pVideoSurface[i])))
+ return hr;
+ }
+
+ if(s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE2D)
+ {
+ for(int i = 0; i < countof(m_pVideoTexture); i++)
+ {
+ m_pVideoTexture[i] = NULL;
+ }
+ }
+ }
+ else
+ {
+ if(FAILED(hr = m_pD3DDev->CreateOffscreenPlainSurface(
+ m_NativeVideoSize.cx, m_NativeVideoSize.cy,
+ D3DFMT_X8R8G8B8/*D3DFMT_A8R8G8B8*/,
+ D3DPOOL_DEFAULT, &m_pVideoSurface[0], NULL)))
+ return hr;
+ }
+
+ hr = m_pD3DDev->ColorFill(m_pVideoSurface[0], NULL, 0);
+
+ return S_OK;
+}
+
+void CDX9AllocatorPresenter::DeleteSurfaces()
+{
+ CAutoLock cAutoLock(this);
+
+ for(int i = 0; i < countof(m_pVideoTexture); i++)
+ {
+ m_pVideoTexture[i] = NULL;
+ m_pVideoSurface[i] = NULL;
+ }
+}
+
+UINT CDX9AllocatorPresenter::GetAdapter(IDirect3D9* pD3D)
+{
+ if(m_hWnd == NULL || pD3D == NULL)
+ return D3DADAPTER_DEFAULT;
+
+ HMONITOR hMonitor = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
+ if(hMonitor == NULL) return D3DADAPTER_DEFAULT;
+
+ for(UINT adp = 0, num_adp = pD3D->GetAdapterCount(); adp < num_adp; ++adp)
+ {
+ HMONITOR hAdpMon = pD3D->GetAdapterMonitor(adp);
+ if(hAdpMon == hMonitor) return adp;
+ }
+
+ return D3DADAPTER_DEFAULT;
+}
+
+// ISubPicAllocatorPresenter
+
+STDMETHODIMP CDX9AllocatorPresenter::CreateRenderer(IUnknown** ppRenderer)
+{
+ return E_NOTIMPL;
+}
+
+static bool ClipToSurface(IDirect3DSurface9* pSurface, CRect& s, CRect& d)
+{
+ D3DSURFACE_DESC d3dsd;
+ ZeroMemory(&d3dsd, sizeof(d3dsd));
+ if(FAILED(pSurface->GetDesc(&d3dsd)))
+ return(false);
+
+ int w = d3dsd.Width, h = d3dsd.Height;
+ int sw = s.Width(), sh = s.Height();
+ int dw = d.Width(), dh = d.Height();
+
+ if(d.left >= w || d.right < 0 || d.top >= h || d.bottom < 0
+ || sw <= 0 || sh <= 0 || dw <= 0 || dh <= 0)
+ {
+ s.SetRectEmpty();
+ d.SetRectEmpty();
+ return(true);
+ }
+
+ if(d.right > w) {s.right -= (d.right-w)*sw/dw; d.right = w;}
+ if(d.bottom > h) {s.bottom -= (d.bottom-h)*sh/dh; d.bottom = h;}
+ if(d.left < 0) {s.left += (0-d.left)*sw/dw; d.left = 0;}
+ if(d.top < 0) {s.top += (0-d.top)*sh/dh; d.top = 0;}
+
+ return(true);
+}
+
+HRESULT CDX9AllocatorPresenter::InitResizers(float bicubicA)
+{
+ HRESULT hr;
+
+ if(m_pResizerPixelShader[0] && m_bicubicA == 0 && bicubicA == 0
+ || m_pResizerPixelShader[1] && m_pResizerPixelShader[2] && m_bicubicA == bicubicA && m_pResizerBicubic1stPass)
+ return S_OK;
+
+ m_bicubicA = bicubicA;
+ m_pResizerBicubic1stPass = NULL;
+
+ for(int i = 0; i < countof(m_pResizerPixelShader); i++)
+ m_pResizerPixelShader[i] = NULL;
+
+ if(m_caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
+ return E_FAIL;
+
+ LPCSTR pProfile = m_caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) ? "ps_3_0" : "ps_2_0";
+
+ CStringA str;
+ if(!LoadResource(IDF_SHADER_RESIZER, str, _T("FILE")))
+ return E_FAIL;
+
+ CStringA A;
+ A.Format("(%f)", bicubicA);
+ str.Replace("_The_Value_Of_A_Is_Set_Here_", A);
+
+ LPCSTR pEntries[] = {"main_bilinear", "main_bicubic1pass", "main_bicubic2pass"};
+
+ ASSERT(countof(pEntries) == countof(m_pResizerPixelShader));
+
+ for(int i = 0; i < countof(pEntries); i++)
+ {
+ hr = m_pPSC->CompileShader(str, pEntries[i], pProfile, 0, &m_pResizerPixelShader[i]);
+ if(FAILED(hr)) return hr;
+ }
+
+ if(m_bicubicA)
+ {
+ if(FAILED(m_pD3DDev->CreateTexture(
+ min(max(2048, m_ScreenSize.cx), m_caps.MaxTextureWidth), m_NativeVideoSize.cy, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
+ D3DPOOL_DEFAULT, &m_pResizerBicubic1stPass, NULL)))
+ {
+ ASSERT(0);
+ m_pResizerBicubic1stPass = NULL; // will do 1 pass then
+ }
+ }
+
+ return S_OK;
+}
+
+HRESULT CDX9AllocatorPresenter::TextureCopy(CComPtr<IDirect3DTexture9> pTexture)
+{
+ HRESULT hr;
+
+ D3DSURFACE_DESC desc;
+ if(!pTexture || FAILED(pTexture->GetLevelDesc(0, &desc)))
+ return E_FAIL;
+
+ float w = (float)desc.Width;
+ float h = (float)desc.Height;
+
+ MYD3DVERTEX<1> v[] =
+ {
+ {0, 0, 0.5f, 2.0f, 0, 0},
+ {w, 0, 0.5f, 2.0f, 1, 0},
+ {0, h, 0.5f, 2.0f, 0, 1},
+ {w, h, 0.5f, 2.0f, 1, 1},
+ };
+
+ for(int i = 0; i < countof(v); i++)
+ {
+ v[i].x -= 0.5;
+ v[i].y -= 0.5;
+ }
+
+ hr = m_pD3DDev->SetTexture(0, pTexture);
+
+ return TextureBlt(m_pD3DDev, v, D3DTEXF_LINEAR);
+}
+
+HRESULT CDX9AllocatorPresenter::TextureResize(CComPtr<IDirect3DTexture9> pTexture, Vector dst[4], D3DTEXTUREFILTERTYPE filter)
+{
+ HRESULT hr;
+
+ D3DSURFACE_DESC desc;
+ if(!pTexture || FAILED(pTexture->GetLevelDesc(0, &desc)))
+ return E_FAIL;
+
+ float w = (float)desc.Width;
+ float h = (float)desc.Height;
+
+ float dx = 1.0f/w;
+ float dy = 1.0f/h;
+
+ MYD3DVERTEX<1> v[] =
+ {
+ {dst[0].x, dst[0].y, dst[0].z, 1.0f/dst[0].z, 0, 0},
+ {dst[1].x, dst[1].y, dst[1].z, 1.0f/dst[1].z, 1, 0},
+ {dst[2].x, dst[2].y, dst[2].z, 1.0f/dst[2].z, 0, 1},
+ {dst[3].x, dst[3].y, dst[3].z, 1.0f/dst[3].z, 1, 1},
+ };
+
+ AdjustQuad(v, dx, dy);
+
+ hr = m_pD3DDev->SetTexture(0, pTexture);
+
+ hr = m_pD3DDev->SetPixelShader(NULL);
+
+ hr = TextureBlt(m_pD3DDev, v, filter);
+
+ return hr;
+}
+
+HRESULT CDX9AllocatorPresenter::TextureResizeBilinear(CComPtr<IDirect3DTexture9> pTexture, Vector dst[4])
+{
+ HRESULT hr;
+
+ D3DSURFACE_DESC desc;
+ if(!pTexture || FAILED(pTexture->GetLevelDesc(0, &desc)))
+ return E_FAIL;
+
+ float w = (float)desc.Width;
+ float h = (float)desc.Height;
+
+ float dx = 1.0f/w;
+ float dy = 1.0f/h;
+
+ MYD3DVERTEX<5> v[] =
+ {
+ {dst[0].x, dst[0].y, dst[0].z, 1.0f/dst[0].z, 0, 0, 0+dx, 0, 0, 0+dy, 0+dx, 0+dy, 0, 0},
+ {dst[1].x, dst[1].y, dst[1].z, 1.0f/dst[1].z, 1, 0, 1+dx, 0, 1, 0+dy, 1+dx, 0+dy, w, 0},
+ {dst[2].x, dst[2].y, dst[2].z, 1.0f/dst[2].z, 0, 1, 0+dx, 1, 0, 1+dy, 0+dx, 1+dy, 0, h},
+ {dst[3].x, dst[3].y, dst[3].z, 1.0f/dst[3].z, 1, 1, 1+dx, 1, 1, 1+dy, 1+dx, 1+dy, w, h},
+ };
+
+ AdjustQuad(v, dx, dy);
+
+ hr = m_pD3DDev->SetTexture(0, pTexture);
+ hr = m_pD3DDev->SetTexture(1, pTexture);
+ hr = m_pD3DDev->SetTexture(2, pTexture);
+ hr = m_pD3DDev->SetTexture(3, pTexture);
+
+ hr = m_pD3DDev->SetPixelShader(m_pResizerPixelShader[0]);
+
+ hr = TextureBlt(m_pD3DDev, v, D3DTEXF_POINT);
+
+ //
+
+ m_pD3DDev->SetPixelShader(NULL);
+
+ return hr;
+}
+
+HRESULT CDX9AllocatorPresenter::TextureResizeBicubic1pass(CComPtr<IDirect3DTexture9> pTexture, Vector dst[4])
+{
+ HRESULT hr;
+
+ D3DSURFACE_DESC desc;
+ if(!pTexture || FAILED(pTexture->GetLevelDesc(0, &desc)))
+ return E_FAIL;
+
+ float w = (float)desc.Width;
+ float h = (float)desc.Height;
+
+ float dx = 1.0f/w;
+ float dy = 1.0f/h;
+
+ MYD3DVERTEX<2> v[] =
+ {
+ {dst[0].x, dst[0].y, dst[0].z, 1.0f/dst[0].z, 0, 0, 0, 0},
+ {dst[1].x, dst[1].y, dst[1].z, 1.0f/dst[1].z, 1, 0, w, 0},
+ {dst[2].x, dst[2].y, dst[2].z, 1.0f/dst[2].z, 0, 1, 0, h},
+ {dst[3].x, dst[3].y, dst[3].z, 1.0f/dst[3].z, 1, 1, w, h},
+ };
+
+ AdjustQuad(v, dx, dy);
+
+ hr = m_pD3DDev->SetTexture(0, pTexture);
+
+ float fConstData[][4] = {{w, h, 0, 0}, {1.0f / w, 1.0f / h, 0, 0}, {1.0f / w, 0, 0, 0}, {0, 1.0f / h, 0, 0}};
+ hr = m_pD3DDev->SetPixelShaderConstantF(0, (float*)fConstData, countof(fConstData));
+
+ hr = m_pD3DDev->SetPixelShader(m_pResizerPixelShader[1]);
+
+ hr = TextureBlt(m_pD3DDev, v, D3DTEXF_POINT);
+
+ m_pD3DDev->SetPixelShader(NULL);
+
+ return hr;
+}
+
+HRESULT CDX9AllocatorPresenter::TextureResizeBicubic2pass(CComPtr<IDirect3DTexture9> pTexture, Vector dst[4])
+{
+ // return TextureResizeBicubic1pass(pTexture, dst);
+
+ HRESULT hr;
+
+ // rotated?
+ if(dst[0].z != dst[1].z || dst[2].z != dst[3].z || dst[0].z != dst[3].z
+ || dst[0].y != dst[1].y || dst[0].x != dst[2].x || dst[2].y != dst[3].y || dst[1].x != dst[3].x)
+ return TextureResizeBicubic1pass(pTexture, dst);
+
+ D3DSURFACE_DESC desc;
+ if(!pTexture || FAILED(pTexture->GetLevelDesc(0, &desc)))
+ return E_FAIL;
+
+ float dx = 1.0f/desc.Width;
+
+ float w = (float)desc.Width;
+ float h = (float)desc.Height;
+
+ CRect dst1(0, 0, (int)(dst[3].x - dst[0].x), (int)h);
+
+ if(!m_pResizerBicubic1stPass || FAILED(m_pResizerBicubic1stPass->GetLevelDesc(0, &desc)))
+ return TextureResizeBicubic1pass(pTexture, dst);
+
+ float dy = 1.0f/desc.Height;
+
+ float dw = (float)dst1.Width() / desc.Width;
+ float dh = (float)dst1.Height() / desc.Height;
+
+ ASSERT(dst1.Height() == desc.Height);
+
+ if(dst1.Width() > desc.Width || dst1.Height() > desc.Height)
+ // if(dst1.Width() != desc.Width || dst1.Height() != desc.Height)
+ return TextureResizeBicubic1pass(pTexture, dst);
+
+ MYD3DVERTEX<5> vx[] =
+ {
+ {(float)dst1.left, (float)dst1.top, 0.5f, 2.0f, 0-dx, 0, 0, 0, 0+dx, 0, 0+dx*2, 0, 0, 0},
+ {(float)dst1.right, (float)dst1.top, 0.5f, 2.0f, 1-dx, 0, 1, 0, 1+dx, 0, 1+dx*2, 0, w, 0},
+ {(float)dst1.left, (float)dst1.bottom, 0.5f, 2.0f, 0-dx, 1, 0, 1, 0+dx, 1, 0+dx*2, 1, 0, 0},
+ {(float)dst1.right, (float)dst1.bottom, 0.5f, 2.0f, 1-dx, 1, 1, 1, 1+dx, 1, 1+dx*2, 1, w, 0},
+ };
+
+ AdjustQuad(vx, dx, 0);
+
+ MYD3DVERTEX<5> vy[] =
+ {
+ {dst[0].x, dst[0].y, dst[0].z, 1.0f/dst[0].z, 0, 0-dy, 0, 0, 0, 0+dy, 0, 0+dy*2, 0, 0},
+ {dst[1].x, dst[1].y, dst[1].z, 1.0f/dst[1].z, dw, 0-dy, dw, 0, dw, 0+dy, dw, 0+dy*2, 0, 0},
+ {dst[2].x, dst[2].y, dst[2].z, 1.0f/dst[2].z, 0, dh-dy, 0, dh, 0, dh+dy, 0, dh+dy*2, h, 0},
+ {dst[3].x, dst[3].y, dst[3].z, 1.0f/dst[3].z, dw, dh-dy, dw, dh, dw, dh+dy, dw, dh+dy*2, h, 0},
+ };
+
+ AdjustQuad(vy, 0, dy);
+
+ hr = m_pD3DDev->SetPixelShader(m_pResizerPixelShader[2]);
+
+ hr = m_pD3DDev->SetTexture(0, pTexture);
+ hr = m_pD3DDev->SetTexture(1, pTexture);
+ hr = m_pD3DDev->SetTexture(2, pTexture);
+ hr = m_pD3DDev->SetTexture(3, pTexture);
+
+ CComPtr<IDirect3DSurface9> pRTOld;
+ hr = m_pD3DDev->GetRenderTarget(0, &pRTOld);
+
+ CComPtr<IDirect3DSurface9> pRT;
+ hr = m_pResizerBicubic1stPass->GetSurfaceLevel(0, &pRT);
+ hr = m_pD3DDev->SetRenderTarget(0, pRT);
+
+ hr = TextureBlt(m_pD3DDev, vx, D3DTEXF_POINT);
+
+ hr = m_pD3DDev->SetTexture(0, m_pResizerBicubic1stPass);
+ hr = m_pD3DDev->SetTexture(1, m_pResizerBicubic1stPass);
+ hr = m_pD3DDev->SetTexture(2, m_pResizerBicubic1stPass);
+ hr = m_pD3DDev->SetTexture(3, m_pResizerBicubic1stPass);
+
+ hr = m_pD3DDev->SetRenderTarget(0, pRTOld);
+
+ hr = TextureBlt(m_pD3DDev, vy, D3DTEXF_POINT);
+
+ m_pD3DDev->SetPixelShader(NULL);
+
+ return hr;
+}
+
+HRESULT CDX9AllocatorPresenter::AlphaBlt(RECT* pSrc, RECT* pDst, CComPtr<IDirect3DTexture9> pTexture)
+{
+ if(!pSrc || !pDst)
+ return E_POINTER;
+
+ CRect src(*pSrc), dst(*pDst);
+
+ HRESULT hr;
+
+ do
+ {
+ D3DSURFACE_DESC d3dsd;
+ ZeroMemory(&d3dsd, sizeof(d3dsd));
+ if(FAILED(pTexture->GetLevelDesc(0, &d3dsd)) /*|| d3dsd.Type != D3DRTYPE_TEXTURE*/)
+ break;
+
+ float w = (float)d3dsd.Width;
+ float h = (float)d3dsd.Height;
+
+ struct
+ {
+ float x, y, z, rhw;
+ float tu, tv;
+ }
+ pVertices[] =
+ {
+ {(float)dst.left, (float)dst.top, 0.5f, 2.0f, (float)src.left / w, (float)src.top / h},
+ {(float)dst.right, (float)dst.top, 0.5f, 2.0f, (float)src.right / w, (float)src.top / h},
+ {(float)dst.left, (float)dst.bottom, 0.5f, 2.0f, (float)src.left / w, (float)src.bottom / h},
+ {(float)dst.right, (float)dst.bottom, 0.5f, 2.0f, (float)src.right / w, (float)src.bottom / h},
+ };
+/*
+ for(int i = 0; i < countof(pVertices); i++)
+ {
+ pVertices[i].x -= 0.5;
+ pVertices[i].y -= 0.5;
+ }
+*/
+
+ hr = m_pD3DDev->SetTexture(0, pTexture);
+
+ DWORD abe, sb, db;
+ hr = m_pD3DDev->GetRenderState(D3DRS_ALPHABLENDENABLE, &abe);
+ hr = m_pD3DDev->GetRenderState(D3DRS_SRCBLEND, &sb);
+ hr = m_pD3DDev->GetRenderState(D3DRS_DESTBLEND, &db);
+
+ hr = m_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ hr = m_pD3DDev->SetRenderState(D3DRS_LIGHTING, FALSE);
+ hr = m_pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE);
+ hr = m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ hr = m_pD3DDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); // pre-multiplied src and ...
+ hr = m_pD3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA); // ... inverse alpha channel for dst
+
+ hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+
+ hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+
+ hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
+ hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
+
+ /*//
+
+ D3DCAPS9 d3dcaps9;
+ hr = m_pD3DDev->GetDeviceCaps(&d3dcaps9);
+ if(d3dcaps9.AlphaCmpCaps & D3DPCMPCAPS_LESS)
+ {
+ hr = m_pD3DDev->SetRenderState(D3DRS_ALPHAREF, (DWORD)0x000000FE);
+ hr = m_pD3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
+ hr = m_pD3DDev->SetRenderState(D3DRS_ALPHAFUNC, D3DPCMPCAPS_LESS);
+ }
+
+ *///
+
+ hr = m_pD3DDev->SetPixelShader(NULL);
+
+ if(FAILED(hr = m_pD3DDev->BeginScene()))
+ break;
+
+ hr = m_pD3DDev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
+ hr = m_pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pVertices, sizeof(pVertices[0]));
+
+ hr = m_pD3DDev->EndScene();
+
+ //
+
+ m_pD3DDev->SetTexture(0, NULL);
+
+ m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, abe);
+ m_pD3DDev->SetRenderState(D3DRS_SRCBLEND, sb);
+ m_pD3DDev->SetRenderState(D3DRS_DESTBLEND, db);
+
+ return S_OK;
+ }
+ while(0);
+
+ return E_FAIL;
+}
+
+
+STDMETHODIMP_(bool) CDX9AllocatorPresenter::Paint(bool fAll)
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ CAutoLock cAutoLock(this);
+
+ if(m_WindowRect.right <= m_WindowRect.left || m_WindowRect.bottom <= m_WindowRect.top
+ || m_NativeVideoSize.cx <= 0 || m_NativeVideoSize.cy <= 0
+ || !m_pVideoSurface)
+ return(false);
+
+ HRESULT hr;
+
+ CRect rSrcVid(CPoint(0, 0), m_NativeVideoSize);
+ CRect rDstVid(m_VideoRect);
+
+ CRect rSrcPri(CPoint(0, 0), m_WindowRect.Size());
+ CRect rDstPri(m_WindowRect);
+
+ CComPtr<IDirect3DSurface9> pBackBuffer;
+ m_pD3DDev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
+
+ m_pD3DDev->SetRenderTarget(0, pBackBuffer);
+
+ if(fAll)
+ {
+ // clear the backbuffer
+
+ hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0);
+
+ // paint the video on the backbuffer
+
+ if(!rDstVid.IsRectEmpty())
+ {
+ if(m_pVideoTexture[0])
+ {
+ CComPtr<IDirect3DTexture9> pVideoTexture = m_pVideoTexture[0];
+
+ if(m_pVideoTexture[1] && m_pVideoTexture[2] && !m_pPixelShaders.IsEmpty())
+ {
+ static __int64 counter = 0;
+ static long start = clock();
+
+ long stop = clock();
+ long diff = stop - start;
+
+ if(diff >= 10*60*CLOCKS_PER_SEC) start = stop; // reset after 10 min (ps float has its limits in both range and accuracy)
+
+ float fConstData[][4] =
+ {
+ {(float)m_NativeVideoSize.cx, (float)m_NativeVideoSize.cy, (float)(counter++), (float)diff / CLOCKS_PER_SEC},
+ {1.0f / m_NativeVideoSize.cx, 1.0f / m_NativeVideoSize.cy, 0, 0},
+ };
+
+ hr = m_pD3DDev->SetPixelShaderConstantF(0, (float*)fConstData, countof(fConstData));
+
+ CComPtr<IDirect3DSurface9> pRT;
+ hr = m_pD3DDev->GetRenderTarget(0, &pRT);
+
+ int src = 0, dst = 1;
+
+ POSITION pos = m_pPixelShaders.GetHeadPosition();
+ while(pos)
+ {
+ pVideoTexture = m_pVideoTexture[dst];
+
+ hr = m_pD3DDev->SetRenderTarget(0, m_pVideoSurface[dst]);
+ hr = m_pD3DDev->SetPixelShader(m_pPixelShaders.GetNext(pos));
+ TextureCopy(m_pVideoTexture[src]);
+
+ if(++src > 2) src = 1;
+ if(++dst > 2) dst = 1;
+ }
+
+ hr = m_pD3DDev->SetRenderTarget(0, pRT);
+ hr = m_pD3DDev->SetPixelShader(NULL);
+ }
+
+ Vector dst[4];
+ Transform(rDstVid, dst);
+
+ DWORD iDX9Resizer = s.iDX9Resizer;
+
+ float A = 0;
+
+ switch(iDX9Resizer)
+ {
+ case 3: A = -0.60f; break;
+ case 4: A = -0.75f; break;
+ case 5: A = -1.00f; break;
+ }
+
+ hr = InitResizers(A);
+
+ if(iDX9Resizer == 0 || iDX9Resizer == 1 || rSrcVid.Size() == rDstVid.Size() || FAILED(hr))
+ {
+ hr = TextureResize(pVideoTexture, dst, iDX9Resizer == 0 ? D3DTEXF_POINT : D3DTEXF_LINEAR);
+ }
+ else if(iDX9Resizer == 2)
+ {
+ hr = TextureResizeBilinear(pVideoTexture, dst);
+ }
+ else if(iDX9Resizer >= 3)
+ {
+ hr = TextureResizeBicubic2pass(pVideoTexture, dst);
+ }
+
+ }
+ else
+ {
+ if(pBackBuffer)
+ {
+ ClipToSurface(pBackBuffer, rSrcVid, rDstVid); // grrr
+ // IMPORTANT: rSrcVid has to be aligned on mod2 for yuy2->rgb conversion with StretchRect!!!
+ rSrcVid.left &= ~1; rSrcVid.right &= ~1;
+ rSrcVid.top &= ~1; rSrcVid.bottom &= ~1;
+ hr = m_pD3DDev->StretchRect(m_pVideoSurface[0], rSrcVid, pBackBuffer, rDstVid, m_filter);
+ }
+ }
+ }
+
+ // paint the text on the backbuffer
+
+ AlphaBltSubPic(rSrcPri.Size());
+ }
+
+ // Casimir666 : affichage de l'OSD
+ if (m_VMR9AlphaBitmap.dwFlags & VMRBITMAP_UPDATE)
+ {
+ CRect rcSrc (m_VMR9AlphaBitmap.rSrc);
+ m_pOSDTexture = NULL;
+ m_pOSDSurface = NULL;
+ if ((m_VMR9AlphaBitmap.dwFlags & VMRBITMAP_DISABLE) == 0)
+ {
+ if(SUCCEEDED(hr = m_pD3DDev->CreateTexture(rcSrc.Width(), rcSrc.Height(), 1,
+ D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
+ D3DPOOL_DEFAULT, &m_pOSDTexture, NULL)))
+ {
+ if (SUCCEEDED (hr = m_pOSDTexture->GetSurfaceLevel(0, &m_pOSDSurface)))
+ {
+ HBITMAP hBitmap = (HBITMAP)GetCurrentObject (m_VMR9AlphaBitmap.hdc, OBJ_BITMAP);
+ DIBSECTION info = {0};
+
+ ::GetObject(hBitmap, sizeof( DIBSECTION ), &info );
+ CRect rcBitmap (0, 0, info.dsBm.bmWidth, info.dsBm.bmHeight);
+
+ hr = D3DXLoadSurfaceFromMemory (m_pOSDSurface,
+ NULL,
+ NULL,
+ info.dsBm.bmBits,
+ D3DFMT_A8R8G8B8,
+ info.dsBm.bmWidthBytes,
+ NULL,
+ &rcBitmap,
+ D3DX_FILTER_NONE,
+ m_VMR9AlphaBitmap.clrSrcKey);
+ }
+ if (FAILED (hr))
+ {
+ m_pOSDTexture = NULL;
+ m_pOSDSurface = NULL;
+ }
+ }
+ }
+ m_VMR9AlphaBitmap.dwFlags ^= VMRBITMAP_UPDATE;
+
+ }
+ if (m_pOSDTexture) AlphaBlt(rSrcPri, rDstPri, m_pOSDTexture);
+
+ if(m_fVMRSyncFix)
+ {
+ D3DLOCKED_RECT lr;
+ if(SUCCEEDED(pBackBuffer->LockRect(&lr, NULL, 0)))
+ pBackBuffer->UnlockRect();
+ }
+
+ if (((CMainFrame*)AfxGetApp()->m_pMainWnd)->IsD3DFullScreenMode())
+ hr = m_pD3DDev->Present(NULL, NULL, NULL, NULL);
+ else
+ hr = m_pD3DDev->Present(rSrcPri, rDstPri, NULL, NULL);
+
+ bool fResetDevice = false;
+
+ if(hr == D3DERR_DEVICELOST && m_pD3DDev->TestCooperativeLevel() == D3DERR_DEVICENOTRESET)
+ {
+ fResetDevice = true;
+ }
+
+ D3DDEVICE_CREATION_PARAMETERS Parameters;
+ if(SUCCEEDED(m_pD3DDev->GetCreationParameters(&Parameters))
+ && m_pD3D->GetAdapterMonitor(Parameters.AdapterOrdinal) != m_pD3D->GetAdapterMonitor(GetAdapter(m_pD3D)))
+ {
+ fResetDevice = true;
+ }
+
+ if(fResetDevice)
+ {
+ DeleteSurfaces();
+ if(FAILED(hr = CreateDevice()) || FAILED(hr = AllocSurfaces()))
+ return false;
+ }
+
+ return(true);
+}
+
+STDMETHODIMP CDX9AllocatorPresenter::GetDIB(BYTE* lpDib, DWORD* size)
+{
+ CheckPointer(size, E_POINTER);
+
+ HRESULT hr;
+
+ D3DSURFACE_DESC desc;
+ memset(&desc, 0, sizeof(desc));
+ m_pVideoSurface[0]->GetDesc(&desc);
+
+ DWORD required = sizeof(BITMAPINFOHEADER) + (desc.Width * desc.Height * 32 >> 3);
+ if(!lpDib) {*size = required; return S_OK;}
+ if(*size < required) return E_OUTOFMEMORY;
+ *size = required;
+
+ CComPtr<IDirect3DSurface9> pSurface = m_pVideoSurface[0];
+ D3DLOCKED_RECT r;
+ if(FAILED(hr = pSurface->LockRect(&r, NULL, D3DLOCK_READONLY)))
+ {
+ pSurface = NULL;
+ if(FAILED(hr = m_pD3DDev->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pSurface, NULL))
+ || FAILED(hr = m_pD3DDev->GetRenderTargetData(m_pVideoSurface[0], pSurface))
+ || FAILED(hr = pSurface->LockRect(&r, NULL, D3DLOCK_READONLY)))
+ return hr;
+ }
+
+ BITMAPINFOHEADER* bih = (BITMAPINFOHEADER*)lpDib;
+ memset(bih, 0, sizeof(BITMAPINFOHEADER));
+ bih->biSize = sizeof(BITMAPINFOHEADER);
+ bih->biWidth = desc.Width;
+ bih->biHeight = desc.Height;
+ bih->biBitCount = 32;
+ bih->biPlanes = 1;
+ bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount >> 3;
+
+ BitBltFromRGBToRGB(
+ bih->biWidth, bih->biHeight,
+ (BYTE*)(bih + 1), bih->biWidth*bih->biBitCount>>3, bih->biBitCount,
+ (BYTE*)r.pBits + r.Pitch*(desc.Height-1), -(int)r.Pitch, 32);
+
+ pSurface->UnlockRect();
+
+ return S_OK;
+}
+
+STDMETHODIMP CDX9AllocatorPresenter::SetPixelShader(LPCSTR pSrcData, LPCSTR pTarget)
+{
+ CAutoLock cAutoLock(this);
+
+ if(!pSrcData && !pTarget)
+ {
+ m_pPixelShaders.RemoveAll();
+ m_pD3DDev->SetPixelShader(NULL);
+ return S_OK;
+ }
+
+ if(!pSrcData || !pTarget)
+ return E_INVALIDARG;
+
+ CComPtr<IDirect3DPixelShader9> pPixelShader;
+
+ HRESULT hr = m_pPSC->CompileShader(pSrcData, "main", pTarget, 0, &pPixelShader);
+ if(FAILED(hr)) return hr;
+
+ m_pPixelShaders.AddTail(pPixelShader);
+
+ Paint(true);
+
+ return S_OK;
+}
+
+//
+// CVMR9AllocatorPresenter
+//
+
+#define MY_USER_ID 0x6ABE51
+
+CVMR9AllocatorPresenter::CVMR9AllocatorPresenter(HWND hWnd, HRESULT& hr)
+ : CDX9AllocatorPresenter(hWnd, hr)
+ , m_fUseInternalTimer(false)
+ , m_rtPrevStart(-1)
+{
+}
+
+STDMETHODIMP CVMR9AllocatorPresenter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ CheckPointer(ppv, E_POINTER);
+
+ return
+ QI(IVMRSurfaceAllocator9)
+ QI(IVMRImagePresenter9)
+ QI(IVMRWindowlessControl9)
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+HRESULT CVMR9AllocatorPresenter::CreateDevice()
+{
+ HRESULT hr = __super::CreateDevice();
+ if(FAILED(hr)) return hr;
+
+ if(m_pIVMRSurfAllocNotify)
+ {
+ HMONITOR hMonitor = m_pD3D->GetAdapterMonitor(GetAdapter(m_pD3D));
+ if(FAILED(hr = m_pIVMRSurfAllocNotify->ChangeD3DDevice(m_pD3DDev, hMonitor)))
+ return(false);
+ }
+
+ return hr;
+}
+
+void CVMR9AllocatorPresenter::DeleteSurfaces()
+{
+ CAutoLock cAutoLock(this);
+
+ m_pSurfaces.RemoveAll();
+
+ return __super::DeleteSurfaces();
+}
+
+// ISubPicAllocatorPresenter
+
+class COuterVMR9
+ : public CUnknown
+ , public IVideoWindow
+ , public IBasicVideo2
+ , public IVMRWindowlessControl
+ , public IVMRMixerBitmap9
+{
+ CComPtr<IUnknown> m_pVMR;
+ VMR9AlphaBitmap* m_pVMR9AlphaBitmap;
+
+public:
+
+ COuterVMR9(const TCHAR* pName, LPUNKNOWN pUnk, VMR9AlphaBitmap* pVMR9AlphaBitmap) : CUnknown(pName, pUnk)
+ {
+ m_pVMR.CoCreateInstance(CLSID_VideoMixingRenderer9, GetOwner());
+ m_pVMR9AlphaBitmap = pVMR9AlphaBitmap;
+ }
+
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv)
+ {
+ HRESULT hr;
+
+ // Casimir666 : en mode Renderless faire l'incrustation à la place du VMR
+ if(riid == __uuidof(IVMRMixerBitmap9))
+ return GetInterface((IVMRMixerBitmap9*)this, ppv);
+
+ hr = m_pVMR ? m_pVMR->QueryInterface(riid, ppv) : E_NOINTERFACE;
+ if(m_pVMR && FAILED(hr))
+ {
+ if(riid == __uuidof(IVideoWindow))
+ return GetInterface((IVideoWindow*)this, ppv);
+ if(riid == __uuidof(IBasicVideo))
+ return GetInterface((IBasicVideo*)this, ppv);
+ if(riid == __uuidof(IBasicVideo2))
+ return GetInterface((IBasicVideo2*)this, ppv);
+/* if(riid == __uuidof(IVMRWindowlessControl))
+ return GetInterface((IVMRWindowlessControl*)this, ppv);
+*/
+ }
+
+ return SUCCEEDED(hr) ? hr : __super::NonDelegatingQueryInterface(riid, ppv);
+ }
+
+ // IVMRWindowlessControl
+
+ STDMETHODIMP GetNativeVideoSize(LONG* lpWidth, LONG* lpHeight, LONG* lpARWidth, LONG* lpARHeight)
+ {
+ if(CComQIPtr<IVMRWindowlessControl9> pWC9 = m_pVMR)
+ {
+ return pWC9->GetNativeVideoSize(lpWidth, lpHeight, lpARWidth, lpARHeight);
+ }
+
+ return E_NOTIMPL;
+ }
+ STDMETHODIMP GetMinIdealVideoSize(LONG* lpWidth, LONG* lpHeight) {return E_NOTIMPL;}
+ STDMETHODIMP GetMaxIdealVideoSize(LONG* lpWidth, LONG* lpHeight) {return E_NOTIMPL;}
+ STDMETHODIMP SetVideoPosition(const LPRECT lpSRCRect, const LPRECT lpDSTRect) {return E_NOTIMPL;}
+ STDMETHODIMP GetVideoPosition(LPRECT lpSRCRect, LPRECT lpDSTRect)
+ {
+ if(CComQIPtr<IVMRWindowlessControl9> pWC9 = m_pVMR)
+ {
+ return pWC9->GetVideoPosition(lpSRCRect, lpDSTRect);
+ }
+
+ return E_NOTIMPL;
+ }
+ STDMETHODIMP GetAspectRatioMode(DWORD* lpAspectRatioMode)
+ {
+ if(CComQIPtr<IVMRWindowlessControl9> pWC9 = m_pVMR)
+ {
+ *lpAspectRatioMode = VMR_ARMODE_NONE;
+ return S_OK;
+ }
+
+ return E_NOTIMPL;
+ }
+ STDMETHODIMP SetAspectRatioMode(DWORD AspectRatioMode) {return E_NOTIMPL;}
+ STDMETHODIMP SetVideoClippingWindow(HWND hwnd) {return E_NOTIMPL;}
+ STDMETHODIMP RepaintVideo(HWND hwnd, HDC hdc) {return E_NOTIMPL;}
+ STDMETHODIMP DisplayModeChanged() {return E_NOTIMPL;}
+ STDMETHODIMP GetCurrentImage(BYTE** lpDib) {return E_NOTIMPL;}
+ STDMETHODIMP SetBorderColor(COLORREF Clr) {return E_NOTIMPL;}
+ STDMETHODIMP GetBorderColor(COLORREF* lpClr) {return E_NOTIMPL;}
+ STDMETHODIMP SetColorKey(COLORREF Clr) {return E_NOTIMPL;}
+ STDMETHODIMP GetColorKey(COLORREF* lpClr) {return E_NOTIMPL;}
+
+ // IVideoWindow
+ STDMETHODIMP GetTypeInfoCount(UINT* pctinfo) {return E_NOTIMPL;}
+ STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) {return E_NOTIMPL;}
+ STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) {return E_NOTIMPL;}
+ STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) {return E_NOTIMPL;}
+ STDMETHODIMP put_Caption(BSTR strCaption) {return E_NOTIMPL;}
+ STDMETHODIMP get_Caption(BSTR* strCaption) {return E_NOTIMPL;}
+ STDMETHODIMP put_WindowStyle(long WindowStyle) {return E_NOTIMPL;}
+ STDMETHODIMP get_WindowStyle(long* WindowStyle) {return E_NOTIMPL;}
+ STDMETHODIMP put_WindowStyleEx(long WindowStyleEx) {return E_NOTIMPL;}
+ STDMETHODIMP get_WindowStyleEx(long* WindowStyleEx) {return E_NOTIMPL;}
+ STDMETHODIMP put_AutoShow(long AutoShow) {return E_NOTIMPL;}
+ STDMETHODIMP get_AutoShow(long* AutoShow) {return E_NOTIMPL;}
+ STDMETHODIMP put_WindowState(long WindowState) {return E_NOTIMPL;}
+ STDMETHODIMP get_WindowState(long* WindowState) {return E_NOTIMPL;}
+ STDMETHODIMP put_BackgroundPalette(long BackgroundPalette) {return E_NOTIMPL;}
+ STDMETHODIMP get_BackgroundPalette(long* pBackgroundPalette) {return E_NOTIMPL;}
+ STDMETHODIMP put_Visible(long Visible) {return E_NOTIMPL;}
+ STDMETHODIMP get_Visible(long* pVisible) {return E_NOTIMPL;}
+ STDMETHODIMP put_Left(long Left) {return E_NOTIMPL;}
+ STDMETHODIMP get_Left(long* pLeft) {return E_NOTIMPL;}
+ STDMETHODIMP put_Width(long Width) {return E_NOTIMPL;}
+ STDMETHODIMP get_Width(long* pWidth)
+ {
+ if(CComQIPtr<IVMRWindowlessControl9> pWC9 = m_pVMR)
+ {
+ CRect s, d;
+ HRESULT hr = pWC9->GetVideoPosition(&s, &d);
+ *pWidth = d.Width();
+ return hr;
+ }
+
+ return E_NOTIMPL;
+ }
+ STDMETHODIMP put_Top(long Top) {return E_NOTIMPL;}
+ STDMETHODIMP get_Top(long* pTop) {return E_NOTIMPL;}
+ STDMETHODIMP put_Height(long Height) {return E_NOTIMPL;}
+ STDMETHODIMP get_Height(long* pHeight)
+ {
+ if(CComQIPtr<IVMRWindowlessControl9> pWC9 = m_pVMR)
+ {
+ CRect s, d;
+ HRESULT hr = pWC9->GetVideoPosition(&s, &d);
+ *pHeight = d.Height();
+ return hr;
+ }
+
+ return E_NOTIMPL;
+ }
+ STDMETHODIMP put_Owner(OAHWND Owner) {return E_NOTIMPL;}
+ STDMETHODIMP get_Owner(OAHWND* Owner) {return E_NOTIMPL;}
+ STDMETHODIMP put_MessageDrain(OAHWND Drain) {return E_NOTIMPL;}
+ STDMETHODIMP get_MessageDrain(OAHWND* Drain) {return E_NOTIMPL;}
+ STDMETHODIMP get_BorderColor(long* Color) {return E_NOTIMPL;}
+ STDMETHODIMP put_BorderColor(long Color) {return E_NOTIMPL;}
+ STDMETHODIMP get_FullScreenMode(long* FullScreenMode) {return E_NOTIMPL;}
+ STDMETHODIMP put_FullScreenMode(long FullScreenMode) {return E_NOTIMPL;}
+ STDMETHODIMP SetWindowForeground(long Focus) {return E_NOTIMPL;}
+ STDMETHODIMP NotifyOwnerMessage(OAHWND hwnd, long uMsg, LONG_PTR wParam, LONG_PTR lParam) {return E_NOTIMPL;}
+ STDMETHODIMP SetWindowPosition(long Left, long Top, long Width, long Height) {return E_NOTIMPL;}
+ STDMETHODIMP GetWindowPosition(long* pLeft, long* pTop, long* pWidth, long* pHeight) {return E_NOTIMPL;}
+ STDMETHODIMP GetMinIdealImageSize(long* pWidth, long* pHeight) {return E_NOTIMPL;}
+ STDMETHODIMP GetMaxIdealImageSize(long* pWidth, long* pHeight) {return E_NOTIMPL;}
+ STDMETHODIMP GetRestorePosition(long* pLeft, long* pTop, long* pWidth, long* pHeight) {return E_NOTIMPL;}
+ STDMETHODIMP HideCursor(long HideCursor) {return E_NOTIMPL;}
+ STDMETHODIMP IsCursorHidden(long* CursorHidden) {return E_NOTIMPL;}
+
+ // IBasicVideo2
+ STDMETHODIMP get_AvgTimePerFrame(REFTIME* pAvgTimePerFrame) {return E_NOTIMPL;}
+ STDMETHODIMP get_BitRate(long* pBitRate) {return E_NOTIMPL;}
+ STDMETHODIMP get_BitErrorRate(long* pBitErrorRate) {return E_NOTIMPL;}
+ STDMETHODIMP get_VideoWidth(long* pVideoWidth) {return E_NOTIMPL;}
+ STDMETHODIMP get_VideoHeight(long* pVideoHeight) {return E_NOTIMPL;}
+ STDMETHODIMP put_SourceLeft(long SourceLeft) {return E_NOTIMPL;}
+ STDMETHODIMP get_SourceLeft(long* pSourceLeft) {return E_NOTIMPL;}
+ STDMETHODIMP put_SourceWidth(long SourceWidth) {return E_NOTIMPL;}
+ STDMETHODIMP get_SourceWidth(long* pSourceWidth) {return E_NOTIMPL;}
+ STDMETHODIMP put_SourceTop(long SourceTop) {return E_NOTIMPL;}
+ STDMETHODIMP get_SourceTop(long* pSourceTop) {return E_NOTIMPL;}
+ STDMETHODIMP put_SourceHeight(long SourceHeight) {return E_NOTIMPL;}
+ STDMETHODIMP get_SourceHeight(long* pSourceHeight) {return E_NOTIMPL;}
+ STDMETHODIMP put_DestinationLeft(long DestinationLeft) {return E_NOTIMPL;}
+ STDMETHODIMP get_DestinationLeft(long* pDestinationLeft) {return E_NOTIMPL;}
+ STDMETHODIMP put_DestinationWidth(long DestinationWidth) {return E_NOTIMPL;}
+ STDMETHODIMP get_DestinationWidth(long* pDestinationWidth) {return E_NOTIMPL;}
+ STDMETHODIMP put_DestinationTop(long DestinationTop) {return E_NOTIMPL;}
+ STDMETHODIMP get_DestinationTop(long* pDestinationTop) {return E_NOTIMPL;}
+ STDMETHODIMP put_DestinationHeight(long DestinationHeight) {return E_NOTIMPL;}
+ STDMETHODIMP get_DestinationHeight(long* pDestinationHeight) {return E_NOTIMPL;}
+ STDMETHODIMP SetSourcePosition(long Left, long Top, long Width, long Height) {return E_NOTIMPL;}
+ STDMETHODIMP GetSourcePosition(long* pLeft, long* pTop, long* pWidth, long* pHeight)
+ {
+ // DVD Nav. bug workaround fix
+ {
+ *pLeft = *pTop = 0;
+ return GetVideoSize(pWidth, pHeight);
+ }
+/*
+ if(CComQIPtr<IVMRWindowlessControl9> pWC9 = m_pVMR)
+ {
+ CRect s, d;
+ HRESULT hr = pWC9->GetVideoPosition(&s, &d);
+ *pLeft = s.left;
+ *pTop = s.top;
+ *pWidth = s.Width();
+ *pHeight = s.Height();
+ return hr;
+ }
+*/
+ return E_NOTIMPL;
+ }
+ STDMETHODIMP SetDefaultSourcePosition() {return E_NOTIMPL;}
+ STDMETHODIMP SetDestinationPosition(long Left, long Top, long Width, long Height) {return E_NOTIMPL;}
+ STDMETHODIMP GetDestinationPosition(long* pLeft, long* pTop, long* pWidth, long* pHeight)
+ {
+ if(CComQIPtr<IVMRWindowlessControl9> pWC9 = m_pVMR)
+ {
+ CRect s, d;
+ HRESULT hr = pWC9->GetVideoPosition(&s, &d);
+ *pLeft = d.left;
+ *pTop = d.top;
+ *pWidth = d.Width();
+ *pHeight = d.Height();
+ return hr;
+ }
+
+ return E_NOTIMPL;
+ }
+ STDMETHODIMP SetDefaultDestinationPosition() {return E_NOTIMPL;}
+ STDMETHODIMP GetVideoSize(long* pWidth, long* pHeight)
+ {
+ if(CComQIPtr<IVMRWindowlessControl9> pWC9 = m_pVMR)
+ {
+ LONG aw, ah;
+// return pWC9->GetNativeVideoSize(pWidth, pHeight, &aw, &ah);
+ // DVD Nav. bug workaround fix
+ HRESULT hr = pWC9->GetNativeVideoSize(pWidth, pHeight, &aw, &ah);
+ *pWidth = *pHeight * aw / ah;
+ return hr;
+ }
+
+ return E_NOTIMPL;
+ }
+ STDMETHODIMP GetVideoPaletteEntries(long StartIndex, long Entries, long* pRetrieved, long* pPalette) {return E_NOTIMPL;}
+ STDMETHODIMP GetCurrentImage(long* pBufferSize, long* pDIBImage) {return E_NOTIMPL;}
+ STDMETHODIMP IsUsingDefaultSource() {return E_NOTIMPL;}
+ STDMETHODIMP IsUsingDefaultDestination() {return E_NOTIMPL;}
+
+ STDMETHODIMP GetPreferredAspectRatio(long* plAspectX, long* plAspectY)
+ {
+ if(CComQIPtr<IVMRWindowlessControl9> pWC9 = m_pVMR)
+ {
+ LONG w, h;
+ return pWC9->GetNativeVideoSize(&w, &h, plAspectX, plAspectY);
+ }
+
+ return E_NOTIMPL;
+ }
+
+ // IVMRMixerBitmap9
+ STDMETHODIMP GetAlphaBitmapParameters(VMR9AlphaBitmap* pBmpParms)
+ {
+ CheckPointer(pBmpParms, E_POINTER);
+ memcpy (pBmpParms, m_pVMR9AlphaBitmap, sizeof(VMR9AlphaBitmap));
+ return S_OK;
+ }
+
+ STDMETHODIMP SetAlphaBitmap(const VMR9AlphaBitmap* pBmpParms)
+ {
+ CheckPointer(pBmpParms, E_POINTER);
+ memcpy (m_pVMR9AlphaBitmap, pBmpParms, sizeof(VMR9AlphaBitmap));
+ m_pVMR9AlphaBitmap->dwFlags |= VMRBITMAP_UPDATE;
+ return S_OK;
+ }
+
+ STDMETHODIMP UpdateAlphaBitmapParameters(const VMR9AlphaBitmap* pBmpParms)
+ {
+ CheckPointer(pBmpParms, E_POINTER);
+ memcpy (m_pVMR9AlphaBitmap, pBmpParms, sizeof(VMR9AlphaBitmap));
+ m_pVMR9AlphaBitmap->dwFlags |= VMRBITMAP_UPDATE;
+ return S_OK;
+ }
+};
+
+STDMETHODIMP CVMR9AllocatorPresenter::CreateRenderer(IUnknown** ppRenderer)
+{
+ CheckPointer(ppRenderer, E_POINTER);
+
+ *ppRenderer = NULL;
+
+ HRESULT hr;
+
+ do
+ {
+ CMacrovisionKicker* pMK = new CMacrovisionKicker(NAME("CMacrovisionKicker"), NULL);
+ CComPtr<IUnknown> pUnk = (IUnknown*)(INonDelegatingUnknown*)pMK;
+ pMK->SetInner((IUnknown*)(INonDelegatingUnknown*)new COuterVMR9(NAME("COuterVMR9"), pUnk, &m_VMR9AlphaBitmap));
+ CComQIPtr<IBaseFilter> pBF = pUnk;
+/*
+ CComQIPtr<IBaseFilter> pBF = (IUnknown*)(INonDelegatingUnknown*)new COuterVMR9(NAME("COuterVMR9"), NULL);
+ if(!pBF) pBF.CoCreateInstance(CLSID_VideoMixingRenderer9);
+*/
+
+ CComPtr<IPin> pPin = GetFirstPin(pBF);
+ CComQIPtr<IMemInputPin> pMemInputPin = pPin;
+ m_fUseInternalTimer = HookNewSegmentAndReceive((IPinC*)(IPin*)pPin, (IMemInputPinC*)(IMemInputPin*)pMemInputPin);
+/*
+if(CComQIPtr<IAMVideoAccelerator> pAMVA = pPin)
+ HookAMVideoAccelerator((IAMVideoAcceleratorC*)(IAMVideoAccelerator*)pAMVA);
+*/
+ CComQIPtr<IVMRFilterConfig9> pConfig = pBF;
+ if(!pConfig)
+ break;
+
+ AppSettings& s = AfxGetAppSettings();
+
+ if(s.fVMR9MixerMode)
+ {
+ if(FAILED(hr = pConfig->SetNumberOfStreams(1)))
+ break;
+
+ if(s.fVMR9MixerYUV)
+ {
+ if(CComQIPtr<IVMRMixerControl9> pMC = pBF)
+ {
+ DWORD dwPrefs;
+ pMC->GetMixingPrefs(&dwPrefs);
+ dwPrefs &= ~MixerPref9_RenderTargetMask;
+ dwPrefs |= MixerPref9_RenderTargetYUV;
+ pMC->SetMixingPrefs(dwPrefs);
+ }
+ }
+ }
+
+ if(FAILED(hr = pConfig->SetRenderingMode(VMR9Mode_Renderless)))
+ break;
+
+ CComQIPtr<IVMRSurfaceAllocatorNotify9> pSAN = pBF;
+ if(!pSAN)
+ break;
+
+ if(FAILED(hr = pSAN->AdviseSurfaceAllocator(MY_USER_ID, static_cast<IVMRSurfaceAllocator9*>(this)))
+ || FAILED(hr = AdviseNotify(pSAN)))
+ break;
+
+ *ppRenderer = (IUnknown*)pBF.Detach();
+
+ return S_OK;
+ }
+ while(0);
+
+ return E_FAIL;
+}
+
+STDMETHODIMP_(void) CVMR9AllocatorPresenter::SetTime(REFERENCE_TIME rtNow)
+{
+ __super::SetTime(rtNow);
+ m_fUseInternalTimer = false;
+}
+
+// IVMRSurfaceAllocator9
+
+STDMETHODIMP CVMR9AllocatorPresenter::InitializeDevice(DWORD_PTR dwUserID, VMR9AllocationInfo* lpAllocInfo, DWORD* lpNumBuffers)
+{
+ if(!lpAllocInfo || !lpNumBuffers)
+ return E_POINTER;
+
+ if(!m_pIVMRSurfAllocNotify)
+ return E_FAIL;
+
+ if((GetAsyncKeyState(VK_CONTROL)&0x80000000))
+ if(lpAllocInfo->Format == '21VY' || lpAllocInfo->Format == '024I')
+ return E_FAIL;
+
+ DeleteSurfaces();
+
+ m_pSurfaces.SetCount(*lpNumBuffers);
+
+ int w = lpAllocInfo->dwWidth;
+ int h = abs((int)lpAllocInfo->dwHeight);
+
+ HRESULT hr;
+
+ if(lpAllocInfo->dwFlags & VMR9AllocFlag_3DRenderTarget)
+ lpAllocInfo->dwFlags |= VMR9AllocFlag_TextureSurface;
+
+ hr = m_pIVMRSurfAllocNotify->AllocateSurfaceHelper(lpAllocInfo, lpNumBuffers, &m_pSurfaces[0]);
+ if(FAILED(hr)) return hr;
+
+ m_NativeVideoSize = m_AspectRatio = CSize(w, h);
+ int arx = lpAllocInfo->szAspectRatio.cx, ary = lpAllocInfo->szAspectRatio.cy;
+ if(arx > 0 && ary > 0) m_AspectRatio.SetSize(arx, ary);
+
+ if(FAILED(hr = AllocSurfaces()))
+ return hr;
+
+ if(!(lpAllocInfo->dwFlags & VMR9AllocFlag_TextureSurface))
+ {
+ // test if the colorspace is acceptable
+ if(FAILED(hr = m_pD3DDev->StretchRect(m_pSurfaces[0], NULL, m_pVideoSurface[0], NULL, D3DTEXF_NONE)))
+ {
+ DeleteSurfaces();
+ return E_FAIL;
+ }
+ }
+
+ hr = m_pD3DDev->ColorFill(m_pVideoSurface[0], NULL, 0);
+
+ return hr;
+}
+
+STDMETHODIMP CVMR9AllocatorPresenter::TerminateDevice(DWORD_PTR dwUserID)
+{
+ DeleteSurfaces();
+ return S_OK;
+}
+
+STDMETHODIMP CVMR9AllocatorPresenter::GetSurface(DWORD_PTR dwUserID, DWORD SurfaceIndex, DWORD SurfaceFlags, IDirect3DSurface9** lplpSurface)
+{
+ if(!lplpSurface)
+ return E_POINTER;
+
+ if(SurfaceIndex >= m_pSurfaces.GetCount())
+ return E_FAIL;
+
+ CAutoLock cAutoLock(this);
+
+ (*lplpSurface = m_pSurfaces[SurfaceIndex])->AddRef();
+
+ return S_OK;
+}
+
+STDMETHODIMP CVMR9AllocatorPresenter::AdviseNotify(IVMRSurfaceAllocatorNotify9* lpIVMRSurfAllocNotify)
+{
+ CAutoLock cAutoLock(this);
+
+ m_pIVMRSurfAllocNotify = lpIVMRSurfAllocNotify;
+
+ HRESULT hr;
+ HMONITOR hMonitor = m_pD3D->GetAdapterMonitor(GetAdapter(m_pD3D));
+ if(FAILED(hr = m_pIVMRSurfAllocNotify->SetD3DDevice(m_pD3DDev, hMonitor)))
+ return hr;
+
+ return S_OK;
+}
+
+// IVMRImagePresenter9
+
+STDMETHODIMP CVMR9AllocatorPresenter::StartPresenting(DWORD_PTR dwUserID)
+{
+ CAutoLock cAutoLock(this);
+
+ ASSERT(m_pD3DDev);
+
+ return m_pD3DDev ? S_OK : E_FAIL;
+}
+
+STDMETHODIMP CVMR9AllocatorPresenter::StopPresenting(DWORD_PTR dwUserID)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CVMR9AllocatorPresenter::PresentImage(DWORD_PTR dwUserID, VMR9PresentationInfo* lpPresInfo)
+{
+ CheckPointer(m_pIVMRSurfAllocNotify, E_UNEXPECTED);
+
+ HRESULT hr;
+
+ if(!lpPresInfo || !lpPresInfo->lpSurf)
+ return E_POINTER;
+
+ CAutoLock cAutoLock(this);
+
+ CComPtr<IDirect3DTexture9> pTexture;
+ lpPresInfo->lpSurf->GetContainer(IID_IDirect3DTexture9, (void**)&pTexture);
+
+ if(pTexture)
+ {
+ m_pVideoSurface[0] = lpPresInfo->lpSurf;
+ if(m_pVideoTexture[0]) m_pVideoTexture[0] = pTexture;
+ }
+ else
+ {
+ hr = m_pD3DDev->StretchRect(lpPresInfo->lpSurf, NULL, m_pVideoSurface[0], NULL, D3DTEXF_NONE);
+ }
+
+ if(lpPresInfo->rtEnd > lpPresInfo->rtStart)
+ {
+ REFERENCE_TIME rtTimePerFrame = lpPresInfo->rtEnd - lpPresInfo->rtStart;
+ m_fps = 10000000.0 / rtTimePerFrame;
+
+ if(m_pSubPicQueue)
+ {
+ m_pSubPicQueue->SetFPS(m_fps);
+
+ if(m_fUseInternalTimer)
+ {
+ __super::SetTime(g_tSegmentStart + g_tSampleStart);
+ }
+ }
+ }
+
+ CSize VideoSize = m_NativeVideoSize;
+ int arx = lpPresInfo->szAspectRatio.cx, ary = lpPresInfo->szAspectRatio.cy;
+ if(arx > 0 && ary > 0) VideoSize.cx = VideoSize.cy*arx/ary;
+ if(VideoSize != GetVideoSize())
+ {
+ m_AspectRatio.SetSize(arx, ary);
+ AfxGetApp()->m_pMainWnd->PostMessage(WM_REARRANGERENDERLESS);
+ }
+
+ // Tear test bars
+ if (AfxGetMyApp()->m_fTearingTest)
+ {
+ RECT rcTearing;
+
+ rcTearing.left = m_nTearingPos;
+ rcTearing.top = 0;
+ rcTearing.right = rcTearing.left + 4;
+ rcTearing.bottom = m_NativeVideoSize.cy;
+ m_pD3DDev->ColorFill (m_pVideoSurface[0], &rcTearing, D3DCOLOR_ARGB (255,255,0,0));
+
+ rcTearing.left = (rcTearing.right + 15) % m_NativeVideoSize.cx;
+ rcTearing.right = rcTearing.left + 4;
+ m_pD3DDev->ColorFill (m_pVideoSurface[0], &rcTearing, D3DCOLOR_ARGB (255,255,0,0));
+
+ m_nTearingPos = (m_nTearingPos + 7) % m_NativeVideoSize.cx;
+ }
+
+ Paint(true);
+
+ return S_OK;
+}
+
+// IVMRWindowlessControl9
+//
+// It is only implemented (partially) for the dvd navigator's
+// menu handling, which needs to know a few things about the
+// location of our window.
+
+STDMETHODIMP CVMR9AllocatorPresenter::GetNativeVideoSize(LONG* lpWidth, LONG* lpHeight, LONG* lpARWidth, LONG* lpARHeight)
+{
+ if(lpWidth) *lpWidth = m_NativeVideoSize.cx;
+ if(lpHeight) *lpHeight = m_NativeVideoSize.cy;
+ if(lpARWidth) *lpARWidth = m_AspectRatio.cx;
+ if(lpARHeight) *lpARHeight = m_AspectRatio.cy;
+ return S_OK;
+}
+STDMETHODIMP CVMR9AllocatorPresenter::GetMinIdealVideoSize(LONG* lpWidth, LONG* lpHeight) {return E_NOTIMPL;}
+STDMETHODIMP CVMR9AllocatorPresenter::GetMaxIdealVideoSize(LONG* lpWidth, LONG* lpHeight) {return E_NOTIMPL;}
+STDMETHODIMP CVMR9AllocatorPresenter::SetVideoPosition(const LPRECT lpSRCRect, const LPRECT lpDSTRect) {return E_NOTIMPL;} // we have our own method for this
+STDMETHODIMP CVMR9AllocatorPresenter::GetVideoPosition(LPRECT lpSRCRect, LPRECT lpDSTRect)
+{
+ CopyRect(lpSRCRect, CRect(CPoint(0, 0), m_NativeVideoSize));
+ CopyRect(lpDSTRect, &m_VideoRect);
+ return S_OK;
+}
+STDMETHODIMP CVMR9AllocatorPresenter::GetAspectRatioMode(DWORD* lpAspectRatioMode)
+{
+ if(lpAspectRatioMode) *lpAspectRatioMode = AM_ARMODE_STRETCHED;
+ return S_OK;
+}
+STDMETHODIMP CVMR9AllocatorPresenter::SetAspectRatioMode(DWORD AspectRatioMode) {return E_NOTIMPL;}
+STDMETHODIMP CVMR9AllocatorPresenter::SetVideoClippingWindow(HWND hwnd) {return E_NOTIMPL;}
+STDMETHODIMP CVMR9AllocatorPresenter::RepaintVideo(HWND hwnd, HDC hdc) {return E_NOTIMPL;}
+STDMETHODIMP CVMR9AllocatorPresenter::DisplayModeChanged() {return E_NOTIMPL;}
+STDMETHODIMP CVMR9AllocatorPresenter::GetCurrentImage(BYTE** lpDib) {return E_NOTIMPL;}
+STDMETHODIMP CVMR9AllocatorPresenter::SetBorderColor(COLORREF Clr) {return E_NOTIMPL;}
+STDMETHODIMP CVMR9AllocatorPresenter::GetBorderColor(COLORREF* lpClr)
+{
+ if(lpClr) *lpClr = 0;
+ return S_OK;
+}
+
+//
+// CRM9AllocatorPresenter
+//
+
+CRM9AllocatorPresenter::CRM9AllocatorPresenter(HWND hWnd, HRESULT& hr)
+ : CDX9AllocatorPresenter(hWnd, hr)
+{
+}
+
+STDMETHODIMP CRM9AllocatorPresenter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ CheckPointer(ppv, E_POINTER);
+
+ return
+ QI2(IRMAVideoSurface)
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+HRESULT CRM9AllocatorPresenter::AllocSurfaces()
+{
+ CAutoLock cAutoLock(this);
+
+ m_pVideoSurfaceOff = NULL;
+ m_pVideoSurfaceYUY2 = NULL;
+
+ HRESULT hr;
+
+ if(FAILED(hr = m_pD3DDev->CreateOffscreenPlainSurface(
+ m_NativeVideoSize.cx, m_NativeVideoSize.cy, D3DFMT_X8R8G8B8,
+ D3DPOOL_DEFAULT, &m_pVideoSurfaceOff, NULL)))
+ return hr;
+
+ m_pD3DDev->ColorFill(m_pVideoSurfaceOff, NULL, 0);
+
+ if(FAILED(hr = m_pD3DDev->CreateOffscreenPlainSurface(
+ m_NativeVideoSize.cx, m_NativeVideoSize.cy, D3DFMT_YUY2,
+ D3DPOOL_DEFAULT, &m_pVideoSurfaceYUY2, NULL)))
+ m_pVideoSurfaceYUY2 = NULL;
+
+ if(m_pVideoSurfaceYUY2)
+ {
+ m_pD3DDev->ColorFill(m_pVideoSurfaceOff, NULL, 0x80108010);
+ }
+
+ return __super::AllocSurfaces();
+}
+
+void CRM9AllocatorPresenter::DeleteSurfaces()
+{
+ CAutoLock cAutoLock(this);
+ m_pVideoSurfaceOff = NULL;
+ m_pVideoSurfaceYUY2 = NULL;
+ __super::DeleteSurfaces();
+}
+
+// IRMAVideoSurface
+
+STDMETHODIMP CRM9AllocatorPresenter::Blt(UCHAR* pImageData, RMABitmapInfoHeader* pBitmapInfo, REF(PNxRect) inDestRect, REF(PNxRect) inSrcRect)
+{
+ if(!m_pVideoSurface || !m_pVideoSurfaceOff)
+ return E_FAIL;
+
+ bool fRGB = false;
+ bool fYUY2 = false;
+
+ CRect src((RECT*)&inSrcRect), dst((RECT*)&inDestRect), src2(CPoint(0,0), src.Size());
+ if(src.Width() > dst.Width() || src.Height() > dst.Height())
+ return E_FAIL;
+
+ D3DSURFACE_DESC d3dsd;
+ ZeroMemory(&d3dsd, sizeof(d3dsd));
+ if(FAILED(m_pVideoSurfaceOff->GetDesc(&d3dsd)))
+ return E_FAIL;
+
+ int dbpp =
+ d3dsd.Format == D3DFMT_R8G8B8 || d3dsd.Format == D3DFMT_X8R8G8B8 || d3dsd.Format == D3DFMT_A8R8G8B8 ? 32 :
+ d3dsd.Format == D3DFMT_R5G6B5 ? 16 : 0;
+
+ if(pBitmapInfo->biCompression == '024I')
+ {
+ DWORD pitch = pBitmapInfo->biWidth;
+ DWORD size = pitch*abs(pBitmapInfo->biHeight);
+
+ BYTE* y = pImageData + src.top*pitch + src.left;
+ BYTE* u = pImageData + size + src.top*(pitch/2) + src.left/2;
+ BYTE* v = pImageData + size + size/4 + src.top*(pitch/2) + src.left/2;
+
+ if(m_pVideoSurfaceYUY2)
+ {
+ D3DLOCKED_RECT r;
+ if(SUCCEEDED(m_pVideoSurfaceYUY2->LockRect(&r, src2, 0)))
+ {
+ BitBltFromI420ToYUY2(src.Width(), src.Height(), (BYTE*)r.pBits, r.Pitch, y, u, v, pitch);
+ m_pVideoSurfaceYUY2->UnlockRect();
+ fYUY2 = true;
+ }
+ }
+ else
+ {
+ D3DLOCKED_RECT r;
+ if(SUCCEEDED(m_pVideoSurfaceOff->LockRect(&r, src2, 0)))
+ {
+ BitBltFromI420ToRGB(src.Width(), src.Height(), (BYTE*)r.pBits, r.Pitch, dbpp, y, u, v, pitch);
+ m_pVideoSurfaceOff->UnlockRect();
+ fRGB = true;
+ }
+ }
+ }
+ else if(pBitmapInfo->biCompression == '2YUY')
+ {
+ DWORD w = pBitmapInfo->biWidth;
+ DWORD h = abs(pBitmapInfo->biHeight);
+ DWORD pitch = pBitmapInfo->biWidth*2;
+
+ BYTE* yvyu = pImageData + src.top*pitch + src.left*2;
+
+ if(m_pVideoSurfaceYUY2)
+ {
+ D3DLOCKED_RECT r;
+ if(SUCCEEDED(m_pVideoSurfaceYUY2->LockRect(&r, src2, 0)))
+ {
+ BitBltFromYUY2ToYUY2(src.Width(), src.Height(), (BYTE*)r.pBits, r.Pitch, yvyu, pitch);
+ m_pVideoSurfaceYUY2->UnlockRect();
+ fYUY2 = true;
+ }
+ }
+ else
+ {
+ D3DLOCKED_RECT r;
+ if(SUCCEEDED(m_pVideoSurfaceOff->LockRect(&r, src2, 0)))
+ {
+ BitBltFromYUY2ToRGB(src.Width(), src.Height(), (BYTE*)r.pBits, r.Pitch, dbpp, yvyu, pitch);
+ m_pVideoSurfaceOff->UnlockRect();
+ fRGB = true;
+ }
+ }
+ }
+ else if(pBitmapInfo->biCompression == 0 || pBitmapInfo->biCompression == 3
+ || pBitmapInfo->biCompression == 'BGRA')
+ {
+ DWORD w = pBitmapInfo->biWidth;
+ DWORD h = abs(pBitmapInfo->biHeight);
+ DWORD pitch = pBitmapInfo->biWidth*pBitmapInfo->biBitCount>>3;
+
+ BYTE* rgb = pImageData + src.top*pitch + src.left*(pBitmapInfo->biBitCount>>3);
+
+ D3DLOCKED_RECT r;
+ if(SUCCEEDED(m_pVideoSurfaceOff->LockRect(&r, src2, 0)))
+ {
+ BYTE* pBits = (BYTE*)r.pBits;
+ if(pBitmapInfo->biHeight > 0) {pBits += r.Pitch*(src.Height()-1); r.Pitch = -r.Pitch;}
+ BitBltFromRGBToRGB(src.Width(), src.Height(), pBits, r.Pitch, dbpp, rgb, pitch, pBitmapInfo->biBitCount);
+ m_pVideoSurfaceOff->UnlockRect();
+ fRGB = true;
+ }
+ }
+
+ if(!fRGB && !fYUY2)
+ {
+ m_pD3DDev->ColorFill(m_pVideoSurfaceOff, NULL, 0);
+
+ HDC hDC;
+ if(SUCCEEDED(m_pVideoSurfaceOff->GetDC(&hDC)))
+ {
+ CString str;
+ str.Format(_T("Sorry, this format is not supported"));
+
+ SetBkColor(hDC, 0);
+ SetTextColor(hDC, 0x404040);
+ TextOut(hDC, 10, 10, str, str.GetLength());
+
+ m_pVideoSurfaceOff->ReleaseDC(hDC);
+
+ fRGB = true;
+ }
+ }
+
+ HRESULT hr;
+
+ if(fRGB)
+ hr = m_pD3DDev->StretchRect(m_pVideoSurfaceOff, src2, m_pVideoSurface[0], dst, D3DTEXF_NONE);
+ if(fYUY2)
+ hr = m_pD3DDev->StretchRect(m_pVideoSurfaceYUY2, src2, m_pVideoSurface[0], dst, D3DTEXF_NONE);
+
+ Paint(true);
+
+ return PNR_OK;
+}
+
+STDMETHODIMP CRM9AllocatorPresenter::BeginOptimizedBlt(RMABitmapInfoHeader* pBitmapInfo)
+{
+ CAutoLock cAutoLock(this);
+ DeleteSurfaces();
+ m_NativeVideoSize = m_AspectRatio = CSize(pBitmapInfo->biWidth, abs(pBitmapInfo->biHeight));
+ if(FAILED(AllocSurfaces())) return E_FAIL;
+ return PNR_NOTIMPL;
+}
+
+STDMETHODIMP CRM9AllocatorPresenter::OptimizedBlt(UCHAR* pImageBits, REF(PNxRect) rDestRect, REF(PNxRect) rSrcRect)
+{
+ return PNR_NOTIMPL;
+}
+
+STDMETHODIMP CRM9AllocatorPresenter::EndOptimizedBlt()
+{
+ return PNR_NOTIMPL;
+}
+
+STDMETHODIMP CRM9AllocatorPresenter::GetOptimizedFormat(REF(RMA_COMPRESSION_TYPE) ulType)
+{
+ return PNR_NOTIMPL;
+}
+
+STDMETHODIMP CRM9AllocatorPresenter::GetPreferredFormat(REF(RMA_COMPRESSION_TYPE) ulType)
+{
+ ulType = RMA_I420;
+ return PNR_OK;
+}
+
+//
+// CQT9AllocatorPresenter
+//
+
+CQT9AllocatorPresenter::CQT9AllocatorPresenter(HWND hWnd, HRESULT& hr)
+ : CDX9AllocatorPresenter(hWnd, hr)
+{
+}
+
+STDMETHODIMP CQT9AllocatorPresenter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ CheckPointer(ppv, E_POINTER);
+
+ return
+ QI(IQTVideoSurface)
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+HRESULT CQT9AllocatorPresenter::AllocSurfaces()
+{
+ HRESULT hr;
+
+ m_pVideoSurfaceOff = NULL;
+
+ if(FAILED(hr = m_pD3DDev->CreateOffscreenPlainSurface(
+ m_NativeVideoSize.cx, m_NativeVideoSize.cy, D3DFMT_X8R8G8B8,
+ D3DPOOL_DEFAULT, &m_pVideoSurfaceOff, NULL)))
+ return hr;
+
+ return __super::AllocSurfaces();
+}
+
+void CQT9AllocatorPresenter::DeleteSurfaces()
+{
+ m_pVideoSurfaceOff = NULL;
+
+ __super::DeleteSurfaces();
+}
+
+// IQTVideoSurface
+
+STDMETHODIMP CQT9AllocatorPresenter::BeginBlt(const BITMAP& bm)
+{
+ CAutoLock cAutoLock(this);
+ DeleteSurfaces();
+ m_NativeVideoSize = m_AspectRatio = CSize(bm.bmWidth, abs(bm.bmHeight));
+ if(FAILED(AllocSurfaces())) return E_FAIL;
+ return S_OK;
+}
+
+STDMETHODIMP CQT9AllocatorPresenter::DoBlt(const BITMAP& bm)
+{
+ if(!m_pVideoSurface || !m_pVideoSurfaceOff)
+ return E_FAIL;
+
+ bool fOk = false;
+
+ D3DSURFACE_DESC d3dsd;
+ ZeroMemory(&d3dsd, sizeof(d3dsd));
+ if(FAILED(m_pVideoSurfaceOff->GetDesc(&d3dsd)))
+ return E_FAIL;
+
+ int w = bm.bmWidth;
+ int h = abs(bm.bmHeight);
+ int bpp = bm.bmBitsPixel;
+ int dbpp =
+ d3dsd.Format == D3DFMT_R8G8B8 || d3dsd.Format == D3DFMT_X8R8G8B8 || d3dsd.Format == D3DFMT_A8R8G8B8 ? 32 :
+ d3dsd.Format == D3DFMT_R5G6B5 ? 16 : 0;
+
+ if((bpp == 16 || bpp == 24 || bpp == 32) && w == d3dsd.Width && h == d3dsd.Height)
+ {
+ D3DLOCKED_RECT r;
+ if(SUCCEEDED(m_pVideoSurfaceOff->LockRect(&r, NULL, 0)))
+ {
+ BitBltFromRGBToRGB(
+ w, h,
+ (BYTE*)r.pBits, r.Pitch, dbpp,
+ (BYTE*)bm.bmBits, bm.bmWidthBytes, bm.bmBitsPixel);
+ m_pVideoSurfaceOff->UnlockRect();
+ fOk = true;
+ }
+ }
+
+ if(!fOk)
+ {
+ m_pD3DDev->ColorFill(m_pVideoSurfaceOff, NULL, 0);
+
+ HDC hDC;
+ if(SUCCEEDED(m_pVideoSurfaceOff->GetDC(&hDC)))
+ {
+ CString str;
+ str.Format(_T("Sorry, this color format is not supported"));
+
+ SetBkColor(hDC, 0);
+ SetTextColor(hDC, 0x404040);
+ TextOut(hDC, 10, 10, str, str.GetLength());
+
+ m_pVideoSurfaceOff->ReleaseDC(hDC);
+ }
+ }
+
+ m_pD3DDev->StretchRect(m_pVideoSurfaceOff, NULL, m_pVideoSurface[0], NULL, D3DTEXF_NONE);
+
+ Paint(true);
+
+ return S_OK;
+}
+
+//
+// CDXRAllocatorPresenter
+//
+
+CDXRAllocatorPresenter::CDXRAllocatorPresenter(HWND hWnd, HRESULT& hr)
+ : ISubPicAllocatorPresenterImpl(hWnd, hr)
+{
+ if(FAILED(hr)) return;
+
+ hr = S_OK;
+}
+
+CDXRAllocatorPresenter::~CDXRAllocatorPresenter()
+{
+ if(m_pSRCB)
+ {
+ // nasty, but we have to let it know about our death somehow
+ ((CSubRenderCallback*)(ISubRenderCallback*)m_pSRCB)->SetDXRAP(NULL);
+ }
+
+ // the order is important here
+ m_pSubPicQueue = NULL;
+ m_pAllocator = NULL;
+ m_pDXR = NULL;
+}
+
+STDMETHODIMP CDXRAllocatorPresenter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+/*
+ if(riid == __uuidof(IVideoWindow))
+ return GetInterface((IVideoWindow*)this, ppv);
+ if(riid == __uuidof(IBasicVideo))
+ return GetInterface((IBasicVideo*)this, ppv);
+ if(riid == __uuidof(IBasicVideo2))
+ return GetInterface((IBasicVideo2*)this, ppv);
+*/
+/*
+ if(riid == __uuidof(IVMRWindowlessControl))
+ return GetInterface((IVMRWindowlessControl*)this, ppv);
+*/
+
+ if(riid != IID_IUnknown && m_pDXR)
+ {
+ if(SUCCEEDED(m_pDXR->QueryInterface(riid, ppv)))
+ return S_OK;
+ }
+
+ return __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+HRESULT CDXRAllocatorPresenter::SetDevice(IDirect3DDevice9* pD3DDev)
+{
+ CheckPointer(pD3DDev, E_POINTER);
+
+ CSize size;
+ switch(AfxGetAppSettings().nSPCMaxRes)
+ {
+ // TODO: m_ScreenSize ?
+ // case 0: default: size = m_ScreenSize; break;
+ default:
+ case 1: size.SetSize(1024, 768); break;
+ case 2: size.SetSize(800, 600); break;
+ case 3: size.SetSize(640, 480); break;
+ case 4: size.SetSize(512, 384); break;
+ case 5: size.SetSize(384, 288); break;
+ }
+
+ if(m_pAllocator)
+ {
+ m_pAllocator->ChangeDevice(pD3DDev);
+ }
+ else
+ {
+ m_pAllocator = new CDX9SubPicAllocator(pD3DDev, size, AfxGetAppSettings().fSPCPow2Tex);
+ if(!m_pAllocator)
+ return E_FAIL;
+ }
+
+ HRESULT hr = S_OK;
+
+ m_pSubPicQueue = AfxGetAppSettings().nSPCSize > 0
+ ? (ISubPicQueue*)new CSubPicQueue(AfxGetAppSettings().nSPCSize, m_pAllocator, &hr)
+ : (ISubPicQueue*)new CSubPicQueueNoThread(m_pAllocator, &hr);
+ if(!m_pSubPicQueue || FAILED(hr))
+ return E_FAIL;
+
+ if(m_SubPicProvider) m_pSubPicQueue->SetSubPicProvider(m_SubPicProvider);
+
+ return S_OK;
+}
+
+HRESULT CDXRAllocatorPresenter::Render(
+ REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, REFERENCE_TIME atpf,
+ int left, int top, int right, int bottom, int width, int height)
+{
+ __super::SetPosition(CRect(0, 0, width, height), CRect(left, top, right, bottom)); // needed? should be already set by the player
+ SetTime(rtStart);
+ if(atpf > 0 && m_pSubPicQueue) m_pSubPicQueue->SetFPS(10000000.0 / atpf);
+ AlphaBltSubPic(CSize(width, height));
+ return S_OK;
+}
+
+// ISubPicAllocatorPresenter
+
+STDMETHODIMP CDXRAllocatorPresenter::CreateRenderer(IUnknown** ppRenderer)
+{
+ CheckPointer(ppRenderer, E_POINTER);
+
+ if(m_pDXR) return E_UNEXPECTED;
+ m_pDXR.CoCreateInstance(CLSID_DXR, GetOwner());
+ if(!m_pDXR) return E_FAIL;
+
+ CComQIPtr<ISubRender> pSR = m_pDXR;
+ if(!pSR) {m_pDXR = NULL; return E_FAIL;}
+
+ m_pSRCB = new CSubRenderCallback(this);
+ if(FAILED(pSR->SetCallback(m_pSRCB))) {m_pDXR = NULL; return E_FAIL;}
+
+ (*ppRenderer = this)->AddRef();
+
+ return S_OK;
+}
+
+STDMETHODIMP_(void) CDXRAllocatorPresenter::SetPosition(RECT w, RECT v)
+{
+ if(CComQIPtr<IBasicVideo> pBV = m_pDXR)
+ {
+ pBV->SetDefaultSourcePosition();
+ pBV->SetDestinationPosition(v.left, v.top, v.right - v.left, v.bottom - v.top);
+ }
+
+ if(CComQIPtr<IVideoWindow> pVW = m_pDXR)
+ {
+ pVW->SetWindowPosition(w.left, w.top, w.right - w.left, w.bottom - w.top);
+ }
+}
+
+STDMETHODIMP_(SIZE) CDXRAllocatorPresenter::GetVideoSize(bool fCorrectAR)
+{
+ SIZE size = {0, 0};
+
+ if(!fCorrectAR)
+ {
+ if(CComQIPtr<IBasicVideo> pBV = m_pDXR)
+ pBV->GetVideoSize(&size.cx, &size.cy);
+ }
+ else
+ {
+ if(CComQIPtr<IBasicVideo2> pBV2 = m_pDXR)
+ pBV2->GetPreferredAspectRatio(&size.cx, &size.cy);
+ }
+
+ return size;
+}
+
+STDMETHODIMP_(bool) CDXRAllocatorPresenter::Paint(bool fAll)
+{
+ return false; // TODO
+}
+
+STDMETHODIMP CDXRAllocatorPresenter::GetDIB(BYTE* lpDib, DWORD* size)
+{
+ HRESULT hr = E_NOTIMPL;
+ if(CComQIPtr<IBasicVideo> pBV = m_pDXR)
+ hr = pBV->GetCurrentImage((long*)size, (long*)lpDib);
+ return hr;
+}
+
+STDMETHODIMP CDXRAllocatorPresenter::SetPixelShader(LPCSTR pSrcData, LPCSTR pTarget)
+{
+ return E_NOTIMPL; // TODO
+}
+
diff --git a/src/apps/mplayerc/DX9AllocatorPresenter.h b/src/apps/mplayerc/DX9AllocatorPresenter.h
new file mode 100644
index 000000000..0d6046408
--- /dev/null
+++ b/src/apps/mplayerc/DX9AllocatorPresenter.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "..\..\SubPic\ISubPic.h"
+
+// {4E4834FA-22C2-40e2-9446-F77DD05D245E}
+DEFINE_GUID(CLSID_VMR9AllocatorPresenter,
+0x4e4834fa, 0x22c2, 0x40e2, 0x94, 0x46, 0xf7, 0x7d, 0xd0, 0x5d, 0x24, 0x5e);
+
+// {A1542F93-EB53-4e11-8D34-05C57ABA9207}
+DEFINE_GUID(CLSID_RM9AllocatorPresenter,
+0xa1542f93, 0xeb53, 0x4e11, 0x8d, 0x34, 0x5, 0xc5, 0x7a, 0xba, 0x92, 0x7);
+
+// {622A4032-70CE-4040-8231-0F24F2886618}
+DEFINE_GUID(CLSID_QT9AllocatorPresenter,
+0x622a4032, 0x70ce, 0x4040, 0x82, 0x31, 0xf, 0x24, 0xf2, 0x88, 0x66, 0x18);
+
+// {B72EBDD4-831D-440f-A656-B48F5486CD82}
+DEFINE_GUID(CLSID_DXRAllocatorPresenter,
+0xb72ebdd4, 0x831d, 0x440f, 0xa6, 0x56, 0xb4, 0x8f, 0x54, 0x86, 0xcd, 0x82);
+
+extern HRESULT CreateAP9(const CLSID& clsid, HWND hWnd, ISubPicAllocatorPresenter** ppAP);
+
+extern bool IsVMR9InGraph(IFilterGraph* pFG);
diff --git a/src/apps/mplayerc/Debug Unicode/d3dx9_28.dll b/src/apps/mplayerc/Debug Unicode/d3dx9_28.dll
new file mode 100644
index 000000000..fde5bd447
--- /dev/null
+++ b/src/apps/mplayerc/Debug Unicode/d3dx9_28.dll
Binary files differ
diff --git a/src/apps/mplayerc/DeinterlacerFilter.cpp b/src/apps/mplayerc/DeinterlacerFilter.cpp
new file mode 100644
index 000000000..972b071aa
--- /dev/null
+++ b/src/apps/mplayerc/DeinterlacerFilter.cpp
@@ -0,0 +1,123 @@
+#include "stdafx.h"
+#include ".\deinterlacerfilter.h"
+#include "..\..\DSUtil\MediaTypes.h"
+#include "..\..\..\include\moreuuids.h"
+
+CDeinterlacerFilter::CDeinterlacerFilter(LPUNKNOWN punk, HRESULT* phr)
+ : CTransformFilter(NAME("CDeinterlacerFilter"), punk, __uuidof(CDeinterlacerFilter))
+{
+ if(phr) *phr = S_OK;
+}
+
+HRESULT CDeinterlacerFilter::CheckConnect(PIN_DIRECTION dir, IPin* pPin)
+{
+ return GetCLSID(pPin) == __uuidof(*this) ? E_FAIL : S_OK;
+}
+
+HRESULT CDeinterlacerFilter::CheckInputType(const CMediaType* mtIn)
+{
+ BITMAPINFOHEADER bih;
+ if(!ExtractBIH(mtIn, &bih) /*|| bih.biHeight <= 0*/ || bih.biHeight <= 288)
+ return E_FAIL;
+
+ return mtIn->subtype == MEDIASUBTYPE_YUY2 || mtIn->subtype == MEDIASUBTYPE_UYVY
+ || mtIn->subtype == MEDIASUBTYPE_I420 || mtIn->subtype == MEDIASUBTYPE_YV12 || mtIn->subtype == MEDIASUBTYPE_IYUV
+ ? S_OK
+ : E_FAIL;
+}
+
+HRESULT CDeinterlacerFilter::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
+{
+ return mtIn->subtype == mtOut->subtype ? S_OK : E_FAIL;
+}
+
+HRESULT CDeinterlacerFilter::Transform(IMediaSample* pIn, IMediaSample* pOut)
+{
+ HRESULT hr;
+
+ AM_MEDIA_TYPE* pmt = NULL;
+ if(SUCCEEDED(pOut->GetMediaType(&pmt)) && pmt)
+ {
+ CMediaType mt = *pmt;
+ m_pOutput->SetMediaType(&mt);
+ DeleteMediaType(pmt);
+ }
+
+ BYTE* pDataIn = NULL;
+ if(FAILED(pIn->GetPointer(&pDataIn)) || !pDataIn)
+ return S_FALSE;
+
+ BYTE* pDataOut = NULL;
+ if(FAILED(hr = pOut->GetPointer(&pDataOut)) || !pDataOut)
+ return hr;
+
+ const CMediaType& mtIn = m_pInput->CurrentMediaType();
+ const CMediaType& mtOut = m_pOutput->CurrentMediaType();
+
+ BITMAPINFOHEADER bihIn, bihOut;
+ ExtractBIH(&mtIn, &bihIn);
+ ExtractBIH(&mtOut, &bihOut);
+
+ bool fInputFlipped = bihIn.biHeight >= 0 && bihIn.biCompression <= 3;
+ bool fOutputFlipped = bihOut.biHeight >= 0 && bihOut.biCompression <= 3;
+ bool fFlip = fInputFlipped != fOutputFlipped;
+
+ int bppIn = !(bihIn.biBitCount&7) ? bihIn.biBitCount : 8;
+ int bppOut = !(bihOut.biBitCount&7) ? bihOut.biBitCount : 8;
+ int pitchIn = bihIn.biWidth*bppIn>>3;
+ int pitchOut = bihOut.biWidth*bppOut>>3;
+ BYTE* pDataOut2 = pDataOut;
+ if(fFlip) {pDataOut2 += pitchOut*(bihIn.biHeight-1); pitchOut = -pitchOut;}
+
+ if(mtIn.subtype == MEDIASUBTYPE_YUY2 || mtIn.subtype == MEDIASUBTYPE_UYVY)
+ {
+ DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
+ }
+ else if(mtIn.subtype == MEDIASUBTYPE_I420 || mtIn.subtype == MEDIASUBTYPE_YV12 || mtIn.subtype == MEDIASUBTYPE_IYUV)
+ {
+ DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
+
+ int sizeIn = bihIn.biHeight*pitchIn, sizeOut = abs(bihOut.biHeight)*pitchOut;
+ pitchIn /= 2; pitchOut /= 2;
+ bihIn.biHeight /= 2;
+ pDataIn += sizeIn; pDataOut += sizeOut;
+ DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
+
+ pDataIn += sizeIn/4; pDataOut += sizeOut/4;
+ DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
+ }
+
+ return S_OK;
+}
+
+HRESULT CDeinterlacerFilter::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
+{
+ if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
+
+ BITMAPINFOHEADER bih;
+ ExtractBIH(&m_pOutput->CurrentMediaType(), &bih);
+
+ pProperties->cBuffers = 1;
+ pProperties->cbBuffer = bih.biSizeImage;
+ pProperties->cbAlign = 1;
+ pProperties->cbPrefix = 0;
+
+ HRESULT hr;
+ ALLOCATOR_PROPERTIES Actual;
+ if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual)))
+ return hr;
+
+ return pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
+ ? E_FAIL
+ : NOERROR;
+}
+
+HRESULT CDeinterlacerFilter::GetMediaType(int iPosition, CMediaType* pmt)
+{
+ if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
+ if(iPosition < 0) return E_INVALIDARG;
+ if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
+ *pmt = m_pInput->CurrentMediaType();
+ CorrectMediaType(pmt);
+ return S_OK;
+} \ No newline at end of file
diff --git a/src/apps/mplayerc/DeinterlacerFilter.h b/src/apps/mplayerc/DeinterlacerFilter.h
new file mode 100644
index 000000000..d1c441ec6
--- /dev/null
+++ b/src/apps/mplayerc/DeinterlacerFilter.h
@@ -0,0 +1,16 @@
+#pragma once
+
+[uuid("96F3E0BE-1BA4-4E79-973D-191FE425C86B")]
+class CDeinterlacerFilter : public CTransformFilter
+{
+protected:
+ HRESULT CDeinterlacerFilter::CheckConnect(PIN_DIRECTION dir, IPin* pPin);
+ HRESULT CheckInputType(const CMediaType* mtIn);
+ HRESULT CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut);
+ HRESULT Transform(IMediaSample* pIn, IMediaSample* pOut);
+ HRESULT DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties);
+ HRESULT GetMediaType(int iPosition, CMediaType* pmt);
+
+public:
+ CDeinterlacerFilter(LPUNKNOWN punk, HRESULT* phr);
+};
diff --git a/src/apps/mplayerc/FGFilter.cpp b/src/apps/mplayerc/FGFilter.cpp
new file mode 100644
index 000000000..9e4ecff77
--- /dev/null
+++ b/src/apps/mplayerc/FGFilter.cpp
@@ -0,0 +1,592 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "FGFilter.h"
+#include "..\..\DSUtil\DSUtil.h"
+#include "DX7AllocatorPresenter.h"
+#include "DX9AllocatorPresenter.h"
+
+//
+// CFGFilter
+//
+
+CFGFilter::CFGFilter(const CLSID& clsid, CStringW name, UINT64 merit)
+ : m_clsid(clsid)
+ , m_name(name)
+{
+ m_merit.val = merit;
+}
+
+const CAtlList<GUID>& CFGFilter::GetTypes() const
+{
+ return m_types;
+}
+
+void CFGFilter::SetTypes(const CAtlList<GUID>& types)
+{
+ m_types.RemoveAll();
+ m_types.AddTailList(&types);
+}
+
+void CFGFilter::AddType(const GUID& majortype, const GUID& subtype)
+{
+ m_types.AddTail(majortype);
+ m_types.AddTail(subtype);
+}
+
+bool CFGFilter::CheckTypes(const CAtlArray<GUID>& types, bool fExactMatch)
+{
+ POSITION pos = m_types.GetHeadPosition();
+ while(pos)
+ {
+ const GUID& majortype = m_types.GetNext(pos);
+ if(!pos) {ASSERT(0); break;}
+ const GUID& subtype = m_types.GetNext(pos);
+
+ for(int i = 0, len = types.GetCount() & ~1; i < len; i += 2)
+ {
+ if(fExactMatch)
+ {
+ if(majortype == types[i] && majortype != GUID_NULL
+ && subtype == types[i+1] && subtype != GUID_NULL)
+ return true;
+ }
+ else
+ {
+ if((majortype == GUID_NULL || types[i] == GUID_NULL || majortype == types[i])
+ && (subtype == GUID_NULL || types[i+1] == GUID_NULL || subtype == types[i+1]))
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+//
+// CFGFilterRegistry
+//
+
+CFGFilterRegistry::CFGFilterRegistry(IMoniker* pMoniker, UINT64 merit)
+ : CFGFilter(GUID_NULL, L"", merit)
+ , m_pMoniker(pMoniker)
+{
+ if(!m_pMoniker) return;
+
+ LPOLESTR str = NULL;
+ if(FAILED(m_pMoniker->GetDisplayName(0, 0, &str))) return;
+ m_DisplayName = m_name = str;
+ CoTaskMemFree(str), str = NULL;
+
+ CComPtr<IPropertyBag> pPB;
+ if(SUCCEEDED(m_pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB)))
+ {
+ CComVariant var;
+ if(SUCCEEDED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL)))
+ {
+ m_name = var.bstrVal;
+ var.Clear();
+ }
+
+ if(SUCCEEDED(pPB->Read(CComBSTR(_T("CLSID")), &var, NULL)))
+ {
+ CLSIDFromString(var.bstrVal, &m_clsid);
+ var.Clear();
+ }
+
+ if(SUCCEEDED(pPB->Read(CComBSTR(_T("FilterData")), &var, NULL)))
+ {
+ BSTR* pstr;
+ if(SUCCEEDED(SafeArrayAccessData(var.parray, (void**)&pstr)))
+ {
+ ExtractFilterData((BYTE*)pstr, var.parray->cbElements*(var.parray->rgsabound[0].cElements));
+ SafeArrayUnaccessData(var.parray);
+ }
+
+ var.Clear();
+ }
+ }
+
+ if(merit != MERIT64_DO_USE) m_merit.val = merit;
+}
+
+CFGFilterRegistry::CFGFilterRegistry(CStringW DisplayName, UINT64 merit)
+ : CFGFilter(GUID_NULL, L"", merit)
+ , m_DisplayName(DisplayName)
+{
+ if(m_DisplayName.IsEmpty()) return;
+
+ CComPtr<IBindCtx> pBC;
+ CreateBindCtx(0, &pBC);
+
+ ULONG chEaten;
+ if(S_OK != MkParseDisplayName(pBC, CComBSTR(m_DisplayName), &chEaten, &m_pMoniker))
+ return;
+
+ CComPtr<IPropertyBag> pPB;
+ if(SUCCEEDED(m_pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB)))
+ {
+ CComVariant var;
+ if(SUCCEEDED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL)))
+ {
+ m_name = var.bstrVal;
+ var.Clear();
+ }
+
+ if(SUCCEEDED(pPB->Read(CComBSTR(_T("CLSID")), &var, NULL)))
+ {
+ CLSIDFromString(var.bstrVal, &m_clsid);
+ var.Clear();
+ }
+
+ if(SUCCEEDED(pPB->Read(CComBSTR(_T("FilterData")), &var, NULL)))
+ {
+ BSTR* pstr;
+ if(SUCCEEDED(SafeArrayAccessData(var.parray, (void**)&pstr)))
+ {
+ ExtractFilterData((BYTE*)pstr, var.parray->cbElements*(var.parray->rgsabound[0].cElements));
+ SafeArrayUnaccessData(var.parray);
+ }
+
+ var.Clear();
+ }
+ }
+
+ if(merit != MERIT64_DO_USE) m_merit.val = merit;
+}
+
+CFGFilterRegistry::CFGFilterRegistry(const CLSID& clsid, UINT64 merit)
+ : CFGFilter(clsid, L"", merit)
+{
+ if(m_clsid == GUID_NULL) return;
+
+ CString guid = CStringFromGUID(m_clsid);
+
+ CRegKey key;
+
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("CLSID\\") + guid, KEY_READ))
+ {
+ ULONG nChars = 0;
+ if(ERROR_SUCCESS == key.QueryStringValue(NULL, NULL, &nChars))
+ {
+ CString name;
+ if(ERROR_SUCCESS == key.QueryStringValue(NULL, name.GetBuffer(nChars), &nChars))
+ {
+ name.ReleaseBuffer(nChars);
+ m_name = name;
+ }
+ }
+
+ key.Close();
+ }
+
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("CLSID\\{083863F1-70DE-11d0-BD40-00A0C911CE86}\\Instance\\") + guid, KEY_READ))
+ {
+ ULONG nChars = 0;
+ if(ERROR_SUCCESS == key.QueryStringValue(_T("FriendlyName"), NULL, &nChars))
+ {
+ CString name;
+ if(ERROR_SUCCESS == key.QueryStringValue(_T("FriendlyName"), name.GetBuffer(nChars), &nChars))
+ {
+ name.ReleaseBuffer(nChars);
+ m_name = name;
+ }
+ }
+
+ ULONG nBytes = 0;
+ if(ERROR_SUCCESS == key.QueryBinaryValue(_T("FilterData"), NULL, &nBytes))
+ {
+ CAutoVectorPtr<BYTE> buff;
+ if(buff.Allocate(nBytes) && ERROR_SUCCESS == key.QueryBinaryValue(_T("FilterData"), buff, &nBytes))
+ {
+ ExtractFilterData(buff, nBytes);
+ }
+ }
+
+ key.Close();
+ }
+
+ if(merit != MERIT64_DO_USE) m_merit.val = merit;
+}
+
+HRESULT CFGFilterRegistry::Create(IBaseFilter** ppBF, IUnknown** ppUnk)
+{
+ CheckPointer(ppBF, E_POINTER);
+
+ if(ppUnk) *ppUnk = NULL;
+
+ HRESULT hr = E_FAIL;
+
+ if(m_pMoniker)
+ {
+ if(SUCCEEDED(hr = m_pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)ppBF)))
+ {
+ m_clsid = ::GetCLSID(*ppBF);
+ }
+ }
+ else if(m_clsid != GUID_NULL)
+ {
+ CComPtr<IBaseFilter> pBF;
+ if(FAILED(pBF.CoCreateInstance(m_clsid))) return E_FAIL;
+ *ppBF = pBF.Detach();
+ hr = S_OK;
+ }
+
+ return hr;
+};
+
+[uuid("97f7c4d4-547b-4a5f-8332-536430ad2e4d")]
+interface IAMFilterData : public IUnknown
+{
+ STDMETHOD (ParseFilterData) (BYTE* rgbFilterData, ULONG cb, BYTE** prgbRegFilter2) PURE;
+ STDMETHOD (CreateFilterData) (REGFILTER2* prf2, BYTE** prgbFilterData, ULONG* pcb) PURE;
+};
+
+void CFGFilterRegistry::ExtractFilterData(BYTE* p, UINT len)
+{
+ CComPtr<IAMFilterData> pFD;
+ BYTE* ptr = NULL;
+
+ if(SUCCEEDED(pFD.CoCreateInstance(CLSID_FilterMapper2))
+ && SUCCEEDED(pFD->ParseFilterData(p, len, (BYTE**)&ptr)))
+ {
+ REGFILTER2* prf = (REGFILTER2*)*(DWORD*)ptr; // this is f*cked up
+
+ m_merit.mid = prf->dwMerit;
+
+ if(prf->dwVersion == 1)
+ {
+ for(UINT i = 0; i < prf->cPins; i++)
+ {
+ if(prf->rgPins[i].bOutput)
+ continue;
+
+ for(UINT j = 0; j < prf->rgPins[i].nMediaTypes; j++)
+ {
+ if(!prf->rgPins[i].lpMediaType[j].clsMajorType || !prf->rgPins[i].lpMediaType[j].clsMinorType)
+ break;
+
+ const REGPINTYPES& rpt = prf->rgPins[i].lpMediaType[j];
+ AddType(*rpt.clsMajorType, *rpt.clsMinorType);
+ }
+ }
+ }
+ else if(prf->dwVersion == 2)
+ {
+ for(UINT i = 0; i < prf->cPins2; i++)
+ {
+ if(prf->rgPins2[i].dwFlags&REG_PINFLAG_B_OUTPUT)
+ continue;
+
+ for(UINT j = 0; j < prf->rgPins2[i].nMediaTypes; j++)
+ {
+ if(!prf->rgPins2[i].lpMediaType[j].clsMajorType || !prf->rgPins2[i].lpMediaType[j].clsMinorType)
+ break;
+
+ const REGPINTYPES& rpt = prf->rgPins2[i].lpMediaType[j];
+ AddType(*rpt.clsMajorType, *rpt.clsMinorType);
+ }
+ }
+ }
+
+ CoTaskMemFree(prf);
+ }
+ else
+ {
+ BYTE* base = p;
+
+ #define ChkLen(size) if(p - base + size > (int)len) return;
+
+ ChkLen(4)
+ if(*(DWORD*)p != 0x00000002) return; // only version 2 supported, no samples found for 1
+ p += 4;
+
+ ChkLen(4)
+ m_merit.mid = *(DWORD*)p; p += 4;
+
+ m_types.RemoveAll();
+
+ ChkLen(8)
+ DWORD nPins = *(DWORD*)p; p += 8;
+ while(nPins-- > 0)
+ {
+ ChkLen(1)
+ BYTE n = *p-0x30; p++;
+
+ ChkLen(2)
+ WORD pi = *(WORD*)p; p += 2;
+ ASSERT(pi == 'ip');
+
+ ChkLen(1)
+ BYTE x33 = *p; p++;
+ ASSERT(x33 == 0x33);
+
+ ChkLen(8)
+ bool fOutput = !!(*p&REG_PINFLAG_B_OUTPUT);
+ p += 8;
+
+ ChkLen(12)
+ DWORD nTypes = *(DWORD*)p; p += 12;
+ while(nTypes-- > 0)
+ {
+ ChkLen(1)
+ BYTE n = *p-0x30; p++;
+
+ ChkLen(2)
+ WORD ty = *(WORD*)p; p += 2;
+ ASSERT(ty == 'yt');
+
+ ChkLen(5)
+ BYTE x33 = *p; p++;
+ ASSERT(x33 == 0x33);
+ p += 4;
+
+ ChkLen(8)
+ if(*(DWORD*)p < (p-base+8) || *(DWORD*)p >= len
+ || *(DWORD*)(p+4) < (p-base+8) || *(DWORD*)(p+4) >= len)
+ {
+ p += 8;
+ continue;
+ }
+
+ GUID majortype, subtype;
+ memcpy(&majortype, &base[*(DWORD*)p], sizeof(GUID)); p += 4;
+ if(!fOutput) AddType(majortype, subtype);
+ }
+ }
+
+ #undef ChkLen
+ }
+}
+
+//
+// CFGFilterFile
+//
+
+CFGFilterFile::CFGFilterFile(const CLSID& clsid, CString path, CStringW name, UINT64 merit)
+ : CFGFilter(clsid, name, merit)
+ , m_path(path)
+ , m_hInst(NULL)
+{
+}
+
+HRESULT CFGFilterFile::Create(IBaseFilter** ppBF, IUnknown** ppUnk)
+{
+ CheckPointer(ppBF, E_POINTER);
+
+ if(ppUnk) *ppUnk = NULL;
+
+ return LoadExternalFilter(m_path, m_clsid, ppBF);
+}
+
+//
+// CFGFilterVideoRenderer
+//
+
+CFGFilterVideoRenderer::CFGFilterVideoRenderer(HWND hWnd, const CLSID& clsid, CStringW name, UINT64 merit)
+ : CFGFilter(clsid, name, merit)
+ , m_hWnd(hWnd)
+{
+ AddType(MEDIATYPE_Video, MEDIASUBTYPE_NULL);
+}
+
+HRESULT CFGFilterVideoRenderer::Create(IBaseFilter** ppBF, IUnknown** ppUnk)
+{
+ CheckPointer(ppBF, E_POINTER);
+
+ HRESULT hr = S_OK;
+
+ CComPtr<ISubPicAllocatorPresenter> pCAP;
+
+ if(m_clsid == CLSID_VMR7AllocatorPresenter
+ || m_clsid == CLSID_VMR9AllocatorPresenter
+ || m_clsid == CLSID_DXRAllocatorPresenter)
+ {
+ if(SUCCEEDED(CreateAP7(m_clsid, m_hWnd, &pCAP))
+ || SUCCEEDED(CreateAP9(m_clsid, m_hWnd, &pCAP)))
+ {
+ CComPtr<IUnknown> pRenderer;
+ if(SUCCEEDED(hr = pCAP->CreateRenderer(&pRenderer)))
+ {
+ *ppBF = CComQIPtr<IBaseFilter>(pRenderer).Detach();
+ if(ppUnk) *ppUnk = (IUnknown*)pCAP.Detach();
+ }
+ }
+ }
+ else
+ {
+ CComPtr<IBaseFilter> pBF;
+ if(SUCCEEDED(pBF.CoCreateInstance(m_clsid)))
+ {
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ if(CComQIPtr<IMixerPinConfig, &IID_IMixerPinConfig> pMPC = pPin)
+ {
+ if(ppUnk) *ppUnk = pMPC.Detach();
+ break;
+ }
+ }
+ EndEnumPins
+
+ *ppBF = pBF.Detach();
+ }
+ }
+
+ if(!*ppBF) hr = E_FAIL;
+
+ return hr;
+}
+
+//
+// CFGFilterList
+//
+
+CFGFilterList::CFGFilterList()
+{
+}
+
+CFGFilterList::~CFGFilterList()
+{
+ RemoveAll();
+}
+
+void CFGFilterList::RemoveAll()
+{
+ while(!m_filters.IsEmpty())
+ {
+ const filter_t& f = m_filters.RemoveHead();
+ if(f.autodelete) delete f.pFGF;
+ }
+
+ m_sortedfilters.RemoveAll();
+}
+
+void CFGFilterList::Insert(CFGFilter* pFGF, int group, bool exactmatch, bool autodelete)
+{
+ if(CFGFilterRegistry* f1r = dynamic_cast<CFGFilterRegistry*>(pFGF))
+ {
+ POSITION pos = m_filters.GetHeadPosition();
+ while(pos)
+ {
+ filter_t& f2 = m_filters.GetNext(pos);
+
+ if(group != f2.group) continue;
+
+ if(CFGFilterRegistry* f2r = dynamic_cast<CFGFilterRegistry*>(f2.pFGF))
+ {
+ if(f1r->GetMoniker() && f2r->GetMoniker() && S_OK == f1r->GetMoniker()->IsEqual(f2r->GetMoniker())
+ || f1r->GetCLSID() != GUID_NULL && f1r->GetCLSID() == f2r->GetCLSID())
+ {
+ TRACE(_T("FGM: Inserting %d %d %016I64x '%s' NOT!\n"),
+ group, exactmatch, pFGF->GetMerit(),
+ pFGF->GetName().IsEmpty() ? CStringFromGUID(pFGF->GetCLSID()) : CString(pFGF->GetName()));
+
+ if(autodelete) delete pFGF;
+ return;
+ }
+ }
+ }
+ }
+
+ POSITION pos = m_filters.GetHeadPosition();
+ while(pos)
+ {
+ if(m_filters.GetNext(pos).pFGF == pFGF)
+ {
+ TRACE(_T("FGM: Inserting %d %d %016I64x '%s' DUP!\n"),
+ group, exactmatch, pFGF->GetMerit(),
+ pFGF->GetName().IsEmpty() ? CStringFromGUID(pFGF->GetCLSID()) : CString(pFGF->GetName()));
+
+ if(autodelete) delete pFGF;
+ return;
+ }
+ }
+
+ TRACE(_T("FGM: Inserting %d %d %016I64x '%s'\n"),
+ group, exactmatch, pFGF->GetMerit(),
+ pFGF->GetName().IsEmpty() ? CStringFromGUID(pFGF->GetCLSID()) : CString(pFGF->GetName()));
+
+ filter_t f = {m_filters.GetCount(), pFGF, group, exactmatch, autodelete};
+ m_filters.AddTail(f);
+
+ m_sortedfilters.RemoveAll();
+}
+
+POSITION CFGFilterList::GetHeadPosition()
+{
+ if(m_sortedfilters.IsEmpty())
+ {
+ CAtlArray<filter_t> sort;
+ sort.SetCount(m_filters.GetCount());
+ POSITION pos = m_filters.GetHeadPosition();
+ for(int i = 0; pos; i++) sort[i] = m_filters.GetNext(pos);
+ qsort(&sort[0], sort.GetCount(), sizeof(sort[0]), filter_cmp);
+ for(size_t i = 0; i < sort.GetCount(); i++)
+ if(sort[i].pFGF->GetMerit() >= MERIT64_DO_USE)
+ m_sortedfilters.AddTail(sort[i].pFGF);
+ }
+
+ TRACE(_T("FGM: Sorting filters\n"));
+
+ POSITION pos = m_sortedfilters.GetHeadPosition();
+ while(pos)
+ {
+ CFGFilter* pFGF = m_sortedfilters.GetNext(pos);
+ TRACE(_T("FGM: - %016I64x '%s'\n"), pFGF->GetMerit(), pFGF->GetName().IsEmpty() ? CStringFromGUID(pFGF->GetCLSID()) : CString(pFGF->GetName()));
+ }
+
+ return m_sortedfilters.GetHeadPosition();
+}
+
+CFGFilter* CFGFilterList::GetNext(POSITION& pos)
+{
+ return m_sortedfilters.GetNext(pos);
+}
+
+int CFGFilterList::filter_cmp(const void* a, const void* b)
+{
+ filter_t* fa = (filter_t*)a;
+ filter_t* fb = (filter_t*)b;
+
+ if(fa->group < fb->group) return -1;
+ if(fa->group > fb->group) return +1;
+
+ if(fa->pFGF->GetCLSID() == fb->pFGF->GetCLSID())
+ {
+ CFGFilterFile* fgfa = dynamic_cast<CFGFilterFile*>(fa->pFGF);
+ CFGFilterFile* fgfb = dynamic_cast<CFGFilterFile*>(fb->pFGF);
+
+ if(fgfa && !fgfb) return -1;
+ if(!fgfa && fgfb) return +1;
+ }
+
+ if(fa->pFGF->GetMerit() > fb->pFGF->GetMerit()) return -1;
+ if(fa->pFGF->GetMerit() < fb->pFGF->GetMerit()) return +1;
+
+ if(fa->exactmatch && !fb->exactmatch) return -1;
+ if(!fa->exactmatch && fb->exactmatch) return +1;
+
+ if(fa->index < fb->index) return -1;
+ if(fa->index > fb->index) return +1;
+
+ return 0;
+}
diff --git a/src/apps/mplayerc/FGFilter.h b/src/apps/mplayerc/FGFilter.h
new file mode 100644
index 000000000..cae81c000
--- /dev/null
+++ b/src/apps/mplayerc/FGFilter.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#define MERIT64(merit) (((UINT64)(merit))<<16)
+#define MERIT64_DO_NOT_USE MERIT64(MERIT_DO_NOT_USE)
+#define MERIT64_DO_USE MERIT64(MERIT_DO_NOT_USE+1)
+#define MERIT64_UNLIKELY (MERIT64(MERIT_UNLIKELY))
+#define MERIT64_NORMAL (MERIT64(MERIT_NORMAL))
+#define MERIT64_PREFERRED (MERIT64(MERIT_PREFERRED))
+#define MERIT64_ABOVE_DSHOW (MERIT64(1)<<32)
+
+class CFGFilter
+{
+protected:
+ CLSID m_clsid;
+ CStringW m_name;
+ struct {union {UINT64 val; struct {UINT64 low:16, mid:32, high:16;};};} m_merit;
+ CAtlList<GUID> m_types;
+
+public:
+ CFGFilter(const CLSID& clsid, CStringW name = L"", UINT64 merit = MERIT64_DO_USE);
+ virtual ~CFGFilter() {}
+
+ CLSID GetCLSID() {return m_clsid;}
+ CStringW GetName() {return m_name;}
+ UINT64 GetMerit() {return m_merit.val;}
+ DWORD GetMeritForDirectShow() {return m_merit.mid;}
+ const CAtlList<GUID>& GetTypes() const;
+ void SetTypes(const CAtlList<GUID>& types);
+ void AddType(const GUID& majortype, const GUID& subtype);
+ bool CheckTypes(const CAtlArray<GUID>& types, bool fExactMatch);
+
+ CAtlList<CString> m_protocols, m_extensions, m_chkbytes; // TODO: subtype?
+
+ virtual HRESULT Create(IBaseFilter** ppBF, IUnknown** ppUnk) = 0;
+};
+
+class CFGFilterRegistry : public CFGFilter
+{
+protected:
+ CStringW m_DisplayName;
+ CComPtr<IMoniker> m_pMoniker;
+
+ void ExtractFilterData(BYTE* p, UINT len);
+
+public:
+ CFGFilterRegistry(IMoniker* pMoniker, UINT64 merit = MERIT64_DO_USE);
+ CFGFilterRegistry(CStringW DisplayName, UINT64 merit = MERIT64_DO_USE);
+ CFGFilterRegistry(const CLSID& clsid, UINT64 merit = MERIT64_DO_USE);
+
+ CStringW GetDisplayName() {return m_DisplayName;}
+ IMoniker* GetMoniker() {return m_pMoniker;}
+
+ HRESULT Create(IBaseFilter** ppBF, IUnknown** ppUnk);
+};
+
+template<class T>
+class CFGFilterInternal : public CFGFilter
+{
+public:
+ CFGFilterInternal(CStringW name = L"", UINT64 merit = MERIT64_DO_USE) : CFGFilter(__uuidof(T), name, merit) {}
+
+ HRESULT Create(IBaseFilter** ppBF, IUnknown** ppUnk)
+ {
+ CheckPointer(ppBF, E_POINTER);
+
+ if(ppUnk) *ppUnk = NULL;
+
+ HRESULT hr = S_OK;
+ CComPtr<IBaseFilter> pBF = new T(NULL, &hr);
+ if(FAILED(hr)) return hr;
+
+ *ppBF = pBF.Detach();
+
+ return hr;
+ }
+};
+
+class CFGFilterFile : public CFGFilter
+{
+protected:
+ CString m_path;
+ HINSTANCE m_hInst;
+
+public:
+ CFGFilterFile(const CLSID& clsid, CString path, CStringW name = L"", UINT64 merit = MERIT64_DO_USE);
+
+ HRESULT Create(IBaseFilter** ppBF, IUnknown** ppUnk);
+};
+
+class CFGFilterVideoRenderer : public CFGFilter
+{
+protected:
+ HWND m_hWnd;
+
+public:
+ CFGFilterVideoRenderer(HWND hWnd, const CLSID& clsid, CStringW name = L"", UINT64 merit = MERIT64_DO_USE);
+
+ HRESULT Create(IBaseFilter** ppBF, IUnknown** ppUnk);
+};
+
+class CFGFilterList
+{
+ struct filter_t {int index; CFGFilter* pFGF; int group; bool exactmatch, autodelete;};
+ static int filter_cmp(const void* a, const void* b);
+ CAtlList<filter_t> m_filters;
+ CAtlList<CFGFilter*> m_sortedfilters;
+
+public:
+ CFGFilterList();
+ virtual ~CFGFilterList();
+
+ void RemoveAll();
+ void Insert(CFGFilter* pFGF, int group, bool exactmatch = false, bool autodelete = true);
+
+ POSITION GetHeadPosition();
+ CFGFilter* GetNext(POSITION& pos);
+};
diff --git a/src/apps/mplayerc/FGManager.cpp b/src/apps/mplayerc/FGManager.cpp
new file mode 100644
index 000000000..aa8697dc4
--- /dev/null
+++ b/src/apps/mplayerc/FGManager.cpp
@@ -0,0 +1,1840 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "FGManager.h"
+#include "..\..\DSUtil\DSUtil.h"
+#include "..\..\Filters\Filters.h"
+#include "DX7AllocatorPresenter.h"
+#include "DX9AllocatorPresenter.h"
+#include "DeinterlacerFilter.h"
+#include <initguid.h>
+#include "..\..\..\include\moreuuids.h"
+#include <dmodshow.h>
+#include <D3d9.h>
+#include <Vmr9.h>
+
+//
+// CFGManager
+//
+
+CFGManager::CFGManager(LPCTSTR pName, LPUNKNOWN pUnk)
+ : CUnknown(pName, pUnk)
+ , m_dwRegister(0)
+{
+ m_pUnkInner.CoCreateInstance(CLSID_FilterGraph, GetOwner());
+ m_pFM.CoCreateInstance(CLSID_FilterMapper2);
+}
+
+CFGManager::~CFGManager()
+{
+ CAutoLock cAutoLock(this);
+ while(!m_source.IsEmpty()) delete m_source.RemoveHead();
+ while(!m_transform.IsEmpty()) delete m_transform.RemoveHead();
+ while(!m_override.IsEmpty()) delete m_override.RemoveHead();
+ m_pUnks.RemoveAll();
+ m_pUnkInner.Release();
+}
+
+STDMETHODIMP CFGManager::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ CheckPointer(ppv, E_POINTER);
+
+ return
+ QI(IFilterGraph)
+ QI(IGraphBuilder)
+ QI(IFilterGraph2)
+ QI(IGraphBuilder2)
+ QI(IGraphBuilderDeadEnd)
+ m_pUnkInner && (riid != IID_IUnknown && SUCCEEDED(m_pUnkInner->QueryInterface(riid, ppv))) ? S_OK :
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+//
+
+void CFGManager::CStreamPath::Append(IBaseFilter* pBF, IPin* pPin)
+{
+ path_t p;
+ p.clsid = GetCLSID(pBF);
+ p.filter = GetFilterName(pBF);
+ p.pin = GetPinName(pPin);
+ AddTail(p);
+}
+
+bool CFGManager::CStreamPath::Compare(const CStreamPath& path)
+{
+ POSITION pos1 = GetHeadPosition();
+ POSITION pos2 = path.GetHeadPosition();
+
+ while(pos1 && pos2)
+ {
+ const path_t& p1 = GetNext(pos1);
+ const path_t& p2 = path.GetNext(pos2);
+
+ if(p1.filter != p2.filter) return true;
+ else if(p1.pin != p2.pin) return false;
+ }
+
+ return true;
+}
+
+//
+
+bool CFGManager::CheckBytes(HANDLE hFile, CString chkbytes)
+{
+ CAtlList<CString> sl;
+ Explode(chkbytes, sl, ',');
+
+ if(sl.GetCount() < 4)
+ return false;
+
+ ASSERT(!(sl.GetCount()&3));
+
+ LARGE_INTEGER size = {0, 0};
+ size.LowPart = GetFileSize(hFile, (DWORD*)&size.HighPart);
+
+ POSITION pos = sl.GetHeadPosition();
+ while(sl.GetCount() >= 4)
+ {
+ CString offsetstr = sl.RemoveHead();
+ CString cbstr = sl.RemoveHead();
+ CString maskstr = sl.RemoveHead();
+ CString valstr = sl.RemoveHead();
+
+ long cb = _ttol(cbstr);
+
+ if(offsetstr.IsEmpty() || cbstr.IsEmpty()
+ || valstr.IsEmpty() || (valstr.GetLength() & 1)
+ || cb*2 != valstr.GetLength())
+ return false;
+
+ LARGE_INTEGER offset;
+ offset.QuadPart = _ttoi64(offsetstr);
+ if(offset.QuadPart < 0) offset.QuadPart = size.QuadPart - offset.QuadPart;
+ SetFilePointer(hFile, offset.LowPart, &offset.HighPart, FILE_BEGIN);
+
+ // LAME
+ while(maskstr.GetLength() < valstr.GetLength())
+ maskstr += 'F';
+
+ CAtlArray<BYTE> mask, val;
+ CStringToBin(maskstr, mask);
+ CStringToBin(valstr, val);
+
+ for(size_t i = 0; i < val.GetCount(); i++)
+ {
+ BYTE b;
+ DWORD r;
+ if(!ReadFile(hFile, &b, 1, &r, NULL) || (b & mask[i]) != val[i])
+ return false;
+ }
+ }
+
+ return sl.IsEmpty();
+}
+
+HRESULT CFGManager::AddSourceFilter(CFGFilter* pFGF, LPCWSTR lpcwstrFileName, LPCWSTR lpcwstrFilterName, IBaseFilter** ppBF)
+{
+ TRACE(_T("FGM: AddSourceFilter trying '%s'\n"), CStringFromGUID(pFGF->GetCLSID()));
+
+ CheckPointer(lpcwstrFileName, E_POINTER);
+ CheckPointer(ppBF, E_POINTER);
+
+ ASSERT(*ppBF == NULL);
+
+ HRESULT hr;
+
+ CComPtr<IBaseFilter> pBF;
+ CComPtr<IUnknown> pUnk;
+ if(FAILED(hr = pFGF->Create(&pBF, &pUnk)))
+ return hr;
+
+ CComQIPtr<IFileSourceFilter> pFSF = pBF;
+ if(!pFSF) return E_NOINTERFACE;
+
+ if(FAILED(hr = AddFilter(pBF, lpcwstrFilterName)))
+ return hr;
+
+ const AM_MEDIA_TYPE* pmt = NULL;
+
+ CMediaType mt;
+ const CAtlList<GUID>& types = pFGF->GetTypes();
+ if(types.GetCount() == 2 && (types.GetHead() != GUID_NULL || types.GetTail() != GUID_NULL))
+ {
+ mt.majortype = types.GetHead();
+ mt.subtype = types.GetTail();
+ pmt = &mt;
+ }
+
+ if(FAILED(hr = pFSF->Load(lpcwstrFileName, pmt)))
+ {
+ RemoveFilter(pBF);
+ return hr;
+ }
+
+ *ppBF = pBF.Detach();
+
+ if(pUnk) m_pUnks.AddTail(pUnk);
+
+ return S_OK;
+}
+
+// IFilterGraph
+
+STDMETHODIMP CFGManager::AddFilter(IBaseFilter* pFilter, LPCWSTR pName)
+{
+ CAutoLock cAutoLock(this);
+
+ HRESULT hr;
+
+ if(FAILED(hr = CComQIPtr<IFilterGraph2>(m_pUnkInner)->AddFilter(pFilter, pName)))
+ return hr;
+
+ // TODO
+ hr = pFilter->JoinFilterGraph(NULL, NULL);
+ hr = pFilter->JoinFilterGraph(this, pName);
+
+ return hr;
+}
+
+STDMETHODIMP CFGManager::RemoveFilter(IBaseFilter* pFilter)
+{
+ CAutoLock cAutoLock(this);
+
+ return CComQIPtr<IFilterGraph2>(m_pUnkInner)->RemoveFilter(pFilter);
+}
+
+STDMETHODIMP CFGManager::EnumFilters(IEnumFilters** ppEnum)
+{
+ CAutoLock cAutoLock(this);
+
+ return CComQIPtr<IFilterGraph2>(m_pUnkInner)->EnumFilters(ppEnum);
+}
+
+STDMETHODIMP CFGManager::FindFilterByName(LPCWSTR pName, IBaseFilter** ppFilter)
+{
+ CAutoLock cAutoLock(this);
+
+ return CComQIPtr<IFilterGraph2>(m_pUnkInner)->FindFilterByName(pName, ppFilter);
+}
+
+STDMETHODIMP CFGManager::ConnectDirect(IPin* pPinOut, IPin* pPinIn, const AM_MEDIA_TYPE* pmt)
+{
+ CAutoLock cAutoLock(this);
+
+ CComPtr<IBaseFilter> pBF = GetFilterFromPin(pPinIn);
+ CLSID clsid = GetCLSID(pBF);
+
+ // TODO: GetUpStreamFilter goes up on the first input pin only
+ for(CComPtr<IBaseFilter> pBFUS = GetFilterFromPin(pPinOut); pBFUS; pBFUS = GetUpStreamFilter(pBFUS))
+ {
+ if(pBFUS == pBF) return VFW_E_CIRCULAR_GRAPH;
+ if(GetCLSID(pBFUS) == clsid) return VFW_E_CANNOT_CONNECT;
+ }
+
+ return CComQIPtr<IFilterGraph2>(m_pUnkInner)->ConnectDirect(pPinOut, pPinIn, pmt);
+}
+
+STDMETHODIMP CFGManager::Reconnect(IPin* ppin)
+{
+ CAutoLock cAutoLock(this);
+
+ return CComQIPtr<IFilterGraph2>(m_pUnkInner)->Reconnect(ppin);
+}
+
+STDMETHODIMP CFGManager::Disconnect(IPin* ppin)
+{
+ CAutoLock cAutoLock(this);
+
+ return CComQIPtr<IFilterGraph2>(m_pUnkInner)->Disconnect(ppin);
+}
+
+STDMETHODIMP CFGManager::SetDefaultSyncSource()
+{
+ CAutoLock cAutoLock(this);
+
+ return CComQIPtr<IFilterGraph2>(m_pUnkInner)->SetDefaultSyncSource();
+}
+
+// IGraphBuilder
+
+STDMETHODIMP CFGManager::Connect(IPin* pPinOut, IPin* pPinIn)
+{
+ CAutoLock cAutoLock(this);
+
+ CheckPointer(pPinOut, E_POINTER);
+
+ HRESULT hr;
+
+ if(S_OK != IsPinDirection(pPinOut, PINDIR_OUTPUT)
+ || pPinIn && S_OK != IsPinDirection(pPinIn, PINDIR_INPUT))
+ return VFW_E_INVALID_DIRECTION;
+
+ if(S_OK == IsPinConnected(pPinOut)
+ || pPinIn && S_OK == IsPinConnected(pPinIn))
+ return VFW_E_ALREADY_CONNECTED;
+
+ bool fDeadEnd = true;
+
+ if(pPinIn)
+ {
+ // 1. Try a direct connection between the filters, with no intermediate filters
+
+ if(SUCCEEDED(hr = ConnectDirect(pPinOut, pPinIn, NULL)))
+ return hr;
+ }
+ else
+ {
+ // 1. Use IStreamBuilder
+
+ if(CComQIPtr<IStreamBuilder> pSB = pPinOut)
+ {
+ if(SUCCEEDED(hr = pSB->Render(pPinOut, this)))
+ return hr;
+
+ pSB->Backout(pPinOut, this);
+ }
+ }
+
+ // 2. Try cached filters
+
+ if(CComQIPtr<IGraphConfig> pGC = (IGraphBuilder2*)this)
+ {
+ BeginEnumCachedFilters(pGC, pEF, pBF)
+ {
+ if(pPinIn && GetFilterFromPin(pPinIn) == pBF)
+ continue;
+
+ hr = pGC->RemoveFilterFromCache(pBF);
+
+ // does RemoveFilterFromCache call AddFilter like AddFilterToCache calls RemoveFilter ?
+
+ if(SUCCEEDED(hr = ConnectFilterDirect(pPinOut, pBF, NULL)))
+ {
+ if(!IsStreamEnd(pBF)) fDeadEnd = false;
+
+ if(SUCCEEDED(hr = ConnectFilter(pBF, pPinIn)))
+ return hr;
+ }
+
+ hr = pGC->AddFilterToCache(pBF);
+ }
+ EndEnumCachedFilters
+ }
+
+ // 3. Try filters in the graph
+
+ {
+ CInterfaceList<IBaseFilter> pBFs;
+
+ BeginEnumFilters(this, pEF, pBF)
+ {
+ if(pPinIn && GetFilterFromPin(pPinIn) == pBF
+ || GetFilterFromPin(pPinOut) == pBF)
+ continue;
+
+ // HACK: ffdshow - audio capture filter
+ if(GetCLSID(pPinOut) == GUIDFromCString(_T("{04FE9017-F873-410E-871E-AB91661A4EF7}"))
+ && GetCLSID(pBF) == GUIDFromCString(_T("{E30629D2-27E5-11CE-875D-00608CB78066}")))
+ continue;
+
+ pBFs.AddTail(pBF);
+ }
+ EndEnumFilters
+
+ POSITION pos = pBFs.GetHeadPosition();
+ while(pos)
+ {
+ IBaseFilter* pBF = pBFs.GetNext(pos);
+
+ if(SUCCEEDED(hr = ConnectFilterDirect(pPinOut, pBF, NULL)))
+ {
+ if(!IsStreamEnd(pBF)) fDeadEnd = false;
+
+ if(SUCCEEDED(hr = ConnectFilter(pBF, pPinIn)))
+ return hr;
+ }
+
+ EXECUTE_ASSERT(Disconnect(pPinOut));
+ }
+ }
+
+ // 4. Look up filters in the registry
+
+ {
+ CFGFilterList fl;
+
+ CAtlArray<GUID> types;
+ ExtractMediaTypes(pPinOut, types);
+
+ POSITION pos = m_transform.GetHeadPosition();
+ while(pos)
+ {
+ CFGFilter* pFGF = m_transform.GetNext(pos);
+ if(pFGF->GetMerit() < MERIT64_DO_USE || pFGF->CheckTypes(types, false))
+ fl.Insert(pFGF, 0, pFGF->CheckTypes(types, true), false);
+ }
+
+ pos = m_override.GetHeadPosition();
+ while(pos)
+ {
+ CFGFilter* pFGF = m_override.GetNext(pos);
+ if(pFGF->GetMerit() < MERIT64_DO_USE || pFGF->CheckTypes(types, false))
+ fl.Insert(pFGF, 0, pFGF->CheckTypes(types, true), false);
+ }
+
+ CComPtr<IEnumMoniker> pEM;
+ if(types.GetCount() > 0
+ && SUCCEEDED(m_pFM->EnumMatchingFilters(
+ &pEM, 0, FALSE, MERIT_DO_NOT_USE+1,
+ TRUE, types.GetCount()/2, types.GetData(), NULL, NULL, FALSE,
+ !!pPinIn, 0, NULL, NULL, NULL)))
+ {
+ for(CComPtr<IMoniker> pMoniker; S_OK == pEM->Next(1, &pMoniker, NULL); pMoniker = NULL)
+ {
+ CFGFilterRegistry* pFGF = new CFGFilterRegistry(pMoniker);
+ fl.Insert(pFGF, 0, pFGF->CheckTypes(types, true));
+ }
+ }
+
+ pos = fl.GetHeadPosition();
+ while(pos)
+ {
+ CFGFilter* pFGF = fl.GetNext(pos);
+
+ TRACE(_T("FGM: Connecting '%s'\n"), pFGF->GetName());
+
+ CComPtr<IBaseFilter> pBF;
+ CComPtr<IUnknown> pUnk;
+ if(FAILED(pFGF->Create(&pBF, &pUnk)))
+ continue;
+
+ if(FAILED(hr = AddFilter(pBF, pFGF->GetName())))
+ continue;
+
+ hr = E_FAIL;
+
+ if(FAILED(hr))
+ {
+ hr = ConnectFilterDirect(pPinOut, pBF, NULL);
+ }
+/*
+ if(FAILED(hr))
+ {
+ if(types.GetCount() >= 2 && types[0] == MEDIATYPE_Stream && types[1] != GUID_NULL)
+ {
+ CMediaType mt;
+
+ mt.majortype = types[0];
+ mt.subtype = types[1];
+ mt.formattype = FORMAT_None;
+ if(FAILED(hr)) hr = ConnectFilterDirect(pPinOut, pBF, &mt);
+
+ mt.formattype = GUID_NULL;
+ if(FAILED(hr)) hr = ConnectFilterDirect(pPinOut, pBF, &mt);
+ }
+ }
+*/
+ if(SUCCEEDED(hr))
+ {
+ if(!IsStreamEnd(pBF)) fDeadEnd = false;
+
+ hr = ConnectFilter(pBF, pPinIn);
+
+ if(SUCCEEDED(hr))
+ {
+ if(pUnk) m_pUnks.AddTail(pUnk);
+
+ // maybe the application should do this...
+ if(CComQIPtr<IMixerPinConfig, &IID_IMixerPinConfig> pMPC = pUnk)
+ pMPC->SetAspectRatioMode(AM_ARMODE_STRETCHED);
+ if(CComQIPtr<IVMRAspectRatioControl> pARC = pBF)
+ pARC->SetAspectRatioMode(VMR_ARMODE_NONE);
+ if(CComQIPtr<IVMRAspectRatioControl9> pARC = pBF)
+ pARC->SetAspectRatioMode(VMR_ARMODE_NONE);
+ if(CComQIPtr<IVMRMixerControl9> pMC = pBF)
+ m_pUnks.AddTail (pMC);
+ if(CComQIPtr<IVMRMixerBitmap9> pMB = pBF)
+ m_pUnks.AddTail (pMB);
+
+ return hr;
+ }
+ }
+
+ EXECUTE_ASSERT(SUCCEEDED(RemoveFilter(pBF)));
+
+ TRACE(_T("FGM: Connecting '%s' FAILED!\n"), pFGF->GetName());
+ }
+ }
+
+ if(fDeadEnd)
+ {
+ CAutoPtr<CStreamDeadEnd> psde(new CStreamDeadEnd());
+ psde->AddTailList(&m_streampath);
+ BeginEnumMediaTypes(pPinOut, pEM, pmt)
+ psde->mts.AddTail(CMediaType(*pmt));
+ EndEnumMediaTypes(pmt)
+ m_deadends.Add(psde);
+ }
+
+ return pPinIn ? VFW_E_CANNOT_CONNECT : VFW_E_CANNOT_RENDER;
+}
+
+STDMETHODIMP CFGManager::Render(IPin* pPinOut)
+{
+ CAutoLock cAutoLock(this);
+
+ return RenderEx(pPinOut, 0, NULL);
+}
+
+STDMETHODIMP CFGManager::RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList)
+{
+ CAutoLock cAutoLock(this);
+
+ m_streampath.RemoveAll();
+ m_deadends.RemoveAll();
+
+ HRESULT hr;
+
+ CComPtr<IBaseFilter> pBF;
+ if(FAILED(hr = AddSourceFilter(lpcwstrFile, lpcwstrFile, &pBF)))
+ return hr;
+
+ return ConnectFilter(pBF, NULL);
+}
+
+STDMETHODIMP CFGManager::AddSourceFilter(LPCWSTR lpcwstrFileName, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter)
+{
+ CAutoLock cAutoLock(this);
+
+ // TODO: use overrides
+
+ CheckPointer(lpcwstrFileName, E_POINTER);
+ CheckPointer(ppFilter, E_POINTER);
+
+ HRESULT hr;
+
+ CStringW fn = CStringW(lpcwstrFileName).TrimLeft();
+ CStringW protocol = fn.Left(fn.Find(':')+1).TrimRight(':').MakeLower();
+ CStringW ext = CPathW(fn).GetExtension();
+
+ TCHAR buff[256], buff2[256];
+ ULONG len, len2;
+
+ CFGFilterList fl;
+
+ HANDLE hFile = CreateFile(CString(fn), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
+
+ // internal / protocol
+
+ if(protocol.GetLength() > 1 && protocol != L"file")
+ {
+ POSITION pos = m_source.GetHeadPosition();
+ while(pos)
+ {
+ CFGFilter* pFGF = m_source.GetNext(pos);
+ if(pFGF->m_protocols.Find(CString(protocol)))
+ fl.Insert(pFGF, 0, false, false);
+ }
+ }
+
+ // internal / check bytes
+
+ if(hFile != INVALID_HANDLE_VALUE)
+ {
+ POSITION pos = m_source.GetHeadPosition();
+ while(pos)
+ {
+ CFGFilter* pFGF = m_source.GetNext(pos);
+
+ POSITION pos2 = pFGF->m_chkbytes.GetHeadPosition();
+ while(pos2)
+ {
+ if(CheckBytes(hFile, pFGF->m_chkbytes.GetNext(pos2)))
+ {
+ fl.Insert(pFGF, 1, false, false);
+ break;
+ }
+ }
+ }
+ }
+
+ // insernal / file extension
+
+ if(!ext.IsEmpty())
+ {
+ POSITION pos = m_source.GetHeadPosition();
+ while(pos)
+ {
+ CFGFilter* pFGF = m_source.GetNext(pos);
+ if(pFGF->m_extensions.Find(CString(ext)))
+ fl.Insert(pFGF, 2, false, false);
+ }
+ }
+
+ // internal / the rest
+
+ {
+ POSITION pos = m_source.GetHeadPosition();
+ while(pos)
+ {
+ CFGFilter* pFGF = m_source.GetNext(pos);
+ if(pFGF->m_protocols.IsEmpty() && pFGF->m_chkbytes.IsEmpty() && pFGF->m_extensions.IsEmpty())
+ fl.Insert(pFGF, 3, false, false);
+ }
+ }
+
+ // protocol
+
+ if(protocol.GetLength() > 1 && protocol != L"file")
+ {
+ CRegKey key;
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, CString(protocol), KEY_READ))
+ {
+ CRegKey exts;
+ if(ERROR_SUCCESS == exts.Open(key, _T("Extensions"), KEY_READ))
+ {
+ len = countof(buff);
+ if(ERROR_SUCCESS == exts.QueryStringValue(CString(ext), buff, &len))
+ fl.Insert(new CFGFilterRegistry(GUIDFromCString(buff)), 4);
+ }
+
+ len = countof(buff);
+ if(ERROR_SUCCESS == key.QueryStringValue(_T("Source Filter"), buff, &len))
+ fl.Insert(new CFGFilterRegistry(GUIDFromCString(buff)), 5);
+ }
+
+ fl.Insert(new CFGFilterRegistry(CLSID_URLReader), 6);
+ }
+
+ // check bytes
+
+ if(hFile != INVALID_HANDLE_VALUE)
+ {
+ CRegKey key;
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("Media Type"), KEY_READ))
+ {
+ FILETIME ft;
+ len = countof(buff);
+ for(DWORD i = 0; ERROR_SUCCESS == key.EnumKey(i, buff, &len, &ft); i++, len = countof(buff))
+ {
+ GUID majortype;
+ if(FAILED(GUIDFromCString(buff, majortype)))
+ continue;
+
+ CRegKey majorkey;
+ if(ERROR_SUCCESS == majorkey.Open(key, buff, KEY_READ))
+ {
+ len = countof(buff);
+ for(DWORD j = 0; ERROR_SUCCESS == majorkey.EnumKey(j, buff, &len, &ft); j++, len = countof(buff))
+ {
+ GUID subtype;
+ if(FAILED(GUIDFromCString(buff, subtype)))
+ continue;
+
+ CRegKey subkey;
+ if(ERROR_SUCCESS == subkey.Open(majorkey, buff, KEY_READ))
+ {
+ len = countof(buff);
+ if(ERROR_SUCCESS != subkey.QueryStringValue(_T("Source Filter"), buff, &len))
+ continue;
+
+ GUID clsid = GUIDFromCString(buff);
+
+ len = countof(buff);
+ len2 = sizeof(buff2);
+ for(DWORD k = 0, type;
+ clsid != GUID_NULL && ERROR_SUCCESS == RegEnumValue(subkey, k, buff2, &len2, 0, &type, (BYTE*)buff, &len);
+ k++, len = countof(buff), len2 = sizeof(buff2))
+ {
+ if(CheckBytes(hFile, CString(buff)))
+ {
+ CFGFilter* pFGF = new CFGFilterRegistry(clsid);
+ pFGF->AddType(majortype, subtype);
+ fl.Insert(pFGF, 7);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // file extension
+
+ if(!ext.IsEmpty())
+ {
+ CRegKey key;
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("Media Type\\Extensions\\") + CString(ext), KEY_READ))
+ {
+ ULONG len = countof(buff);
+ if(ERROR_SUCCESS == key.QueryStringValue(_T("Source Filter"), buff, &len))
+ {
+ GUID clsid = GUIDFromCString(buff);
+ GUID majortype = GUID_NULL;
+ GUID subtype = GUID_NULL;
+
+ len = countof(buff);
+ if(ERROR_SUCCESS == key.QueryStringValue(_T("Media Type"), buff, &len))
+ majortype = GUIDFromCString(buff);
+
+ len = countof(buff);
+ if(ERROR_SUCCESS == key.QueryStringValue(_T("Subtype"), buff, &len))
+ subtype = GUIDFromCString(buff);
+
+ CFGFilter* pFGF = new CFGFilterRegistry(clsid);
+ pFGF->AddType(majortype, subtype);
+ fl.Insert(pFGF, 8);
+ }
+ }
+ }
+
+ if(hFile != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(hFile);
+ }
+
+ CFGFilter* pFGF = new CFGFilterRegistry(CLSID_AsyncReader);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_NULL);
+ fl.Insert(pFGF, 9);
+
+ POSITION pos = fl.GetHeadPosition();
+ while(pos)
+ {
+ if(SUCCEEDED(hr = AddSourceFilter(fl.GetNext(pos), lpcwstrFileName, lpcwstrFilterName, ppFilter)))
+ return hr;
+ }
+
+ return hFile == INVALID_HANDLE_VALUE ? VFW_E_NOT_FOUND : VFW_E_CANNOT_LOAD_SOURCE_FILTER;
+}
+
+STDMETHODIMP CFGManager::SetLogFile(DWORD_PTR hFile)
+{
+ CAutoLock cAutoLock(this);
+
+ return CComQIPtr<IFilterGraph2>(m_pUnkInner)->SetLogFile(hFile);
+}
+
+STDMETHODIMP CFGManager::Abort()
+{
+ CAutoLock cAutoLock(this);
+
+ return CComQIPtr<IFilterGraph2>(m_pUnkInner)->Abort();
+}
+
+STDMETHODIMP CFGManager::ShouldOperationContinue()
+{
+ CAutoLock cAutoLock(this);
+
+ return CComQIPtr<IFilterGraph2>(m_pUnkInner)->ShouldOperationContinue();
+}
+
+// IFilterGraph2
+
+STDMETHODIMP CFGManager::AddSourceFilterForMoniker(IMoniker* pMoniker, IBindCtx* pCtx, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter)
+{
+ CAutoLock cAutoLock(this);
+
+ return CComQIPtr<IFilterGraph2>(m_pUnkInner)->AddSourceFilterForMoniker(pMoniker, pCtx, lpcwstrFilterName, ppFilter);
+}
+
+STDMETHODIMP CFGManager::ReconnectEx(IPin* ppin, const AM_MEDIA_TYPE* pmt)
+{
+ CAutoLock cAutoLock(this);
+
+ return CComQIPtr<IFilterGraph2>(m_pUnkInner)->ReconnectEx(ppin, pmt);
+}
+
+STDMETHODIMP CFGManager::RenderEx(IPin* pPinOut, DWORD dwFlags, DWORD* pvContext)
+{
+ CAutoLock cAutoLock(this);
+
+ m_streampath.RemoveAll();
+ m_deadends.RemoveAll();
+
+ if(!pPinOut || dwFlags > AM_RENDEREX_RENDERTOEXISTINGRENDERERS || pvContext)
+ return E_INVALIDARG;
+
+ HRESULT hr;
+
+ if(dwFlags & AM_RENDEREX_RENDERTOEXISTINGRENDERERS)
+ {
+ CInterfaceList<IBaseFilter> pBFs;
+
+ BeginEnumFilters(this, pEF, pBF)
+ {
+ if(CComQIPtr<IAMFilterMiscFlags> pAMMF = pBF)
+ {
+ if(pAMMF->GetMiscFlags() & AM_FILTER_MISC_FLAGS_IS_RENDERER)
+ {
+ pBFs.AddTail(pBF);
+ }
+ }
+ else
+ {
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ CComPtr<IPin> pPinIn;
+ DWORD size = 1;
+ if(SUCCEEDED(pPin->QueryInternalConnections(&pPinIn, &size)) && size == 0)
+ {
+ pBFs.AddTail(pBF);
+ break;
+ }
+ }
+ EndEnumPins
+ }
+ }
+ EndEnumFilters
+
+ while(!pBFs.IsEmpty())
+ {
+ if(SUCCEEDED(hr = ConnectFilter(pPinOut, pBFs.RemoveHead())))
+ return hr;
+ }
+
+ return VFW_E_CANNOT_RENDER;
+ }
+
+ return Connect(pPinOut, (IPin*)NULL);
+}
+
+// IGraphBuilder2
+
+STDMETHODIMP CFGManager::IsPinDirection(IPin* pPin, PIN_DIRECTION dir1)
+{
+ CAutoLock cAutoLock(this);
+
+ CheckPointer(pPin, E_POINTER);
+
+ PIN_DIRECTION dir2;
+ if(FAILED(pPin->QueryDirection(&dir2)))
+ return E_FAIL;
+
+ return dir1 == dir2 ? S_OK : S_FALSE;
+}
+
+STDMETHODIMP CFGManager::IsPinConnected(IPin* pPin)
+{
+ CAutoLock cAutoLock(this);
+
+ CheckPointer(pPin, E_POINTER);
+
+ CComPtr<IPin> pPinTo;
+ return SUCCEEDED(pPin->ConnectedTo(&pPinTo)) && pPinTo ? S_OK : S_FALSE;
+}
+
+STDMETHODIMP CFGManager::ConnectFilter(IBaseFilter* pBF, IPin* pPinIn)
+{
+ CAutoLock cAutoLock(this);
+
+ CheckPointer(pBF, E_POINTER);
+
+ if(pPinIn && S_OK != IsPinDirection(pPinIn, PINDIR_INPUT))
+ return VFW_E_INVALID_DIRECTION;
+
+ int nTotal = 0, nRendered = 0;
+
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ if(GetPinName(pPin)[0] != '~'
+ && S_OK == IsPinDirection(pPin, PINDIR_OUTPUT)
+ && S_OK != IsPinConnected(pPin))
+ {
+ m_streampath.Append(pBF, pPin);
+
+ HRESULT hr = Connect(pPin, pPinIn);
+
+ if(SUCCEEDED(hr))
+ {
+ for(int i = m_deadends.GetCount()-1; i >= 0; i--)
+ if(m_deadends[i]->Compare(m_streampath))
+ m_deadends.RemoveAt(i);
+
+ nRendered++;
+ }
+
+ nTotal++;
+
+ m_streampath.RemoveTail();
+
+ if(SUCCEEDED(hr) && pPinIn)
+ return S_OK;
+ }
+ }
+ EndEnumPins
+
+ return
+ nRendered == nTotal ? (nRendered > 0 ? S_OK : S_FALSE) :
+ nRendered > 0 ? VFW_S_PARTIAL_RENDER :
+ VFW_E_CANNOT_RENDER;
+}
+
+STDMETHODIMP CFGManager::ConnectFilter(IPin* pPinOut, IBaseFilter* pBF)
+{
+ CAutoLock cAutoLock(this);
+
+ CheckPointer(pPinOut, E_POINTER);
+ CheckPointer(pBF, E_POINTER);
+
+ if(S_OK != IsPinDirection(pPinOut, PINDIR_OUTPUT))
+ return VFW_E_INVALID_DIRECTION;
+
+ HRESULT hr;
+
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ if(GetPinName(pPin)[0] != '~'
+ && S_OK == IsPinDirection(pPin, PINDIR_INPUT)
+ && S_OK != IsPinConnected(pPin)
+ && SUCCEEDED(hr = Connect(pPinOut, pPin)))
+ return hr;
+ }
+ EndEnumPins
+
+ return VFW_E_CANNOT_CONNECT;
+}
+
+STDMETHODIMP CFGManager::ConnectFilterDirect(IPin* pPinOut, IBaseFilter* pBF, const AM_MEDIA_TYPE* pmt)
+{
+ CAutoLock cAutoLock(this);
+
+ CheckPointer(pPinOut, E_POINTER);
+ CheckPointer(pBF, E_POINTER);
+
+ if(S_OK != IsPinDirection(pPinOut, PINDIR_OUTPUT))
+ return VFW_E_INVALID_DIRECTION;
+
+ HRESULT hr;
+
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ if(GetPinName(pPin)[0] != '~'
+ && S_OK == IsPinDirection(pPin, PINDIR_INPUT)
+ && S_OK != IsPinConnected(pPin)
+ && SUCCEEDED(hr = ConnectDirect(pPinOut, pPin, pmt)))
+ return hr;
+ }
+ EndEnumPins
+
+ return VFW_E_CANNOT_CONNECT;
+}
+
+STDMETHODIMP CFGManager::NukeDownstream(IUnknown* pUnk)
+{
+ CAutoLock cAutoLock(this);
+
+ if(CComQIPtr<IBaseFilter> pBF = pUnk)
+ {
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ NukeDownstream(pPin);
+ }
+ EndEnumPins
+ }
+ else if(CComQIPtr<IPin> pPin = pUnk)
+ {
+ CComPtr<IPin> pPinTo;
+ if(S_OK == IsPinDirection(pPin, PINDIR_OUTPUT)
+ && SUCCEEDED(pPin->ConnectedTo(&pPinTo)) && pPinTo)
+ {
+ if(CComPtr<IBaseFilter> pBF = GetFilterFromPin(pPinTo))
+ {
+ NukeDownstream(pBF);
+ Disconnect(pPinTo);
+ Disconnect(pPin);
+ RemoveFilter(pBF);
+ }
+ }
+ }
+ else
+ {
+ return E_INVALIDARG;
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP CFGManager::FindInterface(REFIID iid, void** ppv, BOOL bRemove)
+{
+ CAutoLock cAutoLock(this);
+
+ CheckPointer(ppv, E_POINTER);
+
+ for(POSITION pos = m_pUnks.GetHeadPosition(); pos; m_pUnks.GetNext(pos))
+ {
+ if(SUCCEEDED(m_pUnks.GetAt(pos)->QueryInterface(iid, ppv)))
+ {
+ if(bRemove) m_pUnks.RemoveAt(pos);
+ return S_OK;
+ }
+ }
+
+ return E_NOINTERFACE;
+}
+
+STDMETHODIMP CFGManager::AddToROT()
+{
+ CAutoLock cAutoLock(this);
+
+ HRESULT hr;
+
+ if(m_dwRegister) return S_FALSE;
+
+ CComPtr<IRunningObjectTable> pROT;
+ CComPtr<IMoniker> pMoniker;
+ WCHAR wsz[256];
+ swprintf(wsz, L"FilterGraph %08p pid %08x (MPC)", (DWORD_PTR)this, GetCurrentProcessId());
+ if(SUCCEEDED(hr = GetRunningObjectTable(0, &pROT))
+ && SUCCEEDED(hr = CreateItemMoniker(L"!", wsz, &pMoniker)))
+ hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, (IGraphBuilder2*)this, pMoniker, &m_dwRegister);
+
+ return hr;
+}
+
+STDMETHODIMP CFGManager::RemoveFromROT()
+{
+ CAutoLock cAutoLock(this);
+
+ HRESULT hr;
+
+ if(!m_dwRegister) return S_FALSE;
+
+ CComPtr<IRunningObjectTable> pROT;
+ if(SUCCEEDED(hr = GetRunningObjectTable(0, &pROT))
+ && SUCCEEDED(hr = pROT->Revoke(m_dwRegister)))
+ m_dwRegister = 0;
+
+ return hr;
+}
+
+// IGraphBuilderDeadEnd
+
+STDMETHODIMP_(size_t) CFGManager::GetCount()
+{
+ CAutoLock cAutoLock(this);
+
+ return m_deadends.GetCount();
+}
+
+STDMETHODIMP CFGManager::GetDeadEnd(int iIndex, CAtlList<CStringW>& path, CAtlList<CMediaType>& mts)
+{
+ CAutoLock cAutoLock(this);
+
+ if(iIndex < 0 || iIndex >= m_deadends.GetCount()) return E_FAIL;
+
+ path.RemoveAll();
+ mts.RemoveAll();
+
+ POSITION pos = m_deadends[iIndex]->GetHeadPosition();
+ while(pos)
+ {
+ const path_t& p = m_deadends[iIndex]->GetNext(pos);
+
+ CStringW str;
+ str.Format(L"%s::%s", p.filter, p.pin);
+ path.AddTail(str);
+ }
+
+ mts.AddTailList(&m_deadends[iIndex]->mts);
+
+ return S_OK;
+}
+
+//
+// CFGManagerCustom
+//
+
+CFGManagerCustom::CFGManagerCustom(LPCTSTR pName, LPUNKNOWN pUnk, UINT src, UINT tra)
+ : CFGManager(pName, pUnk)
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ CFGFilter* pFGF;
+
+ // Source filters
+
+// UINT src = s.SrcFilters;
+
+ if(src & SRC_SHOUTCAST)
+ {
+ pFGF = new CFGFilterInternal<CShoutcastSource>();
+ pFGF->m_protocols.AddTail(_T("http"));
+ m_source.AddTail(pFGF);
+ }
+
+ // if(src & SRC_UDP)
+ {
+ pFGF = new CFGFilterInternal<CUDPReader>();
+ pFGF->m_protocols.AddTail(_T("udp"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_AVI)
+ {
+ pFGF = new CFGFilterInternal<CAviSourceFilter>();
+ pFGF->m_chkbytes.AddTail(_T("0,4,,52494646,8,4,,41564920"));
+ pFGF->m_chkbytes.AddTail(_T("0,4,,52494646,8,4,,41564958"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_MP4)
+ {
+ pFGF = new CFGFilterInternal<CMP4SourceFilter>();
+ pFGF->m_chkbytes.AddTail(_T("4,4,,66747970")); // ftyp
+ pFGF->m_chkbytes.AddTail(_T("4,4,,6d6f6f76")); // moov
+ pFGF->m_chkbytes.AddTail(_T("4,4,,6d646174")); // mdat
+ pFGF->m_chkbytes.AddTail(_T("4,4,,736b6970")); // skip
+ pFGF->m_chkbytes.AddTail(_T("4,12,ffffffff00000000ffffffff,77696465027fe3706d646174")); // wide ? mdat
+ pFGF->m_extensions.AddTail(_T(".mov"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_MATROSKA)
+ {
+ pFGF = new CFGFilterInternal<CMatroskaSourceFilter>();
+ pFGF->m_chkbytes.AddTail(_T("0,4,,1A45DFA3"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_REALMEDIA)
+ {
+ pFGF = new CFGFilterInternal<CRealMediaSourceFilter>();
+ pFGF->m_chkbytes.AddTail(_T("0,4,,2E524D46"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_DSM)
+ {
+ pFGF = new CFGFilterInternal<CDSMSourceFilter>();
+ pFGF->m_chkbytes.AddTail(_T("0,4,,44534D53"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_FLIC)
+ {
+ pFGF = new CFGFilterInternal<CFLICSource>();
+ pFGF->m_chkbytes.AddTail(_T("4,2,,11AF"));
+ pFGF->m_chkbytes.AddTail(_T("4,2,,12AF"));
+ pFGF->m_extensions.AddTail(_T(".fli"));
+ pFGF->m_extensions.AddTail(_T(".flc"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_CDDA)
+ {
+ pFGF = new CFGFilterInternal<CCDDAReader>();
+ pFGF->m_extensions.AddTail(_T(".cda"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_CDXA)
+ {
+ pFGF = new CFGFilterInternal<CCDXAReader>();
+ pFGF->m_chkbytes.AddTail(_T("0,4,,52494646,8,4,,43445841"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_VTS)
+ {
+ pFGF = new CFGFilterInternal<CVTSReader>();
+ pFGF->m_chkbytes.AddTail(_T("0,12,,445644564944454F2D565453"));
+ m_source.AddTail(pFGF);
+ }
+
+ __if_exists(CD2VSource)
+ {
+ if(src & SRC_D2V)
+ {
+ pFGF = new CFGFilterInternal<CD2VSource>();
+ pFGF->m_chkbytes.AddTail(_T("0,18,,4456443241564950726F6A65637446696C65"));
+ pFGF->m_extensions.AddTail(_T(".d2v"));
+ m_source.AddTail(pFGF);
+ }
+ }
+
+ __if_exists(CRadGtSourceFilter)
+ {
+ if(src & SRC_RADGT)
+ {
+ pFGF = new CFGFilterInternal<CRadGtSourceFilter>();
+ pFGF->m_chkbytes.AddTail(_T("0,3,,534D4B"));
+ pFGF->m_chkbytes.AddTail(_T("0,3,,42494B"));
+ pFGF->m_extensions.AddTail(_T(".smk"));
+ pFGF->m_extensions.AddTail(_T(".bik"));
+ m_source.AddTail(pFGF);
+ }
+ }
+
+ if(src & SRC_ROQ)
+ {
+ pFGF = new CFGFilterInternal<CRoQSourceFilter>();
+ pFGF->m_chkbytes.AddTail(_T("0,8,,8410FFFFFFFF1E00"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_OGG)
+ {
+ pFGF = new CFGFilterInternal<COggSourceFilter>();
+ pFGF->m_chkbytes.AddTail(_T("0,4,,4F676753"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_NUT)
+ {
+ pFGF = new CFGFilterInternal<CNutSourceFilter>();
+ pFGF->m_chkbytes.AddTail(_T("0,8,,F9526A624E55544D"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_DIRAC)
+ {
+ pFGF = new CFGFilterInternal<CDiracSourceFilter>();
+ pFGF->m_chkbytes.AddTail(_T("0,8,,4B572D4449524143"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_MPEG)
+ {
+ pFGF = new CFGFilterInternal<CMpegSourceFilter>();
+ pFGF->m_chkbytes.AddTail(_T("0,16,FFFFFFFFF100010001800001FFFFFFFF,000001BA2100010001800001000001BB"));
+ pFGF->m_chkbytes.AddTail(_T("0,5,FFFFFFFFC0,000001BA40"));
+ pFGF->m_chkbytes.AddTail(_T("0,1,,47,188,1,,47,376,1,,47"));
+ pFGF->m_chkbytes.AddTail(_T("4,1,,47,196,1,,47,388,1,,47"));
+ pFGF->m_chkbytes.AddTail(_T("0,8,fffffc00ffe00000,4156000055000000"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_DTSAC3)
+ {
+ pFGF = new CFGFilterInternal<CDTSAC3Source>();
+ pFGF->m_chkbytes.AddTail(_T("0,4,,7FFE8001"));
+ pFGF->m_chkbytes.AddTail(_T("0,2,,0B77"));
+ pFGF->m_chkbytes.AddTail(_T("0,2,,770B"));
+ pFGF->m_extensions.AddTail(_T(".ac3"));
+ pFGF->m_extensions.AddTail(_T(".dts"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(src & SRC_MPA)
+ {
+ pFGF = new CFGFilterInternal<CMpaSourceFilter>();
+ pFGF->m_chkbytes.AddTail(_T("0,2,FFE0,FFE0"));
+ pFGF->m_chkbytes.AddTail(_T("0,10,FFFFFF00000080808080,49443300000000000000"));
+ m_source.AddTail(pFGF);
+ }
+
+ if(AfxGetAppSettings().fUseWMASFReader)
+ {
+ pFGF = new CFGFilterRegistry(CLSID_WMAsfReader);
+ pFGF->m_chkbytes.AddTail(_T("0,4,,3026B275"));
+ pFGF->m_chkbytes.AddTail(_T("0,4,,D129E2D6"));
+ m_source.AddTail(pFGF);
+ }
+
+ // Transform filters
+
+// UINT tra = s.TraFilters;
+
+ pFGF = new CFGFilterInternal<CAVI2AC3Filter>(L"AVI<->AC3/DTS", MERIT64(0x00680000)+1);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_WAVE_DOLBY_AC3);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_WAVE_DTS);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CMatroskaSplitterFilter>(
+ (src & SRC_MATROSKA) ? L"Matroska Splitter" : L"Matroska Splitter (low merit)",
+ (src & SRC_MATROSKA) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_Matroska);
+ pFGF->AddType(MEDIATYPE_Stream, GUID_NULL);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CRealMediaSplitterFilter>(
+ (src & SRC_REALMEDIA) ? L"RealMedia Splitter" : L"RealMedia Splitter (low merit)",
+ (src & SRC_REALMEDIA) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_RealMedia);
+ pFGF->AddType(MEDIATYPE_Stream, GUID_NULL);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CAviSplitterFilter>(
+ (src & SRC_AVI) ? L"Avi Splitter" : L"Avi Splitter (low merit)",
+ (src & SRC_AVI) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_Avi);
+ pFGF->AddType(MEDIATYPE_Stream, GUID_NULL);
+ m_transform.AddTail(pFGF);
+
+ __if_exists(CRadGtSplitterFilter)
+ {
+ pFGF = new CFGFilterInternal<CRadGtSplitterFilter>(
+ (src & SRC_RADGT) ? L"RadGt Splitter" : L"RadGt Splitter (low merit)",
+ (src & SRC_RADGT) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_Bink);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_Smacker);
+ pFGF->AddType(MEDIATYPE_Stream, GUID_NULL);
+ m_transform.AddTail(pFGF);
+ }
+
+ pFGF = new CFGFilterInternal<CRoQSplitterFilter>(
+ (src & SRC_ROQ) ? L"RoQ Splitter" : L"RoQ Splitter (low merit)",
+ (src & SRC_ROQ) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_RoQ);
+ pFGF->AddType(MEDIATYPE_Stream, GUID_NULL);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<COggSplitterFilter>(
+ (src & SRC_OGG) ? L"Ogg Splitter" : L"Ogg Splitter (low merit)",
+ (src & SRC_OGG) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_Ogg);
+ pFGF->AddType(MEDIATYPE_Stream, GUID_NULL);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CNutSplitterFilter>(
+ (src & SRC_NUT) ? L"Nut Splitter" : L"Nut Splitter (low merit)",
+ (src & SRC_NUT) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_Nut);
+ pFGF->AddType(MEDIATYPE_Stream, GUID_NULL);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CMpegSplitterFilter>(
+ (src & SRC_MPEG) ? L"Mpeg Splitter" : L"Mpeg Splitter (low merit)",
+ (src & SRC_MPEG) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG1System);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG2_PROGRAM);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG2_TRANSPORT);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG2_PVA);
+ pFGF->AddType(MEDIATYPE_Stream, GUID_NULL);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CDiracSplitterFilter>(
+ (src & SRC_DIRAC) ? L"Dirac Splitter" : L"Dirac Splitter (low merit)",
+ (src & SRC_DIRAC) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_Dirac);
+ pFGF->AddType(MEDIATYPE_Stream, GUID_NULL);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CMpaSplitterFilter>(
+ (src & SRC_MPA) ? L"Mpa Splitter" : L"Mpa Splitter (low merit)",
+ (src & SRC_MPA) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG1Audio);
+ pFGF->AddType(MEDIATYPE_Stream, GUID_NULL);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CDSMSplitterFilter>(
+ (src & SRC_DSM) ? L"DSM Splitter" : L"DSM Splitter (low merit)",
+ (src & SRC_DSM) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_DirectShowMedia);
+ pFGF->AddType(MEDIATYPE_Stream, GUID_NULL);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CMP4SplitterFilter>(
+ (src & SRC_MP4) ? L"MP4 Splitter" : L"MP4 Splitter (low merit)",
+ (src & SRC_MP4) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Stream, MEDIASUBTYPE_MP4);
+ pFGF->AddType(MEDIATYPE_Stream, GUID_NULL);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CMpeg2DecFilter>(
+ (tra & TRA_MPEG1) ? L"MPEG-1 Video Decoder" : L"MPEG-1 Video Decoder (low merit)",
+ (tra & TRA_MPEG1) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MPEG1Packet);
+ pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MPEG1Payload);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CMpeg2DecFilter>(
+ (tra & TRA_MPEG2) ? L"MPEG-2 Video Decoder" : L"MPEG-2 Video Decoder (low merit)",
+ (tra & TRA_MPEG2) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_MPEG2_VIDEO);
+ pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_MPEG2_VIDEO);
+ pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_MPEG2_VIDEO);
+ pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_MPEG2_VIDEO);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CMpaDecFilter>(
+ (tra & TRA_MPA) ? L"MPEG-1 Audio Decoder" : L"MPEG-1 Audio Decoder (low merit)",
+ (tra & TRA_MPA) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_MP3);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_MPEG1AudioPayload);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_MPEG1Payload);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_MPEG1Packet);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CMpaDecFilter>(
+ (tra & TRA_MPA) ? L"MPEG-2 Audio Decoder" : L"MPEG-2 Audio Decoder (low merit)",
+ (tra & TRA_MPA) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_MPEG2_AUDIO);
+ pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_MPEG2_AUDIO);
+ pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_MPEG2_AUDIO);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_MPEG2_AUDIO);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CMpaDecFilter>(
+ (tra & TRA_LPCM) ? L"LPCM Audio Decoder" : L"LPCM Audio Decoder (low merit)",
+ (tra & TRA_LPCM) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_DVD_LPCM_AUDIO);
+ pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_DVD_LPCM_AUDIO);
+ pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_DVD_LPCM_AUDIO);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_DVD_LPCM_AUDIO);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CMpaDecFilter>(
+ (tra & TRA_AC3) ? L"AC3 Audio Decoder" : L"AC3 Audio Decoder (low merit)",
+ (tra & TRA_AC3) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_DOLBY_AC3);
+ pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_DOLBY_AC3);
+ pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_DOLBY_AC3);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_DOLBY_AC3);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_WAVE_DOLBY_AC3);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CMpaDecFilter>(
+ (tra & TRA_DTS) ? L"DTS Decoder" : L"DTS Decoder (low merit)",
+ (tra & TRA_DTS) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_DTS);
+ pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_DTS);
+ pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_DTS);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_DTS);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_WAVE_DTS);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CMpaDecFilter>(
+ (tra & TRA_AAC) ? L"AAC Decoder" : L"AAC Decoder (low merit)",
+ (tra & TRA_AAC) ? MERIT64_ABOVE_DSHOW+1 : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_AAC);
+ pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_AAC);
+ pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_AAC);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_AAC);
+ pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_MP4A);
+ pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_MP4A);
+ pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_MP4A);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_MP4A);
+ pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_mp4a);
+ pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_mp4a);
+ pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_mp4a);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_mp4a);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CMpaDecFilter>(
+ (tra & TRA_PS2AUD) ? L"PS2 Audio Decoder" : L"PS2 Audio Decoder (low merit)",
+ (tra & TRA_PS2AUD) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_DVD_ENCRYPTED_PACK, MEDIASUBTYPE_PS2_PCM);
+ pFGF->AddType(MEDIATYPE_MPEG2_PACK, MEDIASUBTYPE_PS2_PCM);
+ pFGF->AddType(MEDIATYPE_MPEG2_PES, MEDIASUBTYPE_PS2_PCM);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_PS2_PCM);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CRealVideoDecoder>(
+ (tra & TRA_RV) ? L"RealVideo Decoder" : L"RealVideo Decoder (low merit)",
+ (tra & TRA_RV) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_RV10);
+ pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_RV20);
+ pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_RV30);
+ pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_RV40);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CRealAudioDecoder>(
+ (tra & TRA_RA) ? L"RealAudio Decoder" : L"RealAudio Decoder (low merit)",
+ (tra & TRA_RA) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_14_4);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_28_8);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_ATRC);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_COOK);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_DNET);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_SIPR);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_RAAC);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CRoQVideoDecoder>(
+ (tra & TRA_RV) ? L"RoQ Video Decoder" : L"RoQ Video Decoder (low merit)",
+ (tra & TRA_RV) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_RoQV);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CRoQAudioDecoder>(
+ (tra & TRA_RA) ? L"RoQ Audio Decoder" : L"RoQ Audio Decoder (low merit)",
+ (tra & TRA_RA) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_RoQA);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CDiracVideoDecoder>(
+ (tra & TRA_DIRAC) ? L"Dirac Video Decoder" : L"Dirac Video Decoder (low merit)",
+ (tra & TRA_DIRAC) ? MERIT64_ABOVE_DSHOW : MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_DiracVideo);
+ m_transform.AddTail(pFGF);
+
+ pFGF = new CFGFilterInternal<CNullTextRenderer>(L"NullTextRenderer", MERIT64_DO_USE);
+ pFGF->AddType(MEDIATYPE_Text, MEDIASUBTYPE_NULL);
+ pFGF->AddType(MEDIATYPE_ScriptCommand, MEDIASUBTYPE_NULL);
+ pFGF->AddType(MEDIATYPE_Subtitle, MEDIASUBTYPE_NULL);
+ pFGF->AddType(MEDIATYPE_Text, MEDIASUBTYPE_NULL);
+ pFGF->AddType(MEDIATYPE_NULL, MEDIASUBTYPE_DVD_SUBPICTURE);
+ pFGF->AddType(MEDIATYPE_NULL, MEDIASUBTYPE_CVD_SUBPICTURE);
+ pFGF->AddType(MEDIATYPE_NULL, MEDIASUBTYPE_SVCD_SUBPICTURE);
+ m_transform.AddTail(pFGF);
+
+ // Blocked filters
+
+ // "Subtitle Mixer" makes an access violation around the
+ // 11-12th media type when enumerating them on its output.
+ m_transform.AddTail(new CFGFilterRegistry(GUIDFromCString(_T("{00A95963-3BE5-48C0-AD9F-3356D67EA09D}")), MERIT64_DO_NOT_USE));
+
+ // ISCR suxx
+ m_transform.AddTail(new CFGFilterRegistry(GUIDFromCString(_T("{48025243-2D39-11CE-875D-00608CB78066}")), MERIT64_DO_NOT_USE));
+
+ // Samsung's "mpeg-4 demultiplexor" can even open matroska files, amazing...
+ m_transform.AddTail(new CFGFilterRegistry(GUIDFromCString(_T("{99EC0C72-4D1B-411B-AB1F-D561EE049D94}")), MERIT64_DO_NOT_USE));
+
+ // LG Video Renderer (lgvid.ax) just crashes when trying to connect it
+ m_transform.AddTail(new CFGFilterRegistry(GUIDFromCString(_T("{9F711C60-0668-11D0-94D4-0000C02BA972}")), MERIT64_DO_NOT_USE));
+
+ // palm demuxer crashes (even crashes graphedit when dropping an .ac3 onto it)
+ m_transform.AddTail(new CFGFilterRegistry(GUIDFromCString(_T("{BE2CF8A7-08CE-4A2C-9A25-FD726A999196}")), MERIT64_DO_NOT_USE));
+
+ // DCDSPFilter (early versions crash mpc)
+ {
+ CRegKey key;
+
+ TCHAR buff[256];
+ ULONG len = sizeof(buff);
+ memset(buff, 0, len);
+
+ CString clsid = _T("{B38C58A0-1809-11D6-A458-EDAE78F1DF12}");
+
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, _T("CLSID\\") + clsid + _T("\\InprocServer32"), KEY_READ)
+ && ERROR_SUCCESS == key.QueryStringValue(NULL, buff, &len)
+ && GetFileVersion(buff) < 0x0001000000030000ui64)
+ {
+ m_transform.AddTail(new CFGFilterRegistry(GUIDFromCString(clsid), MERIT64_DO_NOT_USE));
+ }
+ }
+
+ // Overrides
+
+ WORD merit_low = 1;
+
+ POSITION pos = s.filters.GetTailPosition();
+ while(pos)
+ {
+ FilterOverride* fo = s.filters.GetPrev(pos);
+
+ if(fo->fDisabled || fo->type == FilterOverride::EXTERNAL && !CPath(MakeFullPath(fo->path)).FileExists())
+ continue;
+
+ ULONGLONG merit =
+ fo->iLoadType == FilterOverride::PREFERRED ? MERIT64_ABOVE_DSHOW :
+ fo->iLoadType == FilterOverride::MERIT ? MERIT64(fo->dwMerit) :
+ MERIT64_DO_NOT_USE; // fo->iLoadType == FilterOverride::BLOCKED
+
+ merit += merit_low++;
+
+ CFGFilter* pFGF = NULL;
+
+ if(fo->type == FilterOverride::REGISTERED)
+ {
+ pFGF = new CFGFilterRegistry(fo->dispname, merit);
+ }
+ else if(fo->type == FilterOverride::EXTERNAL)
+ {
+ pFGF = new CFGFilterFile(fo->clsid, fo->path, CStringW(fo->name), merit);
+ }
+
+ if(pFGF)
+ {
+ pFGF->SetTypes(fo->guids);
+ m_override.AddTail(pFGF);
+ }
+ }
+}
+
+STDMETHODIMP CFGManagerCustom::AddFilter(IBaseFilter* pBF, LPCWSTR pName)
+{
+ CAutoLock cAutoLock(this);
+
+ HRESULT hr;
+
+ if(FAILED(hr = __super::AddFilter(pBF, pName)))
+ return hr;
+
+ AppSettings& s = AfxGetAppSettings();
+
+ if(GetCLSID(pBF) == CLSID_DMOWrapperFilter)
+ {
+ if(CComQIPtr<IPropertyBag> pPB = pBF)
+ {
+ CComVariant var(true);
+ pPB->Write(CComBSTR(L"_HIRESOUTPUT"), &var);
+ }
+ }
+
+ if(CComQIPtr<IAudioSwitcherFilter> pASF = pBF)
+ {
+ pASF->EnableDownSamplingTo441(s.fDownSampleTo441);
+ pASF->SetSpeakerConfig(s.fCustomChannelMapping, s.pSpeakerToChannelMap);
+ pASF->SetAudioTimeShift(s.fAudioTimeShift ? 10000i64*s.tAudioTimeShift : 0);
+ pASF->SetNormalizeBoost(s.fAudioNormalize, s.fAudioNormalizeRecover, s.AudioBoost);
+ }
+
+ return hr;
+}
+
+//
+// CFGManagerPlayer
+//
+
+CFGManagerPlayer::CFGManagerPlayer(LPCTSTR pName, LPUNKNOWN pUnk, UINT src, UINT tra, HWND hWnd)
+ : CFGManagerCustom(pName, pUnk, src, tra)
+ , m_hWnd(hWnd)
+ , m_vrmerit(MERIT64(MERIT_PREFERRED))
+ , m_armerit(MERIT64(MERIT_PREFERRED))
+{
+ CFGFilter* pFGF;
+
+ AppSettings& s = AfxGetAppSettings();
+
+ if(m_pFM)
+ {
+ CComPtr<IEnumMoniker> pEM;
+
+ GUID guids[] = {MEDIATYPE_Video, MEDIASUBTYPE_NULL};
+
+ if(SUCCEEDED(m_pFM->EnumMatchingFilters(&pEM, 0, FALSE, MERIT_DO_NOT_USE+1,
+ TRUE, 1, guids, NULL, NULL, TRUE, FALSE, 0, NULL, NULL, NULL)))
+ {
+ for(CComPtr<IMoniker> pMoniker; S_OK == pEM->Next(1, &pMoniker, NULL); pMoniker = NULL)
+ {
+ CFGFilterRegistry f(pMoniker);
+ m_vrmerit = max(m_vrmerit, f.GetMerit());
+ }
+ }
+
+ m_vrmerit += 0x100;
+ }
+
+ if(m_pFM)
+ {
+ CComPtr<IEnumMoniker> pEM;
+
+ GUID guids[] = {MEDIATYPE_Audio, MEDIASUBTYPE_NULL};
+
+ if(SUCCEEDED(m_pFM->EnumMatchingFilters(&pEM, 0, FALSE, MERIT_DO_NOT_USE+1,
+ TRUE, 1, guids, NULL, NULL, TRUE, FALSE, 0, NULL, NULL, NULL)))
+ {
+ for(CComPtr<IMoniker> pMoniker; S_OK == pEM->Next(1, &pMoniker, NULL); pMoniker = NULL)
+ {
+ CFGFilterRegistry f(pMoniker);
+ m_armerit = max(m_armerit, f.GetMerit());
+ }
+ }
+
+ BeginEnumSysDev(CLSID_AudioRendererCategory, pMoniker)
+ {
+ CFGFilterRegistry f(pMoniker);
+ m_armerit = max(m_armerit, f.GetMerit());
+ }
+ EndEnumSysDev
+
+ m_armerit += 0x100;
+ }
+
+ // Switchers
+
+ if(s.fEnableAudioSwitcher)
+ {
+ pFGF = new CFGFilterInternal<CAudioSwitcherFilter>(L"Audio Switcher", m_armerit + 0x100);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_NULL);
+ m_transform.AddTail(pFGF);
+
+ // morgan stream switcher
+ m_transform.AddTail(new CFGFilterRegistry(GUIDFromCString(_T("{D3CD7858-971A-4838-ACEC-40CA5D529DC8}")), MERIT64_DO_NOT_USE));
+ }
+
+ // Renderers
+
+ if(s.iDSVideoRendererType == VIDRNDT_DS_OLDRENDERER)
+ m_transform.AddTail(new CFGFilterRegistry(CLSID_VideoRenderer, m_vrmerit));
+ else if(s.iDSVideoRendererType == VIDRNDT_DS_OVERLAYMIXER)
+ m_transform.AddTail(new CFGFilterVideoRenderer(m_hWnd, CLSID_OverlayMixer, L"Overlay Mixer", m_vrmerit));
+ else if(s.iDSVideoRendererType == VIDRNDT_DS_VMR7WINDOWED)
+ m_transform.AddTail(new CFGFilterVideoRenderer(m_hWnd, CLSID_VideoMixingRenderer, L"Video Mixing Render 7 (Windowed)", m_vrmerit));
+ else if(s.iDSVideoRendererType == VIDRNDT_DS_VMR9WINDOWED)
+ m_transform.AddTail(new CFGFilterVideoRenderer(m_hWnd, CLSID_VideoMixingRenderer9, L"Video Mixing Render 9 (Windowed)", m_vrmerit));
+ else if(s.iDSVideoRendererType == VIDRNDT_DS_VMR7RENDERLESS)
+ m_transform.AddTail(new CFGFilterVideoRenderer(m_hWnd, CLSID_VMR7AllocatorPresenter, L"Video Mixing Render 7 (Renderless)", m_vrmerit));
+ else if(s.iDSVideoRendererType == VIDRNDT_DS_VMR9RENDERLESS)
+ m_transform.AddTail(new CFGFilterVideoRenderer(m_hWnd, CLSID_VMR9AllocatorPresenter, L"Video Mixing Render 9 (Renderless)", m_vrmerit));
+ else if(s.iDSVideoRendererType == VIDRNDT_DS_DXR)
+ m_transform.AddTail(new CFGFilterVideoRenderer(m_hWnd, CLSID_DXRAllocatorPresenter, L"Haali's Video Renderer", m_vrmerit));
+ else if(s.iDSVideoRendererType == VIDRNDT_DS_NULL_COMP)
+ {
+ pFGF = new CFGFilterInternal<CNullVideoRenderer>(L"Null Video Renderer (Any)", MERIT64_ABOVE_DSHOW+2);
+ pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_NULL);
+ m_transform.AddTail(pFGF);
+ }
+ else if(s.iDSVideoRendererType == VIDRNDT_DS_NULL_UNCOMP)
+ {
+ pFGF = new CFGFilterInternal<CNullUVideoRenderer>(L"Null Video Renderer (Uncompressed)", MERIT64_ABOVE_DSHOW+2);
+ pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_NULL);
+ m_transform.AddTail(pFGF);
+ }
+
+ if(s.AudioRendererDisplayName == AUDRNDT_NULL_COMP)
+ {
+ pFGF = new CFGFilterInternal<CNullAudioRenderer>(AUDRNDT_NULL_COMP, MERIT64_ABOVE_DSHOW+2);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_NULL);
+ m_transform.AddTail(pFGF);
+ }
+ else if(s.AudioRendererDisplayName == AUDRNDT_NULL_UNCOMP)
+ {
+ pFGF = new CFGFilterInternal<CNullUAudioRenderer>(AUDRNDT_NULL_UNCOMP, MERIT64_ABOVE_DSHOW+2);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_NULL);
+ m_transform.AddTail(pFGF);
+ }
+ else if(!s.AudioRendererDisplayName.IsEmpty())
+ {
+ pFGF = new CFGFilterRegistry(s.AudioRendererDisplayName, m_armerit);
+ pFGF->AddType(MEDIATYPE_Audio, MEDIASUBTYPE_NULL);
+ m_transform.AddTail(pFGF);
+ }
+}
+
+STDMETHODIMP CFGManagerPlayer::ConnectDirect(IPin* pPinOut, IPin* pPinIn, const AM_MEDIA_TYPE* pmt)
+{
+ CAutoLock cAutoLock(this);
+
+ if(GetCLSID(pPinOut) == CLSID_MPEG2Demultiplexer)
+ {
+ CComQIPtr<IMediaSeeking> pMS = pPinOut;
+ REFERENCE_TIME rtDur = 0;
+ if(!pMS || FAILED(pMS->GetDuration(&rtDur)) || rtDur <= 0)
+ return E_FAIL;
+ }
+
+ return __super::ConnectDirect(pPinOut, pPinIn, pmt);
+}
+
+//
+// CFGManagerDVD
+//
+
+CFGManagerDVD::CFGManagerDVD(LPCTSTR pName, LPUNKNOWN pUnk, UINT src, UINT tra, HWND hWnd)
+ : CFGManagerPlayer(pName, pUnk, src, tra, hWnd)
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ if(!s.fXpOrBetter && s.iDSVideoRendererType != VIDRNDT_DS_OVERLAYMIXER || s.iDSVideoRendererType == VIDRNDT_DS_OLDRENDERER)
+ m_transform.AddTail(new CFGFilterVideoRenderer(m_hWnd, CLSID_OverlayMixer, L"Overlay Mixer", m_vrmerit-1));
+
+ // elecard's decoder isn't suited for dvd playback (atm)
+ m_transform.AddTail(new CFGFilterRegistry(GUIDFromCString(_T("{F50B3F13-19C4-11CF-AA9A-02608C9BABA2}")), MERIT64_DO_NOT_USE));
+}
+
+#include "..\..\decss\VobFile.h"
+
+class CResetDVD : public CDVDSession
+{
+public:
+ CResetDVD(LPCTSTR path)
+ {
+ if(Open(path))
+ {
+ if(BeginSession()) {Authenticate(); /*GetDiscKey();*/ EndSession();}
+ Close();
+ }
+ }
+};
+
+STDMETHODIMP CFGManagerDVD::AddSourceFilter(LPCWSTR lpcwstrFileName, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter)
+{
+ CAutoLock cAutoLock(this);
+
+ CheckPointer(lpcwstrFileName, E_POINTER);
+ CheckPointer(ppFilter, E_POINTER);
+
+ HRESULT hr;
+
+ CStringW fn = CStringW(lpcwstrFileName).TrimLeft();
+ CStringW protocol = fn.Left(fn.Find(':')+1).TrimRight(':').MakeLower();
+ CStringW ext = CPathW(fn).GetExtension();
+
+ GUID clsid = ext == L".ratdvd" ? GUIDFromCString(_T("{482d10b6-376e-4411-8a17-833800A065DB}")) : CLSID_DVDNavigator;
+
+ CComPtr<IBaseFilter> pBF;
+ if(FAILED(hr = pBF.CoCreateInstance(clsid))
+ || FAILED(hr = AddFilter(pBF, L"DVD Navigator")))
+ return VFW_E_CANNOT_LOAD_SOURCE_FILTER;
+
+ CComQIPtr<IDvdControl2> pDVDC;
+ CComQIPtr<IDvdInfo2> pDVDI;
+
+ if(!((pDVDC = pBF) && (pDVDI = pBF)))
+ return E_NOINTERFACE;
+
+ WCHAR buff[MAX_PATH];
+ ULONG len;
+ if((!fn.IsEmpty()
+ && FAILED(hr = pDVDC->SetDVDDirectory(fn))
+ && FAILED(hr = pDVDC->SetDVDDirectory(fn + L"VIDEO_TS"))
+ && FAILED(hr = pDVDC->SetDVDDirectory(fn + L"\\VIDEO_TS")))
+ || FAILED(hr = pDVDI->GetDVDDirectory(buff, countof(buff), &len)) || len == 0)
+ return VFW_E_CANNOT_LOAD_SOURCE_FILTER;
+
+ pDVDC->SetOption(DVD_ResetOnStop, FALSE);
+ pDVDC->SetOption(DVD_HMSF_TimeCodeEvents, TRUE);
+
+ m_pUnks.AddTail(pDVDC);
+ m_pUnks.AddTail(pDVDI);
+
+ if(clsid == CLSID_DVDNavigator)
+ CResetDVD(CString(buff));
+
+ *ppFilter = pBF.Detach();
+
+ return S_OK;
+}
+
+//
+// CFGManagerCapture
+//
+
+CFGManagerCapture::CFGManagerCapture(LPCTSTR pName, LPUNKNOWN pUnk, UINT src, UINT tra, HWND hWnd)
+ : CFGManagerPlayer(pName, pUnk, src, tra, hWnd)
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ CFGFilter* pFGF = new CFGFilterInternal<CDeinterlacerFilter>(L"Deinterlacer", m_vrmerit + 0x100);
+ pFGF->AddType(MEDIATYPE_Video, MEDIASUBTYPE_NULL);
+ m_transform.AddTail(pFGF);
+
+ // morgan stream switcher
+ m_transform.AddTail(new CFGFilterRegistry(GUIDFromCString(_T("{D3CD7858-971A-4838-ACEC-40CA5D529DC8}")), MERIT64_DO_NOT_USE));
+}
+
+//
+// CFGManagerMuxer
+//
+
+CFGManagerMuxer::CFGManagerMuxer(LPCTSTR pName, LPUNKNOWN pUnk)
+ : CFGManagerCustom(pName, pUnk, ~0, ~0)
+{
+ m_source.AddTail(new CFGFilterInternal<CSubtitleSourceASS>());
+}
+
diff --git a/src/apps/mplayerc/FGManager.h b/src/apps/mplayerc/FGManager.h
new file mode 100644
index 000000000..a660b5478
--- /dev/null
+++ b/src/apps/mplayerc/FGManager.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "FGFilter.h"
+#include "IGraphBuilder2.h"
+
+class CFGManager
+ : public CUnknown
+ , public IGraphBuilder2
+ , public IGraphBuilderDeadEnd
+ , public CCritSec
+{
+public:
+ struct path_t {CLSID clsid; CString filter, pin;};
+
+ class CStreamPath : public CAtlList<path_t>
+ {
+ public:
+ void Append(IBaseFilter* pBF, IPin* pPin);
+ bool Compare(const CStreamPath& path);
+ };
+
+ class CStreamDeadEnd : public CStreamPath
+ {
+ public:
+ CAtlList<CMediaType> mts;
+ };
+
+private:
+ CComPtr<IUnknown> m_pUnkInner;
+ DWORD m_dwRegister;
+
+ CStreamPath m_streampath;
+ CAutoPtrArray<CStreamDeadEnd> m_deadends;
+
+protected:
+ CComPtr<IFilterMapper2> m_pFM;
+ CInterfaceList<IUnknown, &IID_IUnknown> m_pUnks;
+ CAtlList<CFGFilter*> m_source, m_transform, m_override;
+
+ static bool CheckBytes(HANDLE hFile, CString chkbytes);
+
+ HRESULT AddSourceFilter(CFGFilter* pFGF, LPCWSTR lpcwstrFileName, LPCWSTR lpcwstrFilterName, IBaseFilter** ppBF);
+
+ // IFilterGraph
+
+ STDMETHODIMP AddFilter(IBaseFilter* pFilter, LPCWSTR pName);
+ STDMETHODIMP RemoveFilter(IBaseFilter* pFilter);
+ STDMETHODIMP EnumFilters(IEnumFilters** ppEnum);
+ STDMETHODIMP FindFilterByName(LPCWSTR pName, IBaseFilter** ppFilter);
+ STDMETHODIMP ConnectDirect(IPin* pPinOut, IPin* pPinIn, const AM_MEDIA_TYPE* pmt);
+ STDMETHODIMP Reconnect(IPin* ppin);
+ STDMETHODIMP Disconnect(IPin* ppin);
+ STDMETHODIMP SetDefaultSyncSource();
+
+ // IGraphBuilder
+
+ STDMETHODIMP Connect(IPin* pPinOut, IPin* pPinIn);
+ STDMETHODIMP Render(IPin* pPinOut);
+ STDMETHODIMP RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList);
+ STDMETHODIMP AddSourceFilter(LPCWSTR lpcwstrFileName, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter);
+ STDMETHODIMP SetLogFile(DWORD_PTR hFile);
+ STDMETHODIMP Abort();
+ STDMETHODIMP ShouldOperationContinue();
+
+ // IFilterGraph2
+
+ STDMETHODIMP AddSourceFilterForMoniker(IMoniker* pMoniker, IBindCtx* pCtx, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter);
+ STDMETHODIMP ReconnectEx(IPin* ppin, const AM_MEDIA_TYPE* pmt);
+ STDMETHODIMP RenderEx(IPin* pPinOut, DWORD dwFlags, DWORD* pvContext);
+
+ // IGraphBuilder2
+
+ STDMETHODIMP IsPinDirection(IPin* pPin, PIN_DIRECTION dir);
+ STDMETHODIMP IsPinConnected(IPin* pPin);
+ STDMETHODIMP ConnectFilter(IBaseFilter* pBF, IPin* pPinIn);
+ STDMETHODIMP ConnectFilter(IPin* pPinOut, IBaseFilter* pBF);
+ STDMETHODIMP ConnectFilterDirect(IPin* pPinOut, IBaseFilter* pBF, const AM_MEDIA_TYPE* pmt);
+ STDMETHODIMP NukeDownstream(IUnknown* pUnk);
+ STDMETHODIMP FindInterface(REFIID iid, void** ppv, BOOL bRemove);
+ STDMETHODIMP AddToROT();
+ STDMETHODIMP RemoveFromROT();
+
+ // IGraphBuilderDeadEnd
+
+ STDMETHODIMP_(size_t) GetCount();
+ STDMETHODIMP GetDeadEnd(int iIndex, CAtlList<CStringW>& path, CAtlList<CMediaType>& mts);
+
+public:
+ CFGManager(LPCTSTR pName, LPUNKNOWN pUnk);
+ virtual ~CFGManager();
+
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+};
+
+class CFGManagerCustom : public CFGManager
+{
+public:
+ // IFilterGraph
+
+ STDMETHODIMP AddFilter(IBaseFilter* pFilter, LPCWSTR pName);
+
+public:
+ CFGManagerCustom(LPCTSTR pName, LPUNKNOWN pUnk, UINT src, UINT tra);
+};
+
+class CFGManagerPlayer : public CFGManagerCustom
+{
+protected:
+ HWND m_hWnd;
+ UINT64 m_vrmerit, m_armerit;
+
+ // IFilterGraph
+
+ STDMETHODIMP ConnectDirect(IPin* pPinOut, IPin* pPinIn, const AM_MEDIA_TYPE* pmt);
+
+public:
+ CFGManagerPlayer(LPCTSTR pName, LPUNKNOWN pUnk, UINT src, UINT tra, HWND hWnd);
+};
+
+class CFGManagerDVD : public CFGManagerPlayer
+{
+protected:
+ // IGraphBuilder
+
+ STDMETHODIMP AddSourceFilter(LPCWSTR lpcwstrFileName, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter);
+
+public:
+ CFGManagerDVD(LPCTSTR pName, LPUNKNOWN pUnk, UINT src, UINT tra, HWND hWnd);
+};
+
+class CFGManagerCapture : public CFGManagerPlayer
+{
+public:
+ CFGManagerCapture(LPCTSTR pName, LPUNKNOWN pUnk, UINT src, UINT tra, HWND hWnd);
+};
+
+class CFGManagerMuxer : public CFGManagerCustom
+{
+public:
+ CFGManagerMuxer(LPCTSTR pName, LPUNKNOWN pUnk);
+};
+
diff --git a/src/apps/mplayerc/FakeFilterMapper2.cpp b/src/apps/mplayerc/FakeFilterMapper2.cpp
new file mode 100644
index 000000000..216c9b2d5
--- /dev/null
+++ b/src/apps/mplayerc/FakeFilterMapper2.cpp
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "fakefiltermapper2.h"
+#include "MacrovisionKicker.h"
+#include "..\..\..\include\detours\detours.h"
+#include "..\..\DSUtil\DSUtil.h"
+
+#include <initguid.h>
+#include <qedit.h>
+
+DETOUR_TRAMPOLINE(HRESULT WINAPI Real_CoCreateInstance(IN REFCLSID rclsid, IN LPUNKNOWN pUnkOuter, IN DWORD dwClsContext, IN REFIID riid, OUT LPVOID FAR* ppv), CoCreateInstance);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegCloseKey(HKEY a0), RegCloseKey);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegFlushKey(HKEY a0), RegFlushKey);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegCreateKeyA(HKEY a0, LPCSTR a1, PHKEY a2), RegCreateKeyA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegCreateKeyW(HKEY a0, LPCWSTR a1, PHKEY a2), RegCreateKeyW);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegCreateKeyExA(HKEY a0, LPCSTR a1, DWORD a2, LPSTR a3, DWORD a4, REGSAM a5, LPSECURITY_ATTRIBUTES a6, PHKEY a7, LPDWORD a8), RegCreateKeyExA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegCreateKeyExW(HKEY a0, LPCWSTR a1, DWORD a2, LPWSTR a3, DWORD a4, REGSAM a5, LPSECURITY_ATTRIBUTES a6, PHKEY a7, LPDWORD a8), RegCreateKeyExW);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegDeleteKeyA(HKEY a0, LPCSTR a1), RegDeleteKeyA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegDeleteKeyW(HKEY a0, LPCWSTR a1), RegDeleteKeyW);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegDeleteValueA(HKEY a0, LPCSTR a1), RegDeleteValueA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegDeleteValueW(HKEY a0, LPCWSTR a1), RegDeleteValueW);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegEnumKeyExA(HKEY a0, DWORD a1, LPSTR a2, LPDWORD a3, LPDWORD a4, LPSTR a5, LPDWORD a6, struct _FILETIME* a7), RegEnumKeyExA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegEnumKeyExW(HKEY a0, DWORD a1, LPWSTR a2, LPDWORD a3, LPDWORD a4, LPWSTR a5, LPDWORD a6, struct _FILETIME* a7), RegEnumKeyExW);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegEnumValueA(HKEY a0, DWORD a1, LPSTR a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPBYTE a6, LPDWORD a7), RegEnumValueA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegEnumValueW(HKEY a0, DWORD a1, LPWSTR a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPBYTE a6, LPDWORD a7), RegEnumValueW);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegOpenKeyA(HKEY a0, LPCSTR a1, PHKEY a2), RegOpenKeyA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegOpenKeyW(HKEY a0, LPCWSTR a1, PHKEY a2), RegOpenKeyW);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegOpenKeyExA(HKEY a0, LPCSTR a1, DWORD a2, REGSAM a3, PHKEY a4), RegOpenKeyExA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegOpenKeyExW(HKEY a0, LPCWSTR a1, DWORD a2, REGSAM a3, PHKEY a4), RegOpenKeyExW);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegQueryInfoKeyA(HKEY a0, LPSTR a1, LPDWORD a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPDWORD a6, LPDWORD a7, LPDWORD a8, LPDWORD a9, LPDWORD a10, struct _FILETIME* a11), RegQueryInfoKeyA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegQueryInfoKeyW(HKEY a0, LPWSTR a1, LPDWORD a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPDWORD a6, LPDWORD a7, LPDWORD a8, LPDWORD a9, LPDWORD a10, struct _FILETIME* a11), RegQueryInfoKeyW);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegQueryValueA(HKEY a0, LPCSTR a1, LPSTR a2, PLONG a3), RegQueryValueA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegQueryValueW(HKEY a0, LPCWSTR a1, LPWSTR a2, PLONG a3), RegQueryValueW);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegQueryValueExA(HKEY a0, LPCSTR a1, LPDWORD a2, LPDWORD a3, LPBYTE a4, LPDWORD a5), RegQueryValueExA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegQueryValueExW(HKEY a0, LPCWSTR a1, LPDWORD a2, LPDWORD a3, LPBYTE a4, LPDWORD a5), RegQueryValueExW);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegSetValueA(HKEY a0, LPCSTR a1, DWORD a2, LPCSTR a3, DWORD a4), RegSetValueA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegSetValueW(HKEY a0, LPCWSTR a1, DWORD a2, LPCWSTR a3, DWORD a4), RegSetValueW);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegSetValueExA(HKEY a0, LPCSTR a1, DWORD a2, DWORD a3, BYTE* a4, DWORD a5), RegSetValueExA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_RegSetValueExW(HKEY a0, LPCWSTR a1, DWORD a2, DWORD a3, BYTE* a4, DWORD a5), RegSetValueExW);
+
+HRESULT WINAPI Mine_CoCreateInstance(IN REFCLSID rclsid, IN LPUNKNOWN pUnkOuter,
+ IN DWORD dwClsContext, IN REFIID riid, OUT LPVOID FAR* ppv)
+{
+ if(CFilterMapper2::m_pFilterMapper2)
+ {
+ CheckPointer(ppv, E_POINTER);
+
+ if(rclsid == CLSID_FilterMapper)
+ {
+ ASSERT(0);
+ return REGDB_E_CLASSNOTREG; // sorry...
+ }
+
+ if(rclsid == CLSID_FilterMapper2)
+ {
+ if(pUnkOuter) return CLASS_E_NOAGGREGATION;
+
+ if(riid == __uuidof(IUnknown))
+ {
+ CFilterMapper2::m_pFilterMapper2->AddRef();
+ *ppv = (IUnknown*)CFilterMapper2::m_pFilterMapper2;
+ return S_OK;
+ }
+ else if(riid == __uuidof(IFilterMapper2))
+ {
+ CFilterMapper2::m_pFilterMapper2->AddRef();
+ *ppv = (IFilterMapper2*)CFilterMapper2::m_pFilterMapper2;
+ return S_OK;
+ }
+ else
+ {
+ return E_NOINTERFACE;
+ }
+ }
+ }
+/* else
+ {
+ if(rclsid == CLSID_FilterMapper2)
+ {
+ CFilterMapper2* pFM2 = new CFilterMapper2(true, false, pUnkOuter);
+ CComPtr<IUnknown> pUnk = (IUnknown*)pFM2;
+ return pUnk->QueryInterface(riid, ppv);
+ }
+ }
+*/
+ if(!pUnkOuter)
+ if(rclsid == CLSID_VideoMixingRenderer || rclsid == CLSID_VideoMixingRenderer9
+ || rclsid == CLSID_VideoRenderer || rclsid == CLSID_VideoRendererDefault
+ || rclsid == CLSID_OverlayMixer)// || rclsid == CLSID_OverlayMixer2 - where is this declared?)
+ {
+ CMacrovisionKicker* pMK = new CMacrovisionKicker(NAME("CMacrovisionKicker"), NULL);
+ CComPtr<IUnknown> pUnk = (IUnknown*)(INonDelegatingUnknown*)pMK;
+ CComPtr<IUnknown> pInner;
+ HRESULT hr;
+ if(SUCCEEDED(hr = Real_CoCreateInstance(rclsid, pUnk, dwClsContext, __uuidof(IUnknown), (void**)&pInner)))
+ {
+ pMK->SetInner(pInner);
+ return pUnk->QueryInterface(riid, ppv);
+ }
+ }
+
+ return Real_CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
+}
+
+#define FAKEHKEY (HKEY)0x12345678
+
+LONG WINAPI Mine_RegCloseKey(HKEY a0)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) {return ERROR_SUCCESS;}
+ return Real_RegCloseKey(a0);
+}
+LONG WINAPI Mine_RegFlushKey(HKEY a0)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) {return ERROR_SUCCESS;}
+ return Real_RegFlushKey(a0);
+}
+LONG WINAPI Mine_RegCreateKeyA(HKEY a0, LPCSTR a1, PHKEY a2)
+{
+ if(CFilterMapper2::m_pFilterMapper2) {*a2 = FAKEHKEY; return ERROR_SUCCESS;}
+ return Real_RegCreateKeyA(a0, a1, a2);
+}
+LONG WINAPI Mine_RegCreateKeyW(HKEY a0, LPCWSTR a1, PHKEY a2)
+{
+ if(CFilterMapper2::m_pFilterMapper2) {*a2 = FAKEHKEY; return ERROR_SUCCESS;}
+ return Real_RegCreateKeyW(a0, a1, a2);
+}
+LONG WINAPI Mine_RegCreateKeyExA(HKEY a0, LPCSTR a1, DWORD a2, LPSTR a3, DWORD a4, REGSAM a5, LPSECURITY_ATTRIBUTES a6, PHKEY a7, LPDWORD a8)
+{
+ if(CFilterMapper2::m_pFilterMapper2) {*a7 = FAKEHKEY; return ERROR_SUCCESS;}
+ return Real_RegCreateKeyExA(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+}
+LONG WINAPI Mine_RegCreateKeyExW(HKEY a0, LPCWSTR a1, DWORD a2, LPWSTR a3, DWORD a4, REGSAM a5, LPSECURITY_ATTRIBUTES a6, PHKEY a7, LPDWORD a8)
+{
+ if(CFilterMapper2::m_pFilterMapper2) {*a7 = FAKEHKEY; return ERROR_SUCCESS;}
+ return Real_RegCreateKeyExW(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+}
+LONG WINAPI Mine_RegDeleteKeyA(HKEY a0, LPCSTR a1)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) {return ERROR_SUCCESS;}
+ return Real_RegDeleteKeyA(a0, a1);
+}
+LONG WINAPI Mine_RegDeleteKeyW(HKEY a0, LPCWSTR a1)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) {return ERROR_SUCCESS;}
+ return Real_RegDeleteKeyW(a0, a1);
+}
+LONG WINAPI Mine_RegDeleteValueA(HKEY a0, LPCSTR a1)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) {return ERROR_SUCCESS;}
+ return Real_RegDeleteValueA(a0, a1);
+}
+LONG WINAPI Mine_RegDeleteValueW(HKEY a0, LPCWSTR a1)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) {return ERROR_SUCCESS;}
+ return Real_RegDeleteValueW(a0, a1);
+}
+LONG WINAPI Mine_RegEnumKeyExA(HKEY a0, DWORD a1, LPSTR a2, LPDWORD a3, LPDWORD a4, LPSTR a5, LPDWORD a6, struct _FILETIME* a7)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) {return ERROR_NO_MORE_ITEMS;}
+ return Real_RegEnumKeyExA(a0, a1, a2, a3, a4, a5, a6, a7);
+}
+LONG WINAPI Mine_RegEnumKeyExW(HKEY a0, DWORD a1, LPWSTR a2, LPDWORD a3, LPDWORD a4, LPWSTR a5, LPDWORD a6, struct _FILETIME* a7)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) {return ERROR_NO_MORE_ITEMS;}
+ return Real_RegEnumKeyExW(a0, a1, a2, a3, a4, a5, a6, a7);
+}
+LONG WINAPI Mine_RegEnumValueA(HKEY a0, DWORD a1, LPSTR a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPBYTE a6, LPDWORD a7)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) {return ERROR_NO_MORE_ITEMS;}
+ return Real_RegEnumValueA(a0, a1, a2, a3, a4, a5, a6, a7);
+}
+LONG WINAPI Mine_RegEnumValueW(HKEY a0, DWORD a1, LPWSTR a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPBYTE a6, LPDWORD a7)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) {return ERROR_NO_MORE_ITEMS;}
+ return Real_RegEnumValueW(a0, a1, a2, a3, a4, a5, a6, a7);
+}
+LONG WINAPI Mine_RegOpenKeyA(HKEY a0, LPCSTR a1, PHKEY a2)
+{
+ if(CFilterMapper2::m_pFilterMapper2) {*a2 = FAKEHKEY; return ERROR_SUCCESS;}
+ return Real_RegOpenKeyA(a0, a1, a2);
+}
+LONG WINAPI Mine_RegOpenKeyW(HKEY a0, LPCWSTR a1, PHKEY a2)
+{
+ if(CFilterMapper2::m_pFilterMapper2) {*a2 = FAKEHKEY; return ERROR_SUCCESS;}
+ return Real_RegOpenKeyW(a0, a1, a2);
+}
+LONG WINAPI Mine_RegOpenKeyExA(HKEY a0, LPCSTR a1, DWORD a2, REGSAM a3, PHKEY a4)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && (a3&(KEY_SET_VALUE|KEY_CREATE_SUB_KEY))) {*a4 = FAKEHKEY; return ERROR_SUCCESS;}
+ return Real_RegOpenKeyExA(a0, a1, a2, a3, a4);
+}
+LONG WINAPI Mine_RegOpenKeyExW(HKEY a0, LPCWSTR a1, DWORD a2, REGSAM a3, PHKEY a4)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && (a3&(KEY_SET_VALUE|KEY_CREATE_SUB_KEY))) {*a4 = FAKEHKEY; return ERROR_SUCCESS;}
+ return Real_RegOpenKeyExW(a0, a1, a2, a3, a4);
+}
+LONG WINAPI Mine_RegQueryInfoKeyA(HKEY a0, LPSTR a1, LPDWORD a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPDWORD a6, LPDWORD a7, LPDWORD a8, LPDWORD a9, LPDWORD a10, struct _FILETIME* a11)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) {return ERROR_INVALID_HANDLE;}
+ return Real_RegQueryInfoKeyA(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+}
+LONG WINAPI Mine_RegQueryInfoKeyW(HKEY a0, LPWSTR a1, LPDWORD a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPDWORD a6, LPDWORD a7, LPDWORD a8, LPDWORD a9, LPDWORD a10, struct _FILETIME* a11)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) {return ERROR_INVALID_HANDLE;}
+ return Real_RegQueryInfoKeyW(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+}
+LONG WINAPI Mine_RegQueryValueA(HKEY a0, LPCSTR a1, LPSTR a2, PLONG a3)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) {*a3 = 0; return ERROR_SUCCESS;}
+ return Real_RegQueryValueA(a0, a1, a2, a3);
+}
+LONG WINAPI Mine_RegQueryValueW(HKEY a0, LPCWSTR a1, LPWSTR a2, PLONG a3)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) {*a3 = 0; return ERROR_SUCCESS;}
+ return Real_RegQueryValueW(a0, a1, a2, a3);
+}
+LONG WINAPI Mine_RegQueryValueExA(HKEY a0, LPCSTR a1, LPDWORD a2, LPDWORD a3, LPBYTE a4, LPDWORD a5)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) {*a5 = 0; return ERROR_SUCCESS;}
+ return Real_RegQueryValueExA(a0, a1, a2, a3, a4, a5);
+}
+LONG WINAPI Mine_RegQueryValueExW(HKEY a0, LPCWSTR a1, LPDWORD a2, LPDWORD a3, LPBYTE a4, LPDWORD a5)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) {*a5 = 0; return ERROR_SUCCESS;}
+ return Real_RegQueryValueExW(a0, a1, a2, a3, a4, a5);
+}
+LONG WINAPI Mine_RegSetValueA(HKEY a0, LPCSTR a1, DWORD a2, LPCSTR a3, DWORD a4)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) {return ERROR_SUCCESS;}
+ return Real_RegSetValueA(a0, a1, a2, a3, a4);
+}
+LONG WINAPI Mine_RegSetValueW(HKEY a0, LPCWSTR a1, DWORD a2, LPCWSTR a3, DWORD a4)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) {return ERROR_SUCCESS;}
+ return Real_RegSetValueW(a0, a1, a2, a3, a4);
+}
+LONG WINAPI Mine_RegSetValueExA(HKEY a0, LPCSTR a1, DWORD a2, DWORD a3, BYTE* a4, DWORD a5)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) {return ERROR_SUCCESS;}
+ return Real_RegSetValueExA(a0, a1, a2, a3, a4, a5);
+}
+LONG WINAPI Mine_RegSetValueExW(HKEY a0, LPCWSTR a1, DWORD a2, DWORD a3, BYTE* a4, DWORD a5)
+{
+ if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) {return ERROR_SUCCESS;}
+ return Real_RegSetValueExW(a0, a1, a2, a3, a4, a5);
+}
+
+//
+// CFilterMapper2
+//
+
+IFilterMapper2* CFilterMapper2::m_pFilterMapper2 = NULL;
+
+bool CFilterMapper2::fInitialized = false;
+
+void CFilterMapper2::Init()
+{
+ if(!fInitialized)
+ {
+ DetourFunctionWithTrampoline((PBYTE)Real_CoCreateInstance, (PBYTE)Mine_CoCreateInstance);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegCloseKey, (PBYTE)Mine_RegCloseKey);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegFlushKey, (PBYTE)Mine_RegFlushKey);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegCreateKeyA, (PBYTE)Mine_RegCreateKeyA);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegCreateKeyW, (PBYTE)Mine_RegCreateKeyW);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegCreateKeyExA, (PBYTE)Mine_RegCreateKeyExA);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegCreateKeyExW, (PBYTE)Mine_RegCreateKeyExW);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegDeleteKeyA, (PBYTE)Mine_RegDeleteKeyA);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegDeleteKeyW, (PBYTE)Mine_RegDeleteKeyW);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegDeleteValueA, (PBYTE)Mine_RegDeleteValueA);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegDeleteValueW, (PBYTE)Mine_RegDeleteValueW);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegEnumKeyExA, (PBYTE)Mine_RegEnumKeyExA);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegEnumKeyExW, (PBYTE)Mine_RegEnumKeyExW);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegEnumValueA, (PBYTE)Mine_RegEnumValueA);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegEnumValueW, (PBYTE)Mine_RegEnumValueW);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegOpenKeyA, (PBYTE)Mine_RegOpenKeyA);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegOpenKeyW, (PBYTE)Mine_RegOpenKeyW);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegOpenKeyExA, (PBYTE)Mine_RegOpenKeyExA);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegOpenKeyExW, (PBYTE)Mine_RegOpenKeyExW);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegQueryInfoKeyA, (PBYTE)Mine_RegQueryInfoKeyA);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegQueryInfoKeyW, (PBYTE)Mine_RegQueryInfoKeyW);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegQueryValueA, (PBYTE)Mine_RegQueryValueA);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegQueryValueW, (PBYTE)Mine_RegQueryValueW);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegQueryValueExA, (PBYTE)Mine_RegQueryValueExA);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegQueryValueExW, (PBYTE)Mine_RegQueryValueExW);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegSetValueA, (PBYTE)Mine_RegSetValueA);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegSetValueW, (PBYTE)Mine_RegSetValueW);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegSetValueExA, (PBYTE)Mine_RegSetValueExA);
+ DetourFunctionWithTrampoline((PBYTE)Real_RegSetValueExW, (PBYTE)Mine_RegSetValueExW);
+
+ fInitialized = true;
+ }
+}
+
+CFilterMapper2::CFilterMapper2(bool fRefCounted, bool fAllowUnreg, LPUNKNOWN pUnkOuter)
+ : CUnknown(NAME("CFilterMapper2"), pUnkOuter)
+ , m_fRefCounted(fRefCounted), m_fAllowUnreg(fAllowUnreg)
+{
+ m_cRef = fRefCounted ? 0 : 1;
+
+ Init();
+
+ HRESULT hr = Real_CoCreateInstance(
+ CLSID_FilterMapper2, (IUnknown*)(INonDelegatingUnknown*)this, CLSCTX_ALL,
+ __uuidof(IUnknown), (void**)&m_pFM2);
+ if(FAILED(hr) || !m_pFM2)
+ {
+ ASSERT(0);
+ return;
+ }
+}
+
+CFilterMapper2::~CFilterMapper2()
+{
+ POSITION pos = m_filters.GetHeadPosition();
+ while(pos) delete m_filters.GetNext(pos);
+}
+
+STDMETHODIMP CFilterMapper2::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ if(riid == __uuidof(IFilterMapper2))
+ return GetInterface((IFilterMapper2*)this, ppv);
+
+ HRESULT hr = m_pFM2 ? m_pFM2->QueryInterface(riid, ppv) : E_NOINTERFACE;
+
+ return
+ SUCCEEDED(hr) ? hr :
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+void CFilterMapper2::Register(CString path)
+{
+ if(HMODULE h = LoadLibrary(path))
+ {
+ typedef HRESULT (__stdcall * PDllRegisterServer)();
+ if(PDllRegisterServer p = (PDllRegisterServer)GetProcAddress(h, "DllRegisterServer"))
+ {
+ ASSERT(CFilterMapper2::m_pFilterMapper2 == NULL);
+
+ CFilterMapper2::m_pFilterMapper2 = this;
+ m_path = path;
+ p();
+ m_path.Empty();
+ CFilterMapper2::m_pFilterMapper2 = NULL;
+ }
+
+ FreeLibrary(h);
+ }
+}
+
+// IFilterMapper2
+
+STDMETHODIMP CFilterMapper2::CreateCategory(REFCLSID clsidCategory, DWORD dwCategoryMerit, LPCWSTR Description)
+{
+ if(!m_path.IsEmpty())
+ {
+ return S_OK;
+ }
+ else if(CComQIPtr<IFilterMapper2> pFM2 = m_pFM2)
+ {
+ return pFM2->CreateCategory(clsidCategory, dwCategoryMerit, Description);
+ }
+
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CFilterMapper2::UnregisterFilter(const CLSID* pclsidCategory, const OLECHAR* szInstance, REFCLSID Filter)
+{
+ if(!m_path.IsEmpty())
+ {
+ return S_OK;
+ }
+ else if(CComQIPtr<IFilterMapper2> pFM2 = m_pFM2)
+ {
+ return m_fAllowUnreg
+ ? pFM2->UnregisterFilter(pclsidCategory, szInstance, Filter)
+ : S_OK;
+ }
+
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CFilterMapper2::RegisterFilter(REFCLSID clsidFilter, LPCWSTR Name, IMoniker** ppMoniker, const CLSID* pclsidCategory, const OLECHAR* szInstance, const REGFILTER2* prf2)
+{
+ if(!m_path.IsEmpty())
+ {
+ if(FilterOverride* f = new FilterOverride)
+ {
+ f->fDisabled = false;
+ f->type = FilterOverride::EXTERNAL;
+ f->path = m_path;
+ f->name = CStringW(Name);
+ f->clsid = clsidFilter;
+ f->iLoadType = FilterOverride::MERIT;
+ f->dwMerit = prf2->dwMerit;
+
+ if(prf2->dwVersion == 1)
+ {
+ for(ULONG i = 0; i < prf2->cPins; i++)
+ {
+ const REGFILTERPINS& rgPin = prf2->rgPins[i];
+ if(rgPin.bOutput) continue;
+
+ for(UINT i = 0; i < rgPin.nMediaTypes; i++)
+ {
+ if(!rgPin.lpMediaType[i].clsMajorType || !rgPin.lpMediaType[i].clsMinorType) break;
+ f->guids.AddTail(*rgPin.lpMediaType[i].clsMajorType);
+ f->guids.AddTail(*rgPin.lpMediaType[i].clsMinorType);
+ }
+ }
+ }
+ else if(prf2->dwVersion == 2)
+ {
+ for(ULONG i = 0; i < prf2->cPins2; i++)
+ {
+ const REGFILTERPINS2& rgPin = prf2->rgPins2[i];
+ if(rgPin.dwFlags&REG_PINFLAG_B_OUTPUT) continue;
+
+ for(UINT i = 0; i < rgPin.nMediaTypes; i++)
+ {
+ if(!rgPin.lpMediaType[i].clsMajorType || !rgPin.lpMediaType[i].clsMinorType) break;
+ f->guids.AddTail(*rgPin.lpMediaType[i].clsMajorType);
+ f->guids.AddTail(*rgPin.lpMediaType[i].clsMinorType);
+ }
+ }
+ }
+
+ f->backup.AddTailList(&f->guids);
+
+ m_filters.AddTail(f);
+ }
+
+ return S_OK;
+ }
+ else if(CComQIPtr<IFilterMapper2> pFM2 = m_pFM2)
+ {
+ return pFM2->RegisterFilter(clsidFilter, Name, ppMoniker, pclsidCategory, szInstance, prf2);
+ }
+
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CFilterMapper2::EnumMatchingFilters(IEnumMoniker** ppEnum, DWORD dwFlags, BOOL bExactMatch, DWORD dwMerit,
+ BOOL bInputNeeded, DWORD cInputTypes, const GUID* pInputTypes, const REGPINMEDIUM* pMedIn, const CLSID* pPinCategoryIn, BOOL bRender,
+ BOOL bOutputNeeded, DWORD cOutputTypes, const GUID* pOutputTypes, const REGPINMEDIUM* pMedOut, const CLSID* pPinCategoryOut)
+{
+ if(CComQIPtr<IFilterMapper2> pFM2 = m_pFM2)
+ {
+ pFM2->EnumMatchingFilters(ppEnum, dwFlags, bExactMatch, dwMerit,
+ bInputNeeded, cInputTypes, pInputTypes, pMedIn, pPinCategoryIn, bRender,
+ bOutputNeeded, cOutputTypes, pOutputTypes, pMedOut, pPinCategoryOut);
+ }
+
+ return E_NOTIMPL;
+}
diff --git a/src/apps/mplayerc/FakeFilterMapper2.h b/src/apps/mplayerc/FakeFilterMapper2.h
new file mode 100644
index 000000000..88f071cb3
--- /dev/null
+++ b/src/apps/mplayerc/FakeFilterMapper2.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <atlbase.h>
+
+class FilterOverride
+{
+public:
+ bool fDisabled, fTemporary;
+ enum {REGISTERED, EXTERNAL} type;
+ // REGISTERED
+ CStringW dispname;
+ // EXTERNAL
+ CString path, name;
+ CLSID clsid;
+ // props
+ CAtlList<GUID> guids, backup;
+ enum {PREFERRED, BLOCK, MERIT};
+ int iLoadType;
+ DWORD dwMerit;
+
+ FilterOverride() {fTemporary = false;}
+ FilterOverride(FilterOverride* f)
+ {
+ fDisabled = f->fDisabled;
+ fTemporary = f->fTemporary;
+ type = f->type;
+ dispname = f->dispname;
+ path = f->path;
+ name = f->name;
+ clsid = f->clsid;
+ guids.AddTailList(&f->guids);
+ backup.AddTailList(&f->backup);
+ iLoadType = f->iLoadType;
+ dwMerit = f->dwMerit;
+ }
+};
+/*
+class CFilterMapper2 : protected CUnknown, protected IFilterMapper2
+{
+ static bool fInitialized;
+
+ CComPtr<IFilterMapper2> m_pFM2;
+ CString m_path;
+
+protected:
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ // IFilterMapper2
+
+ STDMETHODIMP CreateCategory(REFCLSID clsidCategory, DWORD dwCategoryMerit, LPCWSTR Description);
+ STDMETHODIMP UnregisterFilter(const CLSID* pclsidCategory, const OLECHAR* szInstance, REFCLSID Filter);
+ STDMETHODIMP RegisterFilter(REFCLSID clsidFilter, LPCWSTR Name, IMoniker** ppMoniker, const CLSID* pclsidCategory, const OLECHAR* szInstance, const REGFILTER2* prf2);
+ STDMETHODIMP EnumMatchingFilters(IEnumMoniker** ppEnum, DWORD dwFlags, BOOL bExactMatch, DWORD dwMerit,
+ BOOL bInputNeeded, DWORD cInputTypes, const GUID* pInputTypes, const REGPINMEDIUM* pMedIn, const CLSID* pPinCategoryIn, BOOL bRender,
+ BOOL bOutputNeeded, DWORD cOutputTypes, const GUID* pOutputTypes, const REGPINMEDIUM* pMedOut, const CLSID* pPinCategoryOut);
+
+public:
+ CFilterMapper2();
+ virtual ~CFilterMapper2();
+
+ static void Init();
+
+ static IFilterMapper2* m_pFilterMapper2;
+ CList<Filter*> m_filters;
+ void Register(CString path);
+};
+*/
+
+class CFilterMapper2 : protected CUnknown, public IFilterMapper2
+{
+ static bool fInitialized;
+
+ CComPtr<IUnknown> m_pFM2;
+ CString m_path;
+
+ bool m_fRefCounted, m_fAllowUnreg;
+
+protected:
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ // IFilterMapper2
+
+ STDMETHODIMP CreateCategory(REFCLSID clsidCategory, DWORD dwCategoryMerit, LPCWSTR Description);
+ STDMETHODIMP UnregisterFilter(const CLSID* pclsidCategory, const OLECHAR* szInstance, REFCLSID Filter);
+ STDMETHODIMP RegisterFilter(REFCLSID clsidFilter, LPCWSTR Name, IMoniker** ppMoniker, const CLSID* pclsidCategory, const OLECHAR* szInstance, const REGFILTER2* prf2);
+ STDMETHODIMP EnumMatchingFilters(IEnumMoniker** ppEnum, DWORD dwFlags, BOOL bExactMatch, DWORD dwMerit,
+ BOOL bInputNeeded, DWORD cInputTypes, const GUID* pInputTypes, const REGPINMEDIUM* pMedIn, const CLSID* pPinCategoryIn, BOOL bRender,
+ BOOL bOutputNeeded, DWORD cOutputTypes, const GUID* pOutputTypes, const REGPINMEDIUM* pMedOut, const CLSID* pPinCategoryOut);
+
+public:
+ CFilterMapper2(bool fRefCounted, bool fAllowUnreg = false, LPUNKNOWN pUnkOuter = NULL);
+ virtual ~CFilterMapper2();
+
+ void SetInner(IUnknown* pUnk) {m_pFM2 = pUnk;}
+
+ static void Init();
+
+ static IFilterMapper2* m_pFilterMapper2;
+ CList<FilterOverride*> m_filters;
+ void Register(CString path);
+};
diff --git a/src/apps/mplayerc/FavoriteAddDlg.cpp b/src/apps/mplayerc/FavoriteAddDlg.cpp
new file mode 100644
index 000000000..9ecee1fac
--- /dev/null
+++ b/src/apps/mplayerc/FavoriteAddDlg.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// FavoritAddDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "FavoriteAddDlg.h"
+
+
+// CFavoriteAddDlg dialog
+
+IMPLEMENT_DYNAMIC(CFavoriteAddDlg, CCmdUIDialog)
+CFavoriteAddDlg::CFavoriteAddDlg(CString shortname, CString fullname, CWnd* pParent /*=NULL*/)
+ : CCmdUIDialog(CFavoriteAddDlg::IDD, pParent)
+ , m_shortname(shortname)
+ , m_fullname(fullname)
+ , m_fRememberPos(TRUE)
+{
+}
+
+CFavoriteAddDlg::~CFavoriteAddDlg()
+{
+}
+
+void CFavoriteAddDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_COMBO1, m_namectrl);
+ DDX_CBString(pDX, IDC_COMBO1, m_name);
+ DDX_Check(pDX, IDC_CHECK1, m_fRememberPos);
+}
+
+BOOL CFavoriteAddDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ if(!m_shortname.IsEmpty()) m_namectrl.AddString(m_shortname);
+ if(!m_fullname.IsEmpty()) m_namectrl.AddString(m_fullname);
+ m_namectrl.SetCurSel(0);
+
+ ::CorrectComboListWidth(m_namectrl, GetFont());
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+
+BEGIN_MESSAGE_MAP(CFavoriteAddDlg, CCmdUIDialog)
+ ON_UPDATE_COMMAND_UI(IDOK, OnUpdateOk)
+END_MESSAGE_MAP()
+
+
+// CFavoriteAddDlg message handlers
+
+void CFavoriteAddDlg::OnUpdateOk(CCmdUI* pCmdUI)
+{
+ UpdateData();
+ pCmdUI->Enable(!m_name.IsEmpty());
+}
diff --git a/src/apps/mplayerc/FavoriteAddDlg.h b/src/apps/mplayerc/FavoriteAddDlg.h
new file mode 100644
index 000000000..20c1e953e
--- /dev/null
+++ b/src/apps/mplayerc/FavoriteAddDlg.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+// CFavoriteAddDlg dialog
+
+class CFavoriteAddDlg : public CCmdUIDialog
+{
+ DECLARE_DYNAMIC(CFavoriteAddDlg)
+
+private:
+ CString m_shortname, m_fullname;
+
+public:
+ CFavoriteAddDlg(CString shortname, CString fullname, CWnd* pParent = NULL); // standard constructor
+ virtual ~CFavoriteAddDlg();
+
+// Dialog Data
+ enum { IDD = IDD_FAVADD };
+
+ CComboBox m_namectrl;
+ CString m_name;
+ BOOL m_fRememberPos;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnUpdateOk(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/FavoriteOrganizeDlg.cpp b/src/apps/mplayerc/FavoriteOrganizeDlg.cpp
new file mode 100644
index 000000000..1d4b09a50
--- /dev/null
+++ b/src/apps/mplayerc/FavoriteOrganizeDlg.cpp
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// FavoriteOrganizeDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "FavoriteOrganizeDlg.h"
+
+
+// CFavoriteOrganizeDlg dialog
+
+//IMPLEMENT_DYNAMIC(CFavoriteOrganizeDlg, CResizableDialog)
+CFavoriteOrganizeDlg::CFavoriteOrganizeDlg(CWnd* pParent /*=NULL*/)
+ : CResizableDialog(CFavoriteOrganizeDlg::IDD, pParent)
+{
+}
+
+CFavoriteOrganizeDlg::~CFavoriteOrganizeDlg()
+{
+}
+
+void CFavoriteOrganizeDlg::SetupList(bool fSave)
+{
+ int i = m_tab.GetCurSel();
+
+ if(fSave)
+ {
+ CAtlList<CString> sl;
+
+ for(int j = 0; j < m_list.GetItemCount(); j++)
+ {
+ CString desc = m_list.GetItemText(j, 0);
+ desc.Remove(';');
+ CString str = m_sl[i].GetAt((POSITION)m_list.GetItemData(j));
+ sl.AddTail(desc + str.Mid(str.Find(';')));
+ }
+
+ m_sl[i].RemoveAll();
+ m_sl[i].AddTailList(&sl);
+ }
+ else
+ {
+ m_list.DeleteAllItems();
+
+ POSITION pos = m_sl[i].GetHeadPosition(), tmp;
+ while(pos)
+ {
+ tmp = pos;
+ CString s = m_sl[i].GetNext(pos);
+ int i = s.Find(';');
+ if(i >= 0) s = s.Left(i);
+ m_list.SetItemData(m_list.InsertItem(m_list.GetItemCount(), s), (DWORD_PTR)tmp);
+ }
+
+ m_list.SetRedraw(FALSE);
+
+ CRect r;
+ m_list.GetClientRect(r);
+ m_list.SetColumnWidth(0, -1);
+ m_list.SetColumnWidth(0, max(m_list.GetColumnWidth(0), r.Size().cx));
+
+ m_list.SetRedraw(TRUE);
+ }
+}
+
+void CFavoriteOrganizeDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_TAB1, m_tab);
+ DDX_Control(pDX, IDC_LIST2, m_list);
+}
+
+
+BEGIN_MESSAGE_MAP(CFavoriteOrganizeDlg, CResizableDialog)
+ ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnTcnSelchangeTab1)
+ ON_WM_DRAWITEM()
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+ ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
+ ON_BN_CLICKED(IDC_BUTTON3, OnBnClickedButton3)
+ ON_BN_CLICKED(IDC_BUTTON4, OnBnClickedButton7)
+ ON_NOTIFY(TCN_SELCHANGING, IDC_TAB1, OnTcnSelchangingTab1)
+ ON_BN_CLICKED(IDOK, OnBnClickedOk)
+ ON_WM_ACTIVATE()
+ ON_NOTIFY(LVN_ENDLABELEDIT, IDC_LIST2, OnLvnEndlabeleditList2)
+ ON_WM_SIZE()
+END_MESSAGE_MAP()
+
+
+// CFavoriteOrganizeDlg message handlers
+
+BOOL CFavoriteOrganizeDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ m_tab.InsertItem(0, ResStr(IDS_R_FAVFILES));
+ m_tab.InsertItem(1, ResStr(IDS_R_FAVDVDS));
+// m_tab.InsertItem(2, ResStr(IDS_R_FAVDEVICES));
+ m_tab.SetCurSel(0);
+
+ m_list.InsertColumn(0, _T(""));
+ m_list.SetExtendedStyle(m_list.GetExtendedStyle()|LVS_EX_FULLROWSELECT);
+
+ AfxGetAppSettings().GetFav(FAV_FILE, m_sl[0]);
+ AfxGetAppSettings().GetFav(FAV_DVD, m_sl[1]);
+ AfxGetAppSettings().GetFav(FAV_DEVICE, m_sl[2]);
+
+ SetupList(false);
+
+ AddAnchor(IDC_TAB1, TOP_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_LIST2, TOP_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_BUTTON1, TOP_RIGHT);
+ AddAnchor(IDC_BUTTON2, TOP_RIGHT);
+ AddAnchor(IDC_BUTTON3, TOP_RIGHT);
+ AddAnchor(IDC_BUTTON4, TOP_RIGHT);
+ AddAnchor(IDOK, BOTTOM_RIGHT);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CFavoriteOrganizeDlg::OnTcnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ SetupList(false);
+
+ m_list.SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+
+ *pResult = 0;
+}
+
+void CFavoriteOrganizeDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
+{
+ if(nIDCtl != IDC_LIST2) return;
+
+ int nItem = lpDrawItemStruct->itemID;
+ CRect rcItem = lpDrawItemStruct->rcItem;
+
+ CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
+
+ if(!!m_list.GetItemState(nItem, LVIS_SELECTED))
+ {
+ FillRect(pDC->m_hDC, rcItem, CBrush(0xf1dacc));
+ FrameRect(pDC->m_hDC, rcItem, CBrush(0xc56a31));
+ }
+ else
+ {
+ CBrush b;
+ b.CreateSysColorBrush(COLOR_WINDOW);
+ FillRect(pDC->m_hDC, rcItem, b);
+ }
+
+ CString str = m_list.GetItemText(nItem, 0);
+
+ pDC->SetTextColor(0);
+ pDC->TextOut(rcItem.left+3, (rcItem.top+rcItem.bottom - pDC->GetTextExtent(str).cy)/2, str);
+}
+
+void CFavoriteOrganizeDlg::OnBnClickedButton1()
+{
+ if(POSITION pos = m_list.GetFirstSelectedItemPosition())
+ {
+ m_list.SetFocus();
+ m_list.EditLabel(m_list.GetNextSelectedItem(pos));
+ }
+}
+
+void CFavoriteOrganizeDlg::OnLvnEndlabeleditList2(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ NMLVDISPINFO* pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
+ if(pDispInfo->item.iItem >= 0 && pDispInfo->item.pszText)
+ m_list.SetItemText(pDispInfo->item.iItem, 0, pDispInfo->item.pszText);
+ *pResult = 0;
+}
+
+void CFavoriteOrganizeDlg::OnBnClickedButton2()
+{
+ if(POSITION pos = m_list.GetFirstSelectedItemPosition())
+ {
+ int nItem = m_list.GetNextSelectedItem(pos);
+ if(nItem < 0 || nItem >= m_list.GetItemCount()) return;
+
+ m_list.DeleteItem(nItem);
+
+ nItem = min(nItem, m_list.GetItemCount()-1);
+
+ m_list.SetSelectionMark(nItem);
+ m_list.SetItemState(nItem, LVIS_SELECTED, LVIS_SELECTED);
+ }
+}
+
+void CFavoriteOrganizeDlg::OnBnClickedButton3()
+{
+ if(POSITION pos = m_list.GetFirstSelectedItemPosition())
+ {
+ int nItem = m_list.GetNextSelectedItem(pos);
+ if(nItem <= 0) return;
+
+ DWORD_PTR data = m_list.GetItemData(nItem);
+ CString str = m_list.GetItemText(nItem, 0);
+
+ m_list.DeleteItem(nItem);
+
+ nItem--;
+
+ m_list.InsertItem(nItem, str);
+ m_list.SetItemData(nItem, data);
+ m_list.SetSelectionMark(nItem);
+ m_list.SetItemState(nItem, LVIS_SELECTED, LVIS_SELECTED);
+ }
+}
+
+void CFavoriteOrganizeDlg::OnBnClickedButton7()
+{
+ if(POSITION pos = m_list.GetFirstSelectedItemPosition())
+ {
+ int nItem = m_list.GetNextSelectedItem(pos);
+ if(nItem < 0 || nItem >= m_list.GetItemCount()-1) return;
+
+ DWORD_PTR data = m_list.GetItemData(nItem);
+ CString str = m_list.GetItemText(nItem, 0);
+
+ m_list.DeleteItem(nItem);
+
+ nItem++;
+
+ m_list.InsertItem(nItem, str);
+ m_list.SetItemData(nItem, data);
+ m_list.SetSelectionMark(nItem);
+ m_list.SetItemState(nItem, LVIS_SELECTED, LVIS_SELECTED);
+ }
+}
+
+void CFavoriteOrganizeDlg::OnTcnSelchangingTab1(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ SetupList(true);
+
+ *pResult = 0;
+}
+
+void CFavoriteOrganizeDlg::OnBnClickedOk()
+{
+ SetupList(true);
+
+ AfxGetAppSettings().SetFav(FAV_FILE, m_sl[0]);
+ AfxGetAppSettings().SetFav(FAV_DVD, m_sl[1]);
+ AfxGetAppSettings().SetFav(FAV_DEVICE, m_sl[2]);
+
+ OnOK();
+}
+
+void CFavoriteOrganizeDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
+{
+ __super::OnActivate(nState, pWndOther, bMinimized);
+
+ if(nState == WA_ACTIVE)
+ m_list.SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+}
+
+void CFavoriteOrganizeDlg::OnSize(UINT nType, int cx, int cy)
+{
+ __super::OnSize(nType, cx, cy);
+
+ if(IsWindow(m_list))
+ m_list.SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER);
+}
diff --git a/src/apps/mplayerc/FavoriteOrganizeDlg.h b/src/apps/mplayerc/FavoriteOrganizeDlg.h
new file mode 100644
index 000000000..59c1be17f
--- /dev/null
+++ b/src/apps/mplayerc/FavoriteOrganizeDlg.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "afxcmn.h"
+#include "afxwin.h"
+#include "..\..\ui\ResizableLib\ResizableDialog.h"
+
+
+// CFavoriteOrganizeDlg dialog
+
+class CFavoriteOrganizeDlg : public CResizableDialog
+{
+// DECLARE_DYNAMIC(CFavoriteOrganizeDlg)
+
+private:
+ CAtlList<CString> m_sl[3];
+ void SetupList(bool fSave);
+
+public:
+ CFavoriteOrganizeDlg(CWnd* pParent = NULL); // standard constructor
+ virtual ~CFavoriteOrganizeDlg();
+
+// Dialog Data
+ enum { IDD = IDD_FAVORGANIZE };
+
+ CTabCtrl m_tab;
+ CListCtrl m_list;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+
+ DECLARE_MESSAGE_MAP()
+public:
+ afx_msg void OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnBnClickedButton2();
+ afx_msg void OnBnClickedButton3();
+ afx_msg void OnBnClickedButton7();
+ afx_msg void OnTcnSelchangingTab1(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnBnClickedOk();
+ afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
+ afx_msg void OnLvnEndlabeleditList2(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+};
diff --git a/src/apps/mplayerc/FileDropTarget.cpp b/src/apps/mplayerc/FileDropTarget.cpp
new file mode 100644
index 000000000..4243d82eb
--- /dev/null
+++ b/src/apps/mplayerc/FileDropTarget.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// FileDropTarget.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "FileDropTarget.h"
+
+
+// CFileDropTarget
+
+//IMPLEMENT_DYNAMIC(CFileDropTarget, COleDropTarget)
+CFileDropTarget::CFileDropTarget(CDropTarget* pDropTarget)
+ : m_pDropTarget(pDropTarget)
+{
+ ASSERT(m_pDropTarget);
+}
+
+CFileDropTarget::~CFileDropTarget()
+{
+}
+
+DROPEFFECT CFileDropTarget::OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
+{
+ return m_pDropTarget ? m_pDropTarget->OnDragEnter(pDataObject, dwKeyState, point) : DROPEFFECT_NONE;
+}
+
+DROPEFFECT CFileDropTarget::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
+{
+ return m_pDropTarget ? m_pDropTarget->OnDragOver(pDataObject, dwKeyState, point) : DROPEFFECT_NONE;
+}
+
+BOOL CFileDropTarget::OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
+{
+ return m_pDropTarget ? m_pDropTarget->OnDrop(pDataObject, dropEffect, point) : DROPEFFECT_NONE;
+}
+
+DROPEFFECT CFileDropTarget::OnDropEx(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point)
+{
+ return m_pDropTarget ? m_pDropTarget->OnDropEx(pDataObject, dropDefault, dropList, point) : DROPEFFECT_NONE;
+}
+
+void CFileDropTarget::OnDragLeave(CWnd* pWnd)
+{
+ if(m_pDropTarget) m_pDropTarget->OnDragLeave();
+}
+
+DROPEFFECT CFileDropTarget::OnDragScroll(CWnd* pWnd, DWORD dwKeyState, CPoint point)
+{
+ return m_pDropTarget ? m_pDropTarget->OnDragScroll(dwKeyState, point) : DROPEFFECT_NONE;
+}
+
+BEGIN_MESSAGE_MAP(CFileDropTarget, COleDropTarget)
+END_MESSAGE_MAP()
+
+
+
+// CFileDropTarget message handlers
diff --git a/src/apps/mplayerc/FileDropTarget.h b/src/apps/mplayerc/FileDropTarget.h
new file mode 100644
index 000000000..79db45449
--- /dev/null
+++ b/src/apps/mplayerc/FileDropTarget.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <afxole.h>
+
+class CDropTarget
+{
+public:
+ CDropTarget() {}
+
+ virtual DROPEFFECT OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) {return DROPEFFECT_NONE;}
+ virtual DROPEFFECT OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) {return DROPEFFECT_NONE;}
+ virtual BOOL OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point) {return FALSE;}
+ virtual DROPEFFECT OnDropEx(COleDataObject* pDataObject, DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point) {return (DROPEFFECT)-1;}
+ virtual void OnDragLeave() {}
+ virtual DROPEFFECT OnDragScroll(DWORD dwKeyState, CPoint point) {return DROPEFFECT_NONE;}
+};
+
+// CFileDropTarget command target
+
+class CFileDropTarget : public COleDropTarget
+{
+// DECLARE_DYNAMIC(CFileDropTarget)
+
+private:
+ CDropTarget* m_pDropTarget;
+
+public:
+ CFileDropTarget(CDropTarget* pDropTarget);
+ virtual ~CFileDropTarget();
+
+protected:
+ DECLARE_MESSAGE_MAP()
+
+ DROPEFFECT OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
+ DROPEFFECT OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
+ BOOL OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point);
+ DROPEFFECT OnDropEx(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point);
+ void OnDragLeave(CWnd* pWnd);
+ DROPEFFECT OnDragScroll(CWnd* pWnd, DWORD dwKeyState, CPoint point);
+};
+
+
diff --git a/src/apps/mplayerc/FloatEdit.cpp b/src/apps/mplayerc/FloatEdit.cpp
new file mode 100644
index 000000000..f437d89ea
--- /dev/null
+++ b/src/apps/mplayerc/FloatEdit.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "floatedit.h"
+
+// CFloatEdit
+
+IMPLEMENT_DYNAMIC(CFloatEdit, CEdit)
+
+bool CFloatEdit::GetFloat(float& f)
+{
+ CString s;
+ GetWindowText(s);
+ return(_stscanf(s, _T("%f"), &f) == 1);
+}
+
+double CFloatEdit::operator = (double d)
+{
+ CString s;
+ s.Format(_T("%.4f"), d);
+ SetWindowText(s);
+ return(d);
+}
+
+CFloatEdit::operator double()
+{
+ CString s;
+ GetWindowText(s);
+ float f;
+ return(_stscanf(s, _T("%f"), &f) == 1 ? f : 0);
+}
+
+BEGIN_MESSAGE_MAP(CFloatEdit, CEdit)
+ ON_WM_CHAR()
+END_MESSAGE_MAP()
+
+void CFloatEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ if(!(nChar >= '0' && nChar <= '9' || nChar == '.' || nChar == '\b'))
+ return;
+
+ CString str;
+ GetWindowText(str);
+
+ if(nChar == '.' && (str.Find('.') >= 0 || str.IsEmpty()))
+ return;
+
+ int nStartChar, nEndChar;
+ GetSel(nStartChar, nEndChar);
+
+ if(nChar == '\b' && nStartChar <= 0)
+ return;
+
+ CEdit::OnChar(nChar, nRepCnt, nFlags);
+}
+
+// CIntEdit
+
+IMPLEMENT_DYNAMIC(CIntEdit, CEdit)
+
+BEGIN_MESSAGE_MAP(CIntEdit, CEdit)
+ ON_WM_CHAR()
+END_MESSAGE_MAP()
+
+void CIntEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ if(!(nChar >= '0' && nChar <= '9' || nChar == '-' || nChar == '\b'))
+ return;
+
+ CString str;
+ GetWindowText(str);
+
+ if(nChar == '-' && !str.IsEmpty() && str[0] == '-')
+ return;
+
+ int nStartChar, nEndChar;
+ GetSel(nStartChar, nEndChar);
+
+ if(nChar == '\b' && nStartChar <= 0)
+ return;
+
+ if(nChar == '-' && (nStartChar != 0 || nEndChar != 0))
+ return;
+
+ CEdit::OnChar(nChar, nRepCnt, nFlags);
+}
+
+// CHexEdit
+
+IMPLEMENT_DYNAMIC(CHexEdit, CEdit)
+
+bool CHexEdit::GetDWORD(DWORD& dw)
+{
+ CString s;
+ GetWindowText(s);
+ return(_stscanf(s, _T("%x"), &dw) == 1);
+}
+
+DWORD CHexEdit::operator = (DWORD dw)
+{
+ CString s;
+ s.Format(_T("%08x"), dw);
+ SetWindowText(s);
+ return(dw);
+}
+
+CHexEdit::operator DWORD()
+{
+ CString s;
+ GetWindowText(s);
+ DWORD dw;
+ return(_stscanf(s, _T("%x"), &dw) == 1 ? dw : 0);
+}
+
+BEGIN_MESSAGE_MAP(CHexEdit, CEdit)
+ ON_WM_CHAR()
+END_MESSAGE_MAP()
+
+void CHexEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ if(!(nChar >= 'A' && nChar <= 'F' || nChar >= 'a' && nChar <= 'f'
+ || nChar >= '0' && nChar <= '9' || nChar == '\b'))
+ return;
+
+ CString str;
+ GetWindowText(str);
+
+ int nStartChar, nEndChar;
+ GetSel(nStartChar, nEndChar);
+
+ if(nChar == '\b' && nStartChar <= 0)
+ return;
+
+ if(nChar != '\b' && nEndChar - nStartChar == 0 && str.GetLength() >= 8)
+ return;
+
+ CEdit::OnChar(nChar, nRepCnt, nFlags);
+}
diff --git a/src/apps/mplayerc/FloatEdit.h b/src/apps/mplayerc/FloatEdit.h
new file mode 100644
index 000000000..8abb97582
--- /dev/null
+++ b/src/apps/mplayerc/FloatEdit.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+// CFloatEdit
+
+class CFloatEdit : public CEdit
+{
+public:
+ bool GetFloat(float& f);
+ double operator = (double d);
+ operator double();
+
+ DECLARE_DYNAMIC(CFloatEdit)
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
+};
+
+// CIntEdit
+
+class CIntEdit : public CEdit
+{
+public:
+ DECLARE_DYNAMIC(CIntEdit)
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
+};
+
+// CHexEdit
+
+class CHexEdit : public CEdit
+{
+public:
+ bool GetDWORD(DWORD& dw);
+ DWORD operator = (DWORD dw);
+ operator DWORD();
+
+ DECLARE_DYNAMIC(CHexEdit)
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
+};
diff --git a/src/apps/mplayerc/FullscreenWnd.cpp b/src/apps/mplayerc/FullscreenWnd.cpp
new file mode 100644
index 000000000..bf76a4a84
--- /dev/null
+++ b/src/apps/mplayerc/FullscreenWnd.cpp
@@ -0,0 +1,103 @@
+// FullscreenWnd.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "FullscreenWnd.h"
+#include "MainFrm.h"
+#include ".\fullscreenwnd.h"
+
+
+// CFullscreenWnd
+
+IMPLEMENT_DYNAMIC(CFullscreenWnd, CWnd)
+CFullscreenWnd::CFullscreenWnd(CMainFrame* pMainFrame)
+{
+ m_pMainFrame = pMainFrame;
+ m_hCursor = ::LoadCursor(NULL, IDC_HAND);
+ m_bCursorVisible = false;
+}
+
+CFullscreenWnd::~CFullscreenWnd()
+{
+}
+
+
+BEGIN_MESSAGE_MAP(CFullscreenWnd, CWnd)
+ ON_WM_ERASEBKGND()
+ ON_WM_SETCURSOR()
+END_MESSAGE_MAP()
+
+
+
+BOOL CFullscreenWnd::PreTranslateMessage(MSG* pMsg)
+{
+ switch (pMsg->message)
+ {
+ case WM_MOUSEMOVE :
+ case WM_SYSKEYDOWN :
+ case WM_SYSKEYUP :
+ case WM_SYSCHAR :
+ case WM_SYSCOMMAND :
+
+ case WM_KEYDOWN :
+ case WM_KEYUP :
+ case WM_CHAR :
+
+ case WM_LBUTTONDOWN :
+ case WM_LBUTTONUP :
+ case WM_LBUTTONDBLCLK :
+ case WM_MBUTTONDOWN :
+ case WM_MBUTTONUP :
+ case WM_MBUTTONDBLCLK :
+ case WM_RBUTTONDOWN :
+ case WM_RBUTTONUP :
+ case WM_RBUTTONDBLCLK :
+
+ case WM_MOUSEWHEEL :
+
+ m_pMainFrame->PostMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
+ break;
+ }
+
+ return CWnd::PreTranslateMessage(pMsg);
+}
+
+
+BOOL CFullscreenWnd::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if(!CWnd::PreCreateWindow(cs))
+ return FALSE;
+
+ cs.style &= ~WS_BORDER;
+ cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, m_hCursor, HBRUSH(COLOR_WINDOW+1), NULL);
+
+ return TRUE;
+}
+
+// CFullscreenWnd message handlers
+
+
+BOOL CFullscreenWnd::OnEraseBkgnd(CDC* pDC)
+{
+ return false;
+}
+
+BOOL CFullscreenWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
+{
+ if (m_bCursorVisible)
+ ::SetCursor(m_hCursor);
+ else
+ ::SetCursor(NULL);
+ return FALSE;
+}
+
+
+void CFullscreenWnd::ShowCursor(bool bVisible)
+{
+ if (m_bCursorVisible != bVisible)
+ {
+ m_bCursorVisible = bVisible;
+ PostMessage (WM_SETCURSOR,0,0);
+ }
+}
diff --git a/src/apps/mplayerc/FullscreenWnd.h b/src/apps/mplayerc/FullscreenWnd.h
new file mode 100644
index 000000000..462e7f4fd
--- /dev/null
+++ b/src/apps/mplayerc/FullscreenWnd.h
@@ -0,0 +1,32 @@
+#pragma once
+
+
+// CFullscreenWnd
+
+class CMainFrame;
+
+class CFullscreenWnd : public CWnd
+{
+ DECLARE_DYNAMIC(CFullscreenWnd)
+
+public:
+ CFullscreenWnd(CMainFrame* pMainFrame);
+ virtual ~CFullscreenWnd();
+
+ void ShowCursor(bool bVisible);
+
+protected:
+ DECLARE_MESSAGE_MAP()
+
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ CMainFrame* m_pMainFrame;
+ HCURSOR m_hCursor;
+ bool m_bCursorVisible;
+public:
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
+};
+
+
diff --git a/src/apps/mplayerc/GoToDlg.cpp b/src/apps/mplayerc/GoToDlg.cpp
new file mode 100644
index 000000000..aebe09d46
--- /dev/null
+++ b/src/apps/mplayerc/GoToDlg.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// GoToDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "GoToDlg.h"
+
+#include <atlrx.h>
+
+
+// CGoToDlg dialog
+
+IMPLEMENT_DYNAMIC(CGoToDlg, CDialog)
+CGoToDlg::CGoToDlg(int time, float fps, CWnd* pParent /*=NULL*/)
+ : CDialog(CGoToDlg::IDD, pParent)
+ , m_timestr(_T(""))
+ , m_framestr(_T(""))
+ , m_time(time)
+ , m_fps(fps)
+{
+ if(m_fps == 0)
+ {
+ CString str = AfxGetApp()->GetProfileString(ResStr(IDS_R_SETTINGS), _T("fps"), _T("0"));
+ if(_stscanf(str, _T("%f"), &m_fps) != 1) m_fps = 0;
+ }
+}
+
+CGoToDlg::~CGoToDlg()
+{
+}
+
+void CGoToDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ DDX_Text(pDX, IDC_EDIT1, m_timestr);
+ DDX_Text(pDX, IDC_EDIT2, m_framestr);
+ DDX_Control(pDX, IDC_EDIT1, m_timeedit);
+ DDX_Control(pDX, IDC_EDIT2, m_frameedit);
+}
+
+BOOL CGoToDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ if(m_time >= 0)
+ {
+ m_timestr.Format(_T("%02d:%02d:%02d.%03d"),
+ (m_time/(1000*60*60))%60, (m_time/(1000*60))%60, (m_time/1000)%60, m_time%1000);
+
+ if(m_fps > 0)
+ {
+ m_framestr.Format(_T("%d, %.3f"), (int)(m_fps*m_time/1000), m_fps);
+ }
+
+ UpdateData(FALSE);
+
+ switch(AfxGetApp()->GetProfileInt(ResStr(IDS_R_SETTINGS), _T("gotoluf"), 0))
+ {
+ default:
+ case 0: m_timeedit.SetFocus(); m_timeedit.SetSel(0, 0); break;
+ case 1: m_frameedit.SetFocus(); m_frameedit.SetSel(0, m_framestr.Find(',')); break;
+ }
+
+ }
+
+ return FALSE;
+
+// return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+
+BEGIN_MESSAGE_MAP(CGoToDlg, CDialog)
+ ON_BN_CLICKED(IDC_OK1, OnBnClickedOk1)
+ ON_BN_CLICKED(IDC_OK2, OnBnClickedOk2)
+END_MESSAGE_MAP()
+
+
+// CGoToDlg message handlers
+
+void CGoToDlg::OnBnClickedOk1()
+{
+ UpdateData();
+
+ int hh, mm, ss, ms;
+ hh = mm = ss = ms = 0;
+
+ CAtlRegExp<> re;
+
+ REParseError status = re.Parse(_T("{\\z}"), FALSE);
+ if(REPARSE_ERROR_OK == status)
+ {
+ CAtlREMatchContext<> mc;
+ const CAtlREMatchContext<>::RECHAR* s = m_timestr.GetBuffer();
+ const CAtlREMatchContext<>::RECHAR* e = NULL;
+ while(s && re.Match(s, &mc, &e))
+ {
+ const CAtlREMatchContext<>::RECHAR* szStart = 0;
+ const CAtlREMatchContext<>::RECHAR* szEnd = 0;
+ mc.GetMatch(0, &szStart, &szEnd);
+
+ if(hh != 0 || hh > 59 || mm > 59 || ss > 59)
+ {
+ AfxMessageBox(_T("Error parsing entered time!"));
+ return;
+ }
+
+ hh = mm;
+ mm = ss;
+ ss = ms;
+ ms = _tcstol(szStart, (TCHAR**)&szStart, 10);
+
+ s = e;
+ }
+
+ m_time = ((hh*60+mm)*60+ss)*1000+ms;
+
+ AfxGetApp()->WriteProfileInt(ResStr(IDS_R_SETTINGS), _T("gotoluf"), 0);
+
+ OnOK();
+ }
+}
+
+
+void CGoToDlg::OnBnClickedOk2()
+{
+ UpdateData();
+
+ int frame = 0;
+ float fps = 0;
+
+ CAtlRegExp<> re;
+
+ REParseError status = re.Parse(_T("{\\z}[^0-9\\.]+{[0-9\\.]+}"), FALSE);
+ if(REPARSE_ERROR_OK == status)
+ {
+ CAtlREMatchContext<> mc;
+ const CAtlREMatchContext<>::RECHAR* s = m_framestr.GetBuffer();
+ const CAtlREMatchContext<>::RECHAR* e = NULL;
+ if(re.Match(s, &mc, &e))
+ {
+ const CAtlREMatchContext<>::RECHAR* szStart = 0;
+ const CAtlREMatchContext<>::RECHAR* szEnd = 0;
+
+ mc.GetMatch(0, &szStart, &szEnd);
+ frame = _tcstol(szStart, (TCHAR**)&szStart, 10);
+
+ mc.GetMatch(1, &szStart, &szEnd);
+ if(_stscanf(szStart, _T("%f"), &fps) != 1) fps = 0;
+ else AfxGetApp()->WriteProfileString(ResStr(IDS_R_SETTINGS), _T("fps"), szStart);
+ }
+ else
+ {
+ AfxMessageBox(_T("Error parsing entered text!"));
+ return;
+ }
+
+ if(fps == 0)
+ {
+ AfxMessageBox(_T("Error parsing entered frame-rate!"));
+ return;
+ }
+
+ m_time = (int)(1000.0*frame/fps) + 1;
+
+ AfxGetApp()->WriteProfileInt(ResStr(IDS_R_SETTINGS), _T("gotoluf"), 1);
+
+ OnOK();
+ }
+}
+
+BOOL CGoToDlg::PreTranslateMessage(MSG* pMsg)
+{
+ if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
+ {
+ if(*GetFocus() == m_timeedit) OnBnClickedOk1();
+ else if(*GetFocus() == m_frameedit) OnBnClickedOk2();
+
+ return TRUE;
+ }
+
+ return __super::PreTranslateMessage(pMsg);
+}
diff --git a/src/apps/mplayerc/GoToDlg.h b/src/apps/mplayerc/GoToDlg.h
new file mode 100644
index 000000000..c0a653344
--- /dev/null
+++ b/src/apps/mplayerc/GoToDlg.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "afxwin.h"
+
+// CGoToDlg dialog
+
+class CGoToDlg : public CDialog
+{
+ DECLARE_DYNAMIC(CGoToDlg)
+
+public:
+ CGoToDlg(int time = -1, float fps = 0, CWnd* pParent = NULL); // standard constructor
+ virtual ~CGoToDlg();
+
+ CString m_timestr;
+ CString m_framestr;
+ CEdit m_timeedit;
+ CEdit m_frameedit;
+
+ int m_time;
+ float m_fps;
+
+// Dialog Data
+ enum { IDD = IDD_GOTO_DLG };
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnBnClickedOk1();
+ afx_msg void OnBnClickedOk2();
+};
diff --git a/src/apps/mplayerc/History.txt b/src/apps/mplayerc/History.txt
new file mode 100644
index 000000000..3dc5b3964
--- /dev/null
+++ b/src/apps/mplayerc/History.txt
@@ -0,0 +1,38 @@
+=== v1.0.5.0 - //2006
+- Correction bug le curseur souris n'était pas caché en lisant des fichiers
+- Correction bug le fait de cliquer sur le slider de l'OSD effectuait égalemetn l'action "play/pause"
+
+=== v1.0.4.0 - 09/05/2006
+- Complément de l'OSD
+ * temp restant / temps total sur l'OSD (Ctrl+I, ou bien "Remaining_Time" pour WinLIRC)
+ * affiche la vitesse accélérée avant et arrière
+- Correction bug d'affichage de la barre de tâche qui perturbait le mode D3D fullscreen
+- Modification de la gestion du fast forward / rewind pour les DVD : plus de vitesse avant lente, et suppression des vitesses maximale avant et arrière (désormais fonction des possibilités du décodeur utilisé).
+- Cache le curseur souris après quelques secondes en mode D3D fullscreen
+
+
+=== v1.0.3.0 - 02/05/2006
+- Correction d'un bug sur l'aspect ratio non respecté en fullscreen D3D
+- Ajout du mode Mixer YUV pour le VMR9 et d'une partie des fonctionnalités de la version 6.4.9.0 officielle (les build-in filter ne sont pas a jour)
+- Première version de l'OSD pour le VMR9, avec pour l'instant le slider et l'affichage du choix des langues et sous-titres pour les DVD
+- La fonction "DVD Menu Activate" active la lecture de la vidéo si l'on est pas dans le menu (pratique une utilisation avec télécommande via WinLirc)
+
+
+=== v1.0.2.0 - 23/04/2006
+- Amélioration du mode Fullscreen Direct 3D avec le VMR9
+- Correction bugs sur le réglage des couleur du VMR9. Ces réglages fonctionnent maintenant en Renderless et en Windowless.
+
+
+=== v1.0.1.0 - 09/04/2006
+- Amélioration de l'ouverture d'un DVD (boîte de dialogue pour choisir le répertoire source)
+- Possibilité de sauvegarder de la position de lecture pour les 5 derniers DVD et les 5 derniers fichier lus (reprend la lecture a cet endroit au lancement). Options a cocher dans les options "Casimir".
+- Ajout d'un raccourcit clavier pour activer ou desactiver rapidement les Pixels Shaders (Ctrl+P)
+- Si l'option "remember window size" est activée, passe MPC en fullscreen au lancement le cas échéant
+- Le fullscreen sur l'écran secondaire est remplacé par l'option "Direct3D Fullscreen" qui permet de supprimer le tearing. Attention cette fonction est beta pour le moment!
+
+
+==== v1.0.0.0 - 29/03/2006
+- Option pour avoir la vidéo systématiquement en full screen sur l'écran secondaire mais en conservant les contrôles sur le principal
+- Réglage contraste / luminosité / hue / saturation pour le VMR renderless en "mixer mode"
+- Rechargement des Pixels Shaders au lancement
+- Fonction de "Tearing test" fonctionnant en VRM9 renderless (Ctrl+T) \ No newline at end of file
diff --git a/src/apps/mplayerc/IGraphBuilder2.h b/src/apps/mplayerc/IGraphBuilder2.h
new file mode 100644
index 000000000..5da815ef2
--- /dev/null
+++ b/src/apps/mplayerc/IGraphBuilder2.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+[uuid("165BE9D6-0929-4363-9BA3-580D735AA0F6")]
+interface IGraphBuilder2 : public IFilterGraph2
+{
+ STDMETHOD(IsPinDirection) (IPin* pPin, PIN_DIRECTION dir) = 0;
+ STDMETHOD(IsPinConnected) (IPin* pPin) = 0;
+ STDMETHOD(ConnectFilter) (IBaseFilter* pBF, IPin* pPinIn) = 0;
+ STDMETHOD(ConnectFilter) (IPin* pPinOut, IBaseFilter* pBF) = 0;
+ STDMETHOD(ConnectFilterDirect) (IPin* pPinOut, IBaseFilter* pBF, const AM_MEDIA_TYPE* pmt) = 0;
+ STDMETHOD(NukeDownstream) (IUnknown* pUnk) = 0;
+ STDMETHOD(FindInterface) (REFIID iid, void** ppv, BOOL bRemove) = 0;
+ STDMETHOD(AddToROT) () = 0;
+ STDMETHOD(RemoveFromROT) () = 0;
+};
+
+// private use only
+[uuid("43CDA93D-6A4E-4A07-BD3E-49D161073EE7")]
+interface IGraphBuilderDeadEnd : public IUnknown
+{
+ STDMETHOD_(size_t, GetCount)() = 0;
+ STDMETHOD(GetDeadEnd) (int iIndex, CAtlList<CStringW>& path, CAtlList<CMediaType>& mts) = 0;
+}; \ No newline at end of file
diff --git a/src/apps/mplayerc/IPinHook.cpp b/src/apps/mplayerc/IPinHook.cpp
new file mode 100644
index 000000000..9721c0d2c
--- /dev/null
+++ b/src/apps/mplayerc/IPinHook.cpp
@@ -0,0 +1,475 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "IPinHook.h"
+
+REFERENCE_TIME g_tSegmentStart = 0;
+REFERENCE_TIME g_tSampleStart = 0;
+
+static HRESULT (STDMETHODCALLTYPE * NewSegmentOrg)(IPinC * This, /* [in] */ REFERENCE_TIME tStart, /* [in] */ REFERENCE_TIME tStop, /* [in] */ double dRate) = NULL;
+
+static HRESULT STDMETHODCALLTYPE NewSegmentMine(IPinC * This, /* [in] */ REFERENCE_TIME tStart, /* [in] */ REFERENCE_TIME tStop, /* [in] */ double dRate)
+{
+ g_tSegmentStart = tStart;
+ return NewSegmentOrg(This, tStart, tStop, dRate);
+}
+
+static HRESULT ( STDMETHODCALLTYPE *ReceiveOrg )( IMemInputPinC * This, IMediaSample *pSample) = NULL;
+
+static HRESULT STDMETHODCALLTYPE ReceiveMine(IMemInputPinC * This, IMediaSample *pSample)
+{
+ REFERENCE_TIME rtStart, rtStop;
+ if(pSample && SUCCEEDED(pSample->GetTime(&rtStart, &rtStop)))
+ g_tSampleStart = rtStart;
+ return ReceiveOrg(This, pSample);
+}
+
+bool HookNewSegmentAndReceive(IPinC* pPinC, IMemInputPinC* pMemInputPinC)
+{
+ if(!pPinC || !pMemInputPinC || (GetVersion()&0x80000000))
+ return false;
+
+ g_tSegmentStart = 0;
+ g_tSampleStart = 0;
+
+ BOOL res;
+ DWORD flOldProtect = 0;
+
+ res = VirtualProtect(pPinC->lpVtbl, sizeof(IPinC), PAGE_WRITECOPY, &flOldProtect);
+ if(NewSegmentOrg == NULL) NewSegmentOrg = pPinC->lpVtbl->NewSegment;
+ pPinC->lpVtbl->NewSegment = NewSegmentMine;
+ res = VirtualProtect(pPinC->lpVtbl, sizeof(IPinC), PAGE_EXECUTE, &flOldProtect);
+
+ res = VirtualProtect(pMemInputPinC->lpVtbl, sizeof(IMemInputPinC), PAGE_WRITECOPY, &flOldProtect);
+ if(ReceiveOrg == NULL) ReceiveOrg = pMemInputPinC->lpVtbl->Receive;
+ pMemInputPinC->lpVtbl->Receive = ReceiveMine;
+ res = VirtualProtect(pMemInputPinC->lpVtbl, sizeof(IMemInputPinC), PAGE_EXECUTE, &flOldProtect);
+
+ return true;
+}
+
+static HRESULT ( STDMETHODCALLTYPE *GetVideoAcceleratorGUIDsOrg )( IAMVideoAcceleratorC * This,/* [out][in] */ LPDWORD pdwNumGuidsSupported,/* [out][in] */ LPGUID pGuidsSupported) = NULL;
+static HRESULT ( STDMETHODCALLTYPE *GetUncompFormatsSupportedOrg )( IAMVideoAcceleratorC * This,/* [in] */ const GUID *pGuid,/* [out][in] */ LPDWORD pdwNumFormatsSupported,/* [out][in] */ LPDDPIXELFORMAT pFormatsSupported) = NULL;
+static HRESULT ( STDMETHODCALLTYPE *GetInternalMemInfoOrg )( IAMVideoAcceleratorC * This,/* [in] */ const GUID *pGuid,/* [in] */ const AMVAUncompDataInfo *pamvaUncompDataInfo,/* [out][in] */ LPAMVAInternalMemInfo pamvaInternalMemInfo) = NULL;
+static HRESULT ( STDMETHODCALLTYPE *GetCompBufferInfoOrg )( IAMVideoAcceleratorC * This,/* [in] */ const GUID *pGuid,/* [in] */ const AMVAUncompDataInfo *pamvaUncompDataInfo,/* [out][in] */ LPDWORD pdwNumTypesCompBuffers,/* [out] */ LPAMVACompBufferInfo pamvaCompBufferInfo) = NULL;
+static HRESULT ( STDMETHODCALLTYPE *GetInternalCompBufferInfoOrg )( IAMVideoAcceleratorC * This,/* [out][in] */ LPDWORD pdwNumTypesCompBuffers,/* [out] */ LPAMVACompBufferInfo pamvaCompBufferInfo) = NULL;
+static HRESULT ( STDMETHODCALLTYPE *BeginFrameOrg )( IAMVideoAcceleratorC * This,/* [in] */ const AMVABeginFrameInfo *amvaBeginFrameInfo) = NULL;
+static HRESULT ( STDMETHODCALLTYPE *EndFrameOrg )( IAMVideoAcceleratorC * This,/* [in] */ const AMVAEndFrameInfo *pEndFrameInfo) = NULL;
+static HRESULT ( STDMETHODCALLTYPE *GetBufferOrg )( IAMVideoAcceleratorC * This,/* [in] */ DWORD dwTypeIndex,/* [in] */ DWORD dwBufferIndex,/* [in] */ BOOL bReadOnly,/* [out] */ LPVOID *ppBuffer,/* [out] */ LONG *lpStride) = NULL;
+static HRESULT ( STDMETHODCALLTYPE *ReleaseBufferOrg )( IAMVideoAcceleratorC * This,/* [in] */ DWORD dwTypeIndex,/* [in] */ DWORD dwBufferIndex) = NULL;
+static HRESULT ( STDMETHODCALLTYPE *ExecuteOrg )( IAMVideoAcceleratorC * This,/* [in] */ DWORD dwFunction,/* [in] */ LPVOID lpPrivateInputData,/* [in] */ DWORD cbPrivateInputData,/* [in] */ LPVOID lpPrivateOutputDat,/* [in] */ DWORD cbPrivateOutputData,/* [in] */ DWORD dwNumBuffers,/* [in] */ const AMVABUFFERINFO *pamvaBufferInfo) = NULL;
+static HRESULT ( STDMETHODCALLTYPE *QueryRenderStatusOrg )( IAMVideoAcceleratorC * This,/* [in] */ DWORD dwTypeIndex,/* [in] */ DWORD dwBufferIndex,/* [in] */ DWORD dwFlags) = NULL;
+static HRESULT ( STDMETHODCALLTYPE *DisplayFrameOrg )( IAMVideoAcceleratorC * This,/* [in] */ DWORD dwFlipToIndex,/* [in] */ IMediaSample *pMediaSample) = NULL;
+
+static void LOG(LPCTSTR fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ if(TCHAR* buff = new TCHAR[_vsctprintf(fmt, args) + 1])
+ {
+ _vstprintf(buff, fmt, args);
+ if(FILE* f = _tfopen(_T("c:\\dxva.log"), _T("at")))
+ {
+ fseek(f, 0, 2);
+ _ftprintf(f, _T("%s\n"), buff);
+ fclose(f);
+ }
+ delete [] buff;
+ }
+ va_end(args);
+}
+
+static void LOGPF(LPCTSTR prefix, const DDPIXELFORMAT* p, int n)
+{
+ for(int i = 0; i < n; i++)
+ {
+ LOG(_T("%s[%d].dwSize = %d"), prefix, i, p[i].dwSize);
+ LOG(_T("%s[%d].dwFlags = %08x"), prefix, i, p[i].dwFlags);
+ LOG(_T("%s[%d].dwFourCC = %4.4hs"), prefix, i, &p[i].dwFourCC);
+ LOG(_T("%s[%d].dwRGBBitCount = %08x"), prefix, i, &p[i].dwRGBBitCount);
+ LOG(_T("%s[%d].dwRBitMask = %08x"), prefix, i, &p[i].dwRBitMask);
+ LOG(_T("%s[%d].dwGBitMask = %08x"), prefix, i, &p[i].dwGBitMask);
+ LOG(_T("%s[%d].dwBBitMask = %08x"), prefix, i, &p[i].dwBBitMask);
+ LOG(_T("%s[%d].dwRGBAlphaBitMask = %08x"), prefix, i, &p[i].dwRGBAlphaBitMask);
+ }
+}
+
+static void LOGUDI(LPCTSTR prefix, const AMVAUncompDataInfo* p, int n)
+{
+ for(int i = 0; i < n; i++)
+ {
+ LOG(_T("%s[%d].dwUncompWidth = %d"), prefix, i, p[i].dwUncompWidth);
+ LOG(_T("%s[%d].dwUncompHeight = %d"), prefix, i, p[i].dwUncompHeight);
+
+ CString prefix2;
+ prefix2.Format(_T("%s[%d]"), prefix, i);
+ LOGPF(prefix2, &p[i].ddUncompPixelFormat, 1);
+ }
+}
+
+static HRESULT STDMETHODCALLTYPE GetVideoAcceleratorGUIDsMine(
+ IAMVideoAcceleratorC * This,
+ /* [out][in] */ LPDWORD pdwNumGuidsSupported,
+ /* [out][in] */ LPGUID pGuidsSupported)
+{
+ LOG(_T("\nGetVideoAcceleratorGUIDs"));
+
+ if(pdwNumGuidsSupported)
+ {
+ LOG(_T("[in] *pdwNumGuidsSupported = %d"), *pdwNumGuidsSupported);
+ }
+
+ HRESULT hr = GetVideoAcceleratorGUIDsOrg(This, pdwNumGuidsSupported, pGuidsSupported);
+
+ LOG(_T("hr = %08x"), hr);
+
+ if(pdwNumGuidsSupported)
+ {
+ LOG(_T("[out] *pdwNumGuidsSupported = %d"), *pdwNumGuidsSupported);
+
+ if(pGuidsSupported)
+ {
+ for(int i = 0; i < *pdwNumGuidsSupported; i++)
+ {
+ LOG(_T("[out] pGuidsSupported[%d] = %s"), i, CStringFromGUID(pGuidsSupported[i]));
+ }
+ }
+ }
+
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE GetUncompFormatsSupportedMine(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ const GUID *pGuid,
+ /* [out][in] */ LPDWORD pdwNumFormatsSupported,
+ /* [out][in] */ LPDDPIXELFORMAT pFormatsSupported)
+{
+ LOG(_T("\nGetUncompFormatsSupported"));
+
+ if(pGuid)
+ {
+ LOG(_T("[in] *pGuid = %s"), CStringFromGUID(*pGuid));
+ }
+
+ if(pdwNumFormatsSupported)
+ {
+ LOG(_T("[in] *pdwNumFormatsSupported = %d"), *pdwNumFormatsSupported);
+ }
+
+ HRESULT hr = GetUncompFormatsSupportedOrg(This, pGuid, pdwNumFormatsSupported, pFormatsSupported);
+
+ LOG(_T("hr = %08x"), hr);
+
+ if(pdwNumFormatsSupported)
+ {
+ LOG(_T("[out] *pdwNumFormatsSupported = %d"), *pdwNumFormatsSupported);
+
+ if(pFormatsSupported)
+ {
+ LOGPF(_T("[out] pFormatsSupported"), pFormatsSupported, *pdwNumFormatsSupported);
+ }
+ }
+
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE GetInternalMemInfoMine(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ const GUID *pGuid,
+ /* [in] */ const AMVAUncompDataInfo *pamvaUncompDataInfo,
+ /* [out][in] */ LPAMVAInternalMemInfo pamvaInternalMemInfo)
+{
+ LOG(_T("\nGetInternalMemInfo"));
+
+ HRESULT hr = GetInternalMemInfoOrg(This, pGuid, pamvaUncompDataInfo, pamvaInternalMemInfo);
+
+ LOG(_T("hr = %08x"), hr);
+
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE GetCompBufferInfoMine(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ const GUID *pGuid,
+ /* [in] */ const AMVAUncompDataInfo *pamvaUncompDataInfo,
+ /* [out][in] */ LPDWORD pdwNumTypesCompBuffers,
+ /* [out] */ LPAMVACompBufferInfo pamvaCompBufferInfo)
+{
+ LOG(_T("\nGetCompBufferInfo"));
+
+ if(pGuid)
+ {
+ LOG(_T("[in] *pGuid = %s"), CStringFromGUID(*pGuid));
+
+ if(pdwNumTypesCompBuffers)
+ {
+ LOG(_T("[in] *pdwNumTypesCompBuffers = %d"), *pdwNumTypesCompBuffers);
+ }
+ }
+
+ HRESULT hr = GetCompBufferInfoOrg(This, pGuid, pamvaUncompDataInfo, pdwNumTypesCompBuffers, pamvaCompBufferInfo);
+
+ LOG(_T("hr = %08x"), hr);
+
+ if(pdwNumTypesCompBuffers)
+ {
+ LOG(_T("[out] *pdwNumTypesCompBuffers = %d"), *pdwNumTypesCompBuffers);
+
+ if(pamvaUncompDataInfo)
+ {
+ LOGUDI(_T("[out] pamvaUncompDataInfo"), pamvaUncompDataInfo, *pdwNumTypesCompBuffers);
+ }
+ }
+
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE GetInternalCompBufferInfoMine(
+ IAMVideoAcceleratorC * This,
+ /* [out][in] */ LPDWORD pdwNumTypesCompBuffers,
+ /* [out] */ LPAMVACompBufferInfo pamvaCompBufferInfo)
+{
+ LOG(_T("\nGetInternalCompBufferInfo"));
+
+ HRESULT hr = GetInternalCompBufferInfoOrg(This, pdwNumTypesCompBuffers, pamvaCompBufferInfo);
+
+ LOG(_T("hr = %08x"), hr);
+
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE BeginFrameMine(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ const AMVABeginFrameInfo *amvaBeginFrameInfo)
+{
+ LOG(_T("\nBeginFrame"));
+
+ if(amvaBeginFrameInfo)
+ {
+ LOG(_T("[in] amvaBeginFrameInfo->dwDestSurfaceIndex = %08x"), amvaBeginFrameInfo->dwDestSurfaceIndex);
+ LOG(_T("[in] amvaBeginFrameInfo->pInputData = %08x"), amvaBeginFrameInfo->pInputData);
+ LOG(_T("[in] amvaBeginFrameInfo->dwSizeInputData = %08x"), amvaBeginFrameInfo->dwSizeInputData);
+ LOG(_T("[in] amvaBeginFrameInfo->pOutputData = %08x"), amvaBeginFrameInfo->pOutputData);
+ LOG(_T("[in] amvaBeginFrameInfo->dwSizeOutputData = %08x"), amvaBeginFrameInfo->dwSizeOutputData);
+ }
+
+ HRESULT hr = BeginFrameOrg(This, amvaBeginFrameInfo);
+
+ LOG(_T("hr = %08x"), hr);
+
+ if(amvaBeginFrameInfo && amvaBeginFrameInfo->pOutputData)
+ {
+ LOG(_T("[out] amvaBeginFrameInfo->pOutputData = %02x %02x %02x %02x..."),
+ ((BYTE*)amvaBeginFrameInfo->pOutputData)[0],
+ ((BYTE*)amvaBeginFrameInfo->pOutputData)[1],
+ ((BYTE*)amvaBeginFrameInfo->pOutputData)[2],
+ ((BYTE*)amvaBeginFrameInfo->pOutputData)[3]);
+ }
+
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE EndFrameMine(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ const AMVAEndFrameInfo *pEndFrameInfo)
+{
+ LOG(_T("\nEndFrame"));
+
+ if(pEndFrameInfo)
+ {
+ LOG(_T("[in] pEndFrameInfo->dwSizeMiscData = %08x"), pEndFrameInfo->dwSizeMiscData);
+ LOG(_T("[in] pEndFrameInfo->pMiscData = %08x"), pEndFrameInfo->pMiscData);
+ }
+
+ HRESULT hr = EndFrameOrg(This, pEndFrameInfo);
+
+ LOG(_T("hr = %08x"), hr);
+
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE GetBufferMine(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ DWORD dwTypeIndex,
+ /* [in] */ DWORD dwBufferIndex,
+ /* [in] */ BOOL bReadOnly,
+ /* [out] */ LPVOID *ppBuffer,
+ /* [out] */ LONG *lpStride)
+{
+ LOG(_T("\nGetBuffer"));
+
+ LOG(_T("[in] dwTypeIndex = %08x"), dwTypeIndex);
+ LOG(_T("[in] dwBufferIndex = %08x"), dwBufferIndex);
+ LOG(_T("[in] bReadOnly = %08x"), bReadOnly);
+ LOG(_T("[in] ppBuffer = %08x"), ppBuffer);
+ LOG(_T("[in] lpStride = %08x"), lpStride);
+
+ HRESULT hr = GetBufferOrg(This, dwTypeIndex, dwBufferIndex, bReadOnly, ppBuffer, lpStride);
+
+ LOG(_T("hr = %08x"), hr);
+
+ LOG(_T("[out] *ppBuffer = %02x %02x %02x %02x ..."), ((BYTE*)*ppBuffer)[0], ((BYTE*)*ppBuffer)[1], ((BYTE*)*ppBuffer)[2], ((BYTE*)*ppBuffer)[3]);
+ LOG(_T("[out] *lpStride = %08x"), *lpStride);
+
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE ReleaseBufferMine(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ DWORD dwTypeIndex,
+ /* [in] */ DWORD dwBufferIndex)
+{
+ LOG(_T("\nReleaseBuffer"));
+
+ LOG(_T("[in] dwTypeIndex = %08x"), dwTypeIndex);
+ LOG(_T("[in] dwBufferIndex = %08x"), dwBufferIndex);
+
+ HRESULT hr = ReleaseBufferOrg(This, dwTypeIndex, dwBufferIndex);
+
+ LOG(_T("hr = %08x"), hr);
+
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE ExecuteMine(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ DWORD dwFunction,
+ /* [in] */ LPVOID lpPrivateInputData,
+ /* [in] */ DWORD cbPrivateInputData,
+ /* [in] */ LPVOID lpPrivateOutputData,
+ /* [in] */ DWORD cbPrivateOutputData,
+ /* [in] */ DWORD dwNumBuffers,
+ /* [in] */ const AMVABUFFERINFO *pamvaBufferInfo)
+{
+ LOG(_T("\nExecute"));
+
+ LOG(_T("[in] dwFunction = %08x"), dwFunction);
+ if(lpPrivateInputData)
+ {
+ LOG(_T("[in] lpPrivateInputData = %02x %02x %02x %02x ..."),
+ ((BYTE*)lpPrivateInputData)[0],
+ ((BYTE*)lpPrivateInputData)[1],
+ ((BYTE*)lpPrivateInputData)[2],
+ ((BYTE*)lpPrivateInputData)[3]);
+ }
+ LOG(_T("[in] cbPrivateInputData = %08x"), cbPrivateInputData);
+ LOG(_T("[in] lpPrivateOutputData = %08"), lpPrivateOutputData);
+ LOG(_T("[in] cbPrivateOutputData = %08x"), cbPrivateOutputData);
+ LOG(_T("[in] dwNumBuffers = %08x"), dwNumBuffers);
+ if(pamvaBufferInfo)
+ {
+ LOG(_T("[in] pamvaBufferInfo->dwTypeIndex = %08x"), pamvaBufferInfo->dwTypeIndex);
+ LOG(_T("[in] pamvaBufferInfo->dwBufferIndex = %08x"), pamvaBufferInfo->dwBufferIndex);
+ LOG(_T("[in] pamvaBufferInfo->dwDataOffset = %08x"), pamvaBufferInfo->dwDataOffset);
+ LOG(_T("[in] pamvaBufferInfo->dwDataSize = %08x"), pamvaBufferInfo->dwDataSize);
+ }
+
+ HRESULT hr = ExecuteOrg(This, dwFunction, lpPrivateInputData, cbPrivateInputData, lpPrivateOutputData, cbPrivateOutputData, dwNumBuffers, pamvaBufferInfo);
+
+ LOG(_T("hr = %08x"), hr);
+
+ if(lpPrivateOutputData)
+ {
+ LOG(_T("[out] *lpPrivateOutputData = %08"), lpPrivateOutputData);
+
+ if(cbPrivateOutputData)
+ {
+ LOG(_T("[out] cbPrivateOutputData = %02x %02x %02x %02x ..."),
+ ((BYTE*)lpPrivateOutputData)[0],
+ ((BYTE*)lpPrivateOutputData)[1],
+ ((BYTE*)lpPrivateOutputData)[2],
+ ((BYTE*)lpPrivateOutputData)[3]);
+ }
+ }
+
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE QueryRenderStatusMine(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ DWORD dwTypeIndex,
+ /* [in] */ DWORD dwBufferIndex,
+ /* [in] */ DWORD dwFlags)
+{
+ LOG(_T("\nQueryRenderStatus"));
+
+ HRESULT hr = QueryRenderStatusOrg(This, dwTypeIndex, dwBufferIndex, dwFlags);
+
+ LOG(_T("hr = %08x"), hr);
+
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE DisplayFrameMine(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ DWORD dwFlipToIndex,
+ /* [in] */ IMediaSample *pMediaSample)
+{
+ LOG(_T("\nDisplayFrame"));
+
+ HRESULT hr = DisplayFrameOrg(This, dwFlipToIndex, pMediaSample);
+
+ LOG(_T("hr = %08x"), hr);
+
+ return hr;
+}
+
+void HookAMVideoAccelerator(IAMVideoAcceleratorC* pAMVideoAcceleratorC)
+{
+ BOOL res;
+ DWORD flOldProtect = 0;
+ res = VirtualProtect(pAMVideoAcceleratorC->lpVtbl, sizeof(IAMVideoAcceleratorC), PAGE_WRITECOPY, &flOldProtect);
+/*
+*/
+ if(GetVideoAcceleratorGUIDsOrg == NULL) GetVideoAcceleratorGUIDsOrg = pAMVideoAcceleratorC->lpVtbl->GetVideoAcceleratorGUIDs;
+ if(GetUncompFormatsSupportedOrg == NULL) GetUncompFormatsSupportedOrg = pAMVideoAcceleratorC->lpVtbl->GetUncompFormatsSupported;
+ if(GetInternalMemInfoOrg == NULL) GetInternalMemInfoOrg = pAMVideoAcceleratorC->lpVtbl->GetInternalMemInfo;
+ if(GetCompBufferInfoOrg == NULL) GetCompBufferInfoOrg = pAMVideoAcceleratorC->lpVtbl->GetCompBufferInfo;
+ if(GetInternalCompBufferInfoOrg == NULL) GetInternalCompBufferInfoOrg = pAMVideoAcceleratorC->lpVtbl->GetInternalCompBufferInfo;
+ if(BeginFrameOrg == NULL) BeginFrameOrg = pAMVideoAcceleratorC->lpVtbl->BeginFrame;
+ if(EndFrameOrg == NULL) EndFrameOrg = pAMVideoAcceleratorC->lpVtbl->EndFrame;
+ if(GetBufferOrg == NULL) GetBufferOrg = pAMVideoAcceleratorC->lpVtbl->GetBuffer;
+ if(ReleaseBufferOrg == NULL) ReleaseBufferOrg = pAMVideoAcceleratorC->lpVtbl->ReleaseBuffer;
+ if(ExecuteOrg == NULL) ExecuteOrg = pAMVideoAcceleratorC->lpVtbl->Execute;
+ if(QueryRenderStatusOrg == NULL) QueryRenderStatusOrg = pAMVideoAcceleratorC->lpVtbl->QueryRenderStatus;
+ if(DisplayFrameOrg == NULL) DisplayFrameOrg = pAMVideoAcceleratorC->lpVtbl->DisplayFrame;
+/*
+*/
+/*
+*/
+ pAMVideoAcceleratorC->lpVtbl->GetVideoAcceleratorGUIDs = GetVideoAcceleratorGUIDsMine;
+ pAMVideoAcceleratorC->lpVtbl->GetUncompFormatsSupported = GetUncompFormatsSupportedMine;
+ pAMVideoAcceleratorC->lpVtbl->GetInternalMemInfo = GetInternalMemInfoMine;
+ pAMVideoAcceleratorC->lpVtbl->GetCompBufferInfo = GetCompBufferInfoMine;
+ pAMVideoAcceleratorC->lpVtbl->GetInternalCompBufferInfo = GetInternalCompBufferInfoMine;
+ pAMVideoAcceleratorC->lpVtbl->BeginFrame = BeginFrameMine;
+ pAMVideoAcceleratorC->lpVtbl->EndFrame = EndFrameMine;
+ pAMVideoAcceleratorC->lpVtbl->GetBuffer = GetBufferMine;
+ pAMVideoAcceleratorC->lpVtbl->ReleaseBuffer = ReleaseBufferMine;
+ pAMVideoAcceleratorC->lpVtbl->Execute = ExecuteMine;
+ pAMVideoAcceleratorC->lpVtbl->QueryRenderStatus = QueryRenderStatusMine;
+ pAMVideoAcceleratorC->lpVtbl->DisplayFrame = DisplayFrameMine;
+/*
+*/
+ res = VirtualProtect(pAMVideoAcceleratorC->lpVtbl, sizeof(IAMVideoAcceleratorC), PAGE_EXECUTE, &flOldProtect);
+}
diff --git a/src/apps/mplayerc/IPinHook.h b/src/apps/mplayerc/IPinHook.h
new file mode 100644
index 000000000..82ab189a2
--- /dev/null
+++ b/src/apps/mplayerc/IPinHook.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+interface IPinC;
+
+typedef struct IPinCVtbl
+{
+ BEGIN_INTERFACE
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )( IPinC * This, /* [in] */ REFIID riid, /* [iid_is][out] */ void **ppvObject );
+ ULONG ( STDMETHODCALLTYPE *AddRef )( IPinC * This );
+ ULONG ( STDMETHODCALLTYPE *Release )( IPinC * This );
+ HRESULT ( STDMETHODCALLTYPE *Connect )( IPinC * This, /* [in] */ IPinC *pReceivePin, /* [in] */ const AM_MEDIA_TYPE *pmt );
+ HRESULT ( STDMETHODCALLTYPE *ReceiveConnection )( IPinC * This, /* [in] */ IPinC *pConnector, /* [in] */ const AM_MEDIA_TYPE *pmt );
+ HRESULT ( STDMETHODCALLTYPE *Disconnect )( IPinC * This );
+ HRESULT ( STDMETHODCALLTYPE *ConnectedTo )( IPinC * This, /* [out] */ IPinC **pPin );
+ HRESULT ( STDMETHODCALLTYPE *ConnectionMediaType )( IPinC * This, /* [out] */ AM_MEDIA_TYPE *pmt );
+ HRESULT ( STDMETHODCALLTYPE *QueryPinInfo )( IPinC * This, /* [out] */ PIN_INFO *pInfo );
+ HRESULT ( STDMETHODCALLTYPE *QueryDirection )( IPinC * This, /* [out] */ PIN_DIRECTION *pPinDir );
+ HRESULT ( STDMETHODCALLTYPE *QueryId )( IPinC * This, /* [out] */ LPWSTR *Id );
+ HRESULT ( STDMETHODCALLTYPE *QueryAccept )( IPinC * This, /* [in] */ const AM_MEDIA_TYPE *pmt );
+ HRESULT ( STDMETHODCALLTYPE *EnumMediaTypes )( IPinC * This, /* [out] */ IEnumMediaTypes **ppEnum );
+ HRESULT ( STDMETHODCALLTYPE *QueryInternalConnections )( IPinC * This, /* [out] */ IPinC **apPin, /* [out][in] */ ULONG *nPin );
+ HRESULT ( STDMETHODCALLTYPE *EndOfStream )( IPinC * This );
+ HRESULT ( STDMETHODCALLTYPE *BeginFlush )( IPinC * This );
+ HRESULT ( STDMETHODCALLTYPE *EndFlush )( IPinC * This );
+ HRESULT ( STDMETHODCALLTYPE *NewSegment )( IPinC * This, /* [in] */ REFERENCE_TIME tStart, /* [in] */ REFERENCE_TIME tStop, /* [in] */ double dRate );
+ END_INTERFACE
+} IPinCVtbl;
+
+interface IPinC
+{
+ CONST_VTBL struct IPinCVtbl *lpVtbl;
+};
+
+interface IMemInputPinC;
+
+typedef struct IMemInputPinCVtbl
+{
+ BEGIN_INTERFACE
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )( IPinC * This, /* [in] */ REFIID riid, /* [iid_is][out] */ void **ppvObject );
+ ULONG ( STDMETHODCALLTYPE *AddRef )( IPinC * This );
+ ULONG ( STDMETHODCALLTYPE *Release )( IPinC * This );
+ HRESULT ( STDMETHODCALLTYPE *GetAllocator )( IMemInputPinC * This, IMemAllocator **ppAllocator);
+ HRESULT ( STDMETHODCALLTYPE *NotifyAllocator )( IMemInputPinC * This, IMemAllocator *pAllocator, BOOL bReadOnly);
+ HRESULT ( STDMETHODCALLTYPE *GetAllocatorRequirements )( IMemInputPinC * This, ALLOCATOR_PROPERTIES *pProps);
+ HRESULT ( STDMETHODCALLTYPE *Receive )( IMemInputPinC * This, IMediaSample *pSample);
+ HRESULT ( STDMETHODCALLTYPE *ReceiveMultiple )( IMemInputPinC * This, IMediaSample **pSamples, long nSamples, long *nSamplesProcessed);
+ HRESULT ( STDMETHODCALLTYPE *ReceiveCanBlock )( IMemInputPinC * This);
+ END_INTERFACE
+} IMemInputPinCVtbl;
+
+interface IMemInputPinC
+{
+ CONST_VTBL struct IMemInputPinCVtbl *lpVtbl;
+};
+
+extern bool HookNewSegmentAndReceive(IPinC* pPinC, IMemInputPinC* pMemInputPin);
+extern REFERENCE_TIME g_tSegmentStart, g_tSampleStart;
+
+//
+
+#include <videoacc.h>
+
+interface IAMVideoAcceleratorC;
+
+typedef struct IAMVideoAcceleratorCVtbl
+{
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IAMVideoAcceleratorC * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IAMVideoAcceleratorC * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetVideoAcceleratorGUIDs )(
+ IAMVideoAcceleratorC * This,
+ /* [out][in] */ LPDWORD pdwNumGuidsSupported,
+ /* [out][in] */ LPGUID pGuidsSupported);
+
+ HRESULT ( STDMETHODCALLTYPE *GetUncompFormatsSupported )(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ const GUID *pGuid,
+ /* [out][in] */ LPDWORD pdwNumFormatsSupported,
+ /* [out][in] */ LPDDPIXELFORMAT pFormatsSupported);
+
+ HRESULT ( STDMETHODCALLTYPE *GetInternalMemInfo )(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ const GUID *pGuid,
+ /* [in] */ const AMVAUncompDataInfo *pamvaUncompDataInfo,
+ /* [out][in] */ LPAMVAInternalMemInfo pamvaInternalMemInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetCompBufferInfo )(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ const GUID *pGuid,
+ /* [in] */ const AMVAUncompDataInfo *pamvaUncompDataInfo,
+ /* [out][in] */ LPDWORD pdwNumTypesCompBuffers,
+ /* [out] */ LPAMVACompBufferInfo pamvaCompBufferInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetInternalCompBufferInfo )(
+ IAMVideoAcceleratorC * This,
+ /* [out][in] */ LPDWORD pdwNumTypesCompBuffers,
+ /* [out] */ LPAMVACompBufferInfo pamvaCompBufferInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *BeginFrame )(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ const AMVABeginFrameInfo *amvaBeginFrameInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *EndFrame )(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ const AMVAEndFrameInfo *pEndFrameInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetBuffer )(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ DWORD dwTypeIndex,
+ /* [in] */ DWORD dwBufferIndex,
+ /* [in] */ BOOL bReadOnly,
+ /* [out] */ LPVOID *ppBuffer,
+ /* [out] */ LONG *lpStride);
+
+ HRESULT ( STDMETHODCALLTYPE *ReleaseBuffer )(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ DWORD dwTypeIndex,
+ /* [in] */ DWORD dwBufferIndex);
+
+ HRESULT ( STDMETHODCALLTYPE *Execute )(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ DWORD dwFunction,
+ /* [in] */ LPVOID lpPrivateInputData,
+ /* [in] */ DWORD cbPrivateInputData,
+ /* [in] */ LPVOID lpPrivateOutputDat,
+ /* [in] */ DWORD cbPrivateOutputData,
+ /* [in] */ DWORD dwNumBuffers,
+ /* [in] */ const AMVABUFFERINFO *pamvaBufferInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *QueryRenderStatus )(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ DWORD dwTypeIndex,
+ /* [in] */ DWORD dwBufferIndex,
+ /* [in] */ DWORD dwFlags);
+
+ HRESULT ( STDMETHODCALLTYPE *DisplayFrame )(
+ IAMVideoAcceleratorC * This,
+ /* [in] */ DWORD dwFlipToIndex,
+ /* [in] */ IMediaSample *pMediaSample);
+
+ END_INTERFACE
+} IAMVideoAcceleratorCVtbl;
+
+interface IAMVideoAcceleratorC
+{
+ CONST_VTBL struct IAMVideoAcceleratorCVtbl *lpVtbl;
+};
+
+extern void HookAMVideoAccelerator(IAMVideoAcceleratorC* pAMVideoAcceleratorC);
diff --git a/src/apps/mplayerc/IQTVideoSurface.h b/src/apps/mplayerc/IQTVideoSurface.h
new file mode 100644
index 000000000..4b6adf6fe
--- /dev/null
+++ b/src/apps/mplayerc/IQTVideoSurface.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+//
+// IQTVideoSurface
+//
+
+[uuid("A6AE36F7-A6F2-4157-AF54-6599857E4E20")]
+interface IQTVideoSurface : public IUnknown
+{
+ STDMETHOD (BeginBlt) (const BITMAP& bm) PURE;
+ STDMETHOD (DoBlt) (const BITMAP& bm) PURE;
+};
diff --git a/src/apps/mplayerc/ISDb.cpp b/src/apps/mplayerc/ISDb.cpp
new file mode 100644
index 000000000..df00ab9c6
--- /dev/null
+++ b/src/apps/mplayerc/ISDb.cpp
@@ -0,0 +1,89 @@
+#include "stdafx.h"
+#include "ISDb.h"
+#include "mplayerc.h"
+
+bool hash(LPCTSTR fn, filehash& fh)
+{
+ CFile f;
+ CFileException fe;
+ if(!f.Open(fn, CFile::modeRead|CFile::osSequentialScan|CFile::shareDenyNone, &fe))
+ return false;
+
+ CPath p(fn);
+ p.StripPath();
+ fh.name = (LPCTSTR)p;
+
+ fh.size = f.GetLength();
+
+ fh.hash = fh.size;
+ for(UINT64 tmp = 0, i = 0; i < 65536/sizeof(tmp) && f.Read(&tmp, sizeof(tmp)); fh.hash += tmp, i++);
+ f.Seek(max(0, (INT64)fh.size - 65536), CFile::begin);
+ for(UINT64 tmp = 0, i = 0; i < 65536/sizeof(tmp) && f.Read(&tmp, sizeof(tmp)); fh.hash += tmp, i++);
+
+ return true;
+}
+
+void hash(CPlaylist& pl, CList<filehash>& fhs)
+{
+ fhs.RemoveAll();
+
+ POSITION pos = pl.GetHeadPosition();
+ while(pos)
+ {
+ CString fn = pl.GetNext(pos).m_fns.GetHead();
+ if(AfxGetAppSettings().Formats.FindExt(CPath(fn).GetExtension().MakeLower(), true))
+ continue;
+
+ filehash fh;
+ if(!hash(fn, fh))
+ continue;
+
+ fhs.AddTail(fh);
+ }
+}
+
+CStringA makeargs(CPlaylist& pl)
+{
+ CList<filehash> fhs;
+ hash(pl, fhs);
+
+ CAtlList<CStringA> args;
+
+ POSITION pos = fhs.GetHeadPosition();
+ for(int i = 0; pos; i++)
+ {
+ filehash& fh = fhs.GetNext(pos);
+
+ CStringA str;
+ str.Format("name[%d]=%s&size[%d]=%016I64x&hash[%d]=%016I64x",
+ i, UrlEncode(CStringA(fh.name)),
+ i, fh.size,
+ i, fh.hash);
+
+ args.AddTail(str);
+ }
+
+ return Implode(args, '&');
+}
+
+bool OpenUrl(CInternetSession& is, CString url, CStringA& str)
+{
+ str.Empty();
+
+ try
+ {
+ CAutoPtr<CStdioFile> f(is.OpenURL(url, 1, INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_EXISTING_CONNECT));
+
+ char buff[1024];
+ for(int len; (len = f->Read(buff, sizeof(buff))) > 0; str += CStringA(buff, len));
+
+ f->Close(); // must close it because the desctructor doesn't seem to do it and we will get an exception when "is" is destroying
+ }
+ catch(CInternetException* ie)
+ {
+ ie->Delete();
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/apps/mplayerc/ISDb.h b/src/apps/mplayerc/ISDb.h
new file mode 100644
index 000000000..97ee0bc9a
--- /dev/null
+++ b/src/apps/mplayerc/ISDb.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <atlcoll.h>
+#include <afxinet.h>
+#include "Playlist.h"
+
+#define ISDb_PROTOCOL_VERSION 1
+
+struct isdb_subtitle
+{
+ int id, discs, disc_no;
+ CStringA name, format, language, iso639_2, nick, email;
+ struct isdb_subtitle() {reset();}
+ void reset() {id = discs = disc_no = 0; format = language = nick = email = "";}
+};
+
+struct isdb_movie
+{
+ CAtlList<CStringA> titles;
+ CAtlList<isdb_subtitle> subs;
+ void reset() {titles.RemoveAll(); subs.RemoveAll();}
+ void operator = (const struct isdb_movie& m)
+ {
+ titles.RemoveAll();
+ titles.AddTailList(&m.titles);
+ subs.RemoveAll();
+ subs.AddTailList(&m.subs);
+ }
+};
+
+struct filehash {CString name; UINT64 size, hash;};
+
+extern bool hash(LPCTSTR fn, filehash& fh);
+extern void hash(CPlaylist& pl, CList<filehash>& fhs);
+extern CStringA makeargs(CPlaylist& pl);
+extern bool OpenUrl(CInternetSession& is, CString url, CStringA& str);
+
diff --git a/src/apps/mplayerc/KeyProvider.cpp b/src/apps/mplayerc/KeyProvider.cpp
new file mode 100644
index 000000000..298f10fc8
--- /dev/null
+++ b/src/apps/mplayerc/KeyProvider.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "keyprovider.h"
+#include "..\..\DSUtil\DSUtil.h"
+//#include "c:\WMSDK\WMFSDK9\include\wmsdk.h"
+
+CKeyProvider::CKeyProvider()
+ : CUnknown(NAME("CKeyProvider"), NULL)
+{
+}
+
+STDMETHODIMP CKeyProvider::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ return
+ QI(IServiceProvider)
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+STDMETHODIMP CKeyProvider::QueryService(REFIID siid, REFIID riid, void **ppv)
+{
+ /*
+ if(siid == __uuidof(IWMReader) && riid == IID_IUnknown)
+ {
+ CComPtr<IUnknown> punkCert;
+ HRESULT hr = WMCreateCertificate(&punkCert);
+ if(SUCCEEDED(hr))
+ *ppv = (void*)punkCert.Detach();
+ return hr;
+ }
+ */
+
+ return E_NOINTERFACE;
+}
diff --git a/src/apps/mplayerc/KeyProvider.h b/src/apps/mplayerc/KeyProvider.h
new file mode 100644
index 000000000..51f68010f
--- /dev/null
+++ b/src/apps/mplayerc/KeyProvider.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <Servprov.h>
+
+// Declare and implement a key provider class derived from IServiceProvider.
+
+class CKeyProvider
+ : public CUnknown
+ , public IServiceProvider
+{
+public:
+ CKeyProvider();
+
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ // IServiceProvider
+ STDMETHODIMP QueryService(REFIID siid, REFIID riid, void **ppv);
+};
diff --git a/src/apps/mplayerc/LineNumberEdit.cpp b/src/apps/mplayerc/LineNumberEdit.cpp
new file mode 100644
index 000000000..563bd4a15
--- /dev/null
+++ b/src/apps/mplayerc/LineNumberEdit.cpp
@@ -0,0 +1,971 @@
+/* ==========================================================================
+ CLineNumberEdit
+ Author : Johan Rosengren, Abstrakt Mekanik AB
+ Date : 2004-03-09
+ Purpose : CLineNumberEdit is a CEdit-derived class that displays
+ line numbers to the left of the text.
+ Description : The class uses the edit rect to make space for the line
+ numbers. The line numbers are relized through a special
+ CStatic-derived class, CLineNumberStatic. As soon as the
+ text is updated, the CLineNumberStatic is updated as
+ well.
+ Usage : The control can be dynamically created, or created from
+ a dialog template. The formatting string for the line
+ numbers can be set by calling SetLineNumberFormat (the
+ same format string as for CString::Format). By calling
+ SetMarginForegroundColor or SetMarginBackgroundColor
+ the fore- and background colors for the line number
+ display is set.
+ ========================================================================
+ Update : Keith Bowes
+ Date : 2004-04-13
+ Purpose : 1. To allow CLineNumberEdit to properly change colour when
+ Enabled/Disabled or when system colours change.
+ Changing system colours only has a noticable effect when
+ a scheme such as Marine or Plum is chosen.
+ 2. To allow a line number delta to be applied to the first
+ line number so the index does not have to start at zero.
+ 3. To allow a max value to be specified to stop the line
+ count and to allow smarter size formatting.
+ Description : 1. Added OnEnable and OnSysColorChange to detect when
+ a colour change is required. This allows the line number
+ area and CEdit area to update colours properly.
+ Added colour ref variables to hold enabled/disabled states
+ of the background/foreground colours.
+ In an attempt to allow previous functionality to take
+ precedence, if the colours are changed explicitly, the
+ system colours are no longer queried.
+ 2. Added m_LineDelta, applied when line numbers are formatted.
+ 3. Using m_maxval when > 0 to limit the max values and when
+ formatting colomn width.
+ JRO: Added m_lineDelta as well.
+ Usage : 1. Default behaviour is to change colours to reflect CEdit.
+ manually changing the colour will cause the colours to
+ only change to the specified colours.
+ 2. SetLineNumberRange sets both min and max values.
+ 3. SetLineNumberRange sets both min and max values.
+
+ Comments : - Perhaps line values should be stored as UINT's as negative
+ values may have unexpected results.
+ - CLineNumberEdit::m_format creates a duplicate of
+ CLineNumberStatic::m_format, is this needed?
+ JRO: Even though the the two classes are thightly coupled,
+ this duplication of data makes it easier to decouple them.
+ A small matter, but code reuse is Politically Correct,
+ and as such A Desirable Feature.
+ - Added options could allow different system colours to be
+ chosen and updated as system attributes are changed.
+ - if m_maxval is exceeded in the edit box, new lines
+ are added without line numbers. This might not be the
+ desired behaviour.
+ JRO: I think this is rather nifty, actually. If I, as a
+ developer, sets the max number of lines to be numbered,
+ I also expect this to be the case :-)))
+ - It's not spelled wrong, just differently. ;0)
+ ========================================================================
+ Update : Johan Rosengren
+ Date : 2004-04-14
+ Purpose : 1. Allow deriving of CLineNumberEdit.
+ Description : 1. Made the message handlers virtual.
+ Usage : 1. Declare message handlers as virtual in derived
+ classes. Note that CLineNumberEdit is not built to
+ be derived from, however.
+ ========================================================================
+ Update : Keith Bowes
+ Date : 2004-04-22
+ Purpose : To allow processing of WM_LINESCROLL messages.
+ Description : Added OnLineScroll to handle the message.
+ Usage : Now will call UpdateTopAndBottom if the message is
+ received.
+ ========================================================================
+ Update : Johan Rosengren
+ Date : 2004-05-02
+ Purpose : Select complete line when a line-number is clicked
+ Description : Added registered user message, sent when the line-
+ number static is clicked.
+ Usage : See urm_SELECTLINE in the code.
+ ========================================================================*/
+
+#include "stdafx.h"
+#include "LineNumberEdit.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+// Registered message to allow selection of complete
+// lines by clicking the line number
+UINT urm_SELECTLINE = ::RegisterWindowMessage( _T("_LINE_NUMBER_EDIT_SELECTLINE_") );
+
+/////////////////////////////////////////////////////////////////////////////
+// CLineNumberEdit
+CLineNumberEdit::CLineNumberEdit()
+/* ============================================================
+ Function : CLineNumberEdit::CLineNumberEdit
+ Description : constructor
+
+ Return : void
+ Parameters : none
+
+ Usage :
+
+ ============================================================*/
+{
+
+ m_hWnd = NULL;
+ m_line.m_hWnd = NULL;
+ m_zero.cx = 0;
+ m_zero.cy = 0;
+ m_format = _T( "%03i" );
+ m_LineDelta = 1;
+
+ // Could default m_maxval to 99,999, but may cause problems
+ // if m_format is changed and m_maxval is not...
+ m_maxval = 998;
+
+ // Setting up so by defult the original hard-coded colour
+ // scheme is used when enabled and the system colours are
+ // used when disabled.
+ m_bUseEnabledSystemColours = FALSE;
+ m_bUseDisabledSystemColours = TRUE;
+ m_EnabledFgCol = RGB( 0, 0, 0 );
+ m_EnabledBgCol = RGB( 200, 200, 200 );
+ m_DisabledFgCol = GetSysColor( COLOR_GRAYTEXT );
+ m_DisabledBgCol = GetSysColor( COLOR_3DFACE );
+
+ SetWindowColour();
+
+}
+
+CLineNumberEdit::~CLineNumberEdit()
+/* ============================================================
+ Function : CLineNumberEdit::~CLineNumberEdit
+ Description : destructor
+
+ Return : void
+ Parameters : none
+
+ Usage :
+
+ ============================================================*/
+{
+}
+
+BEGIN_MESSAGE_MAP(CLineNumberEdit, CEdit)
+ ON_CONTROL_REFLECT(EN_CHANGE, OnChange)
+ ON_WM_VSCROLL()
+ ON_CONTROL_REFLECT(EN_VSCROLL, OnVscroll)
+ ON_MESSAGE(WM_SETFONT, OnSetFont)
+ ON_WM_SIZE()
+ ON_MESSAGE(WM_SETTEXT, OnSetText)
+ ON_WM_SYSCOLORCHANGE()
+ ON_WM_ENABLE()
+ ON_MESSAGE(EM_LINESCROLL, OnLineScroll)
+ ON_REGISTERED_MESSAGE(urm_SELECTLINE, OnSelectLine)
+END_MESSAGE_MAP()
+
+void CLineNumberEdit::PreSubclassWindow()
+/* ============================================================
+ Function : CLineNumberEdit::PreSubclassWindow
+ Description : This function is called before the control
+ is subclassed for a control on a dialog
+ template, and during creation for
+ dynamically created controls.
+
+ Return : void
+ Parameters : none
+
+ Usage : Called from MFC
+
+ ============================================================*/
+{
+
+ // Unfortunately, we can't change to ES_MULTILINE
+ // during run-time.
+ ASSERT( GetStyle() & ES_MULTILINE );
+
+ // Creating the line number control
+ SetLineNumberFormat( m_format );
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CLineNumberEdit message handlers
+
+void CLineNumberEdit::OnSysColorChange()
+/* ============================================================
+ Function : CLineNumberEdit::OnSysColorChange
+ Description : Handles WM_SYSCOLORCHANGE. User has changed
+ the system colours, want to refresh.
+
+ Return : void
+ Parameters : void
+
+ Usage : Called from Windows
+
+ ============================================================*/
+{
+
+ CEdit::OnSysColorChange();
+
+ // update the CStatic with the new colours
+ SetWindowColour( IsWindowEnabled() );
+
+}
+
+LRESULT CLineNumberEdit::OnSetText( WPARAM wParam, LPARAM lParam )
+/* ============================================================
+ Function : CLineNumberEdit::OnSetText
+ Description : Handles WM_SETTEXT. We must update the line
+ numbers in the line number control as well.
+
+ Return : LRESULT - From Def proc
+ Parameters : WPARAM wParam - From Windows
+ LPARAM lParam - From Windows
+
+ Usage : Called from Windows
+
+ ============================================================*/
+{
+
+ // Default processing
+ LRESULT retval = DefWindowProc( WM_SETTEXT, wParam, lParam );
+ UpdateTopAndBottom();
+ return retval;
+
+}
+
+void CLineNumberEdit::OnChange()
+/* ============================================================
+ Function : CLineNumberEdit::OnChange
+ Description : Mapped to EN_CHANGE. We must handle
+ EN_CHANGE to let the line-number control
+ reflect changes to the edit box content.
+
+ Return : void
+ Parameters : none
+
+ Usage : Called from Windows
+
+ ============================================================*/
+{
+
+ UpdateTopAndBottom();
+
+}
+
+void CLineNumberEdit::OnVscroll()
+/* ============================================================
+ Function : CLineNumberEdit::OnVscroll
+ Description : Mapped to EN_VSCROLL. We update the line
+ numbers in the line number control
+
+ Return : void
+ Parameters : none
+
+ Usage : Called from Windows
+
+ ============================================================*/
+{
+
+ UpdateTopAndBottom();
+
+}
+
+void CLineNumberEdit::OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
+/* ============================================================
+ Function : CLineNumberEdit::OnVScroll
+ Description : Handles WM_VSCROLL. We handle WM_VSCROLL
+ in addition to the notification EN_VSCROLL,
+ to handle scrollbar dragging as well
+
+ Return : void
+ Parameters : UINT nSBCode - From Windows
+ UINT nPos - From Windows
+ CScrollBar* pScrollBar - From Windows
+
+ Usage : Called from Windows
+
+ ============================================================*/
+{
+
+ CEdit::OnVScroll( nSBCode, nPos, pScrollBar );
+ UpdateTopAndBottom();
+
+}
+
+LRESULT CLineNumberEdit::OnLineScroll( WPARAM wParam, LPARAM lParam )
+/* ============================================================
+ Function : CLineNumberEdit::OnLineScroll
+ Description : Mapped to EM_LINESCROLL. We update the line
+ numbers in the line number control.
+
+ Return : void
+ Parameters : none
+ Usage : Called from Windows
+ ============================================================*/
+{
+
+ // Default processing
+ LRESULT retval = DefWindowProc( EM_LINESCROLL, wParam, lParam );
+ UpdateTopAndBottom();
+ return retval;
+
+}
+
+LRESULT CLineNumberEdit::OnSetFont( WPARAM wParam, LPARAM lParam )
+/* ============================================================
+ Function : CLineNumberEdit::OnSetFont
+ Description : Mapped to WM_SETFONT. We must recalculate
+ the line number control size as well.
+
+ Return : LRESULT - Always 0
+ Parameters : WPARAM wParam - From Windows
+ LPARAM lParam - From Windows
+
+ Usage : Called from Windows
+
+ ============================================================*/
+{
+
+ DefWindowProc( WM_SETFONT, wParam, lParam );
+ // We resize the line-number
+ // field
+ Prepare();
+ return 0;
+
+}
+
+void CLineNumberEdit::OnSize( UINT nType, int cx, int cy )
+/* ============================================================
+ Function : CLineNumberEdit::OnSize
+ Description : Handles WM_SIZE. Recalculates the line
+ number control size as well.
+
+ Return : void
+ Parameters : UINT nType - From Windows
+ int cx - From Windows
+ int cy - From Windows
+
+ Usage : Called from Windows
+
+ ============================================================*/
+{
+
+ CEdit::OnSize( nType, cx, cy );
+
+ // If we have the line-number
+ // control, it must be resized
+ // as well.
+ if( m_line.m_hWnd )
+ Prepare();
+
+}
+
+void CLineNumberEdit::OnEnable( BOOL bEnable )
+/* ============================================================
+ Function : CLineNumberEdit::OnEnable
+ Description : Handles WM_ENABLE. Calls to set colours.
+
+ Return : void
+ Parameters : BOOL bEnable - From Windows
+
+ Usage : Called from Windows.
+
+ ============================================================*/
+{
+
+ CEdit::OnEnable( bEnable );
+ SetWindowColour( bEnable );
+
+}
+
+LRESULT CLineNumberEdit::OnSelectLine(WPARAM wParam, LPARAM /*lParam*/ )
+/* ============================================================
+ Function : CLineNumberEdit::OnSelectLine
+ Description : Handler for the urm_SELECTLINE registered
+ message. Will select the line in wParam.
+
+ Return : LRESULT - Not used
+ Parameters : WPARAM wParam - The line to select
+ LPARAM lParam - Not used
+
+ Usage : Called from MFC. Use
+ SendMessage( urm_SELECTLINE, line ) from
+ code.
+
+ ============================================================*/
+{
+
+ // Calc start and end position of the line
+ int lineno = wParam + GetScrollPos( SB_VERT );
+ int start = LineIndex( lineno );
+ int end = LineIndex( lineno + 1 );
+ SetSel( start, end - 1 );
+ return 0;
+
+}
+
+void CLineNumberEdit::SetWindowColour( BOOL bEnable /*= TRUE*/ )
+/* ============================================================
+ Function : CLineNumberEdit::SetWindowColour
+ Description : Handles changing window colours.
+
+ Return : void
+ Parameters : BOOL bEnable - flag if set enabled/disabled
+ colours
+
+ Usage : Called to change colours in the edit box.
+
+ ============================================================*/
+{
+
+ if (m_bUseEnabledSystemColours)
+ {
+ // re-query the system colours in case they have changed.
+ m_EnabledFgCol = GetSysColor( COLOR_WINDOWTEXT );
+ m_EnabledBgCol = GetSysColor( COLOR_WINDOW );
+ }
+
+ if (m_bUseDisabledSystemColours)
+ {
+ // re-query the system colours in case they have changed.
+ m_DisabledFgCol = GetSysColor( COLOR_GRAYTEXT );
+ m_DisabledBgCol = GetSysColor( COLOR_3DFACE );
+ }
+
+ // change the colour based on bEnable
+ if (bEnable)
+ {
+ m_line.SetFgColor( m_EnabledFgCol, TRUE );
+ m_line.SetBgColor( m_EnabledBgCol, TRUE );
+ } else {
+ m_line.SetFgColor( m_DisabledFgCol, TRUE );
+ m_line.SetBgColor( m_DisabledBgCol, TRUE );
+ }
+
+}
+
+void CLineNumberEdit::UseSystemColours( BOOL bUseEnabled /*= TRUE*/, BOOL bUseDisabled /*= TRUE*/ )
+/* ============================================================
+ Function : CLineNumberEdit::UseSystemColours
+ Description : Sets the Use*SystemColours flags.
+
+ Return : void
+ Parameters : BOOL bEnabled - flag if to use enabled
+ system colours
+ BOOL bDisabled - flag if to use disabled
+ system colours
+
+ Usage : Called to change colours in the edit box
+
+ ============================================================*/
+{
+
+ m_bUseEnabledSystemColours = bUseEnabled;
+ m_bUseDisabledSystemColours = bUseDisabled;
+ BOOL bEnable = TRUE;
+ if (::IsWindow(m_hWnd))
+ bEnable = IsWindowEnabled();
+
+ SetWindowColour( bEnable );
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CLineNumberEdit private implementation
+
+void CLineNumberEdit::Prepare()
+/* ============================================================
+ Function : CLineNumberEdit::Prepare
+ Description : Setting the edit rect for the control and
+ either create or move the line number
+ control. Also sets the top- and bottom
+ line numbers.
+
+ Return : void
+ Parameters : none
+
+ Usage : Must be called to (re)establish the edit
+ rect, must also be called as soon as the
+ control changes size.
+
+ ============================================================*/
+{
+
+ // Calc sizes
+ int width = CalcLineNumberWidth();
+ CRect rect;
+ GetClientRect( &rect );
+ CRect rectEdit( rect );
+ rect.right = width;
+ rectEdit.left = rect.right + 3;
+
+ // Setting the edit rect and
+ // creating or moving child control
+ SetRect( &rectEdit );
+ if( m_line.m_hWnd )
+ m_line.MoveWindow( 0, 0, width, rect.Height() );
+ else
+ m_line.Create(NULL,WS_CHILD | WS_VISIBLE | SS_NOTIFY, rect, this, 1 );
+
+ GetRect( &rectEdit );
+
+ // Update line number control data
+ m_line.SetTopMargin( rectEdit.top );
+ UpdateTopAndBottom();
+
+}
+
+int CLineNumberEdit::CalcLineNumberWidth()
+/* ============================================================
+ Function : CLineNumberEdit::CalcLineNumberWidth
+ Description : Calculates the desired width of the line
+ number control, using the current format
+ string and the max number of chars allowed
+ (pessimistic - assumes one character per
+ line).
+
+ Return : int - The width in pixels
+ Parameters : none
+
+ Usage : Called as soon as the format string is
+ changed.
+
+ ============================================================*/
+{
+
+ CClientDC dc( this );
+
+ // If a new font is set during runtime,
+ // we must explicitly select the font into
+ // the CClientDC to measure it.
+ CFont* font = GetFont();
+ CFont* oldFont = dc.SelectObject( font );
+
+ m_zero=dc.GetTextExtent( _T( "0" ) );
+ CString format;
+
+ // GetLimitText returns the number of bytes the edit box may contain,
+ // not the max number of lines...
+ //... which is the max number of lines, given one character per d:o :-)
+ int maxval = GetLimitText();
+ if (m_maxval > 0)
+ maxval = m_maxval + m_LineDelta;
+
+ format.Format( m_format, maxval );
+ CSize fmt = dc.GetTextExtent( format );
+ dc.SelectObject( oldFont );
+
+ // Calculate the size of the line-
+ // number field. We add a 5 pixel margin
+ // to the max size of the format string
+ return fmt.cx + 5;
+
+}
+
+void CLineNumberEdit::UpdateTopAndBottom()
+/* ============================================================
+ Function : CLineNumberEdit::UpdateTopAndBottom
+ Description : Updates the top- and bottom line number
+ for the line number control.
+
+ Return : void
+ Parameters : none
+ Usage : Should be called as soon as the contents of
+ the control is changed.
+
+ ============================================================*/
+{
+
+ CRect rect;
+ GetClientRect( &rect );
+ int maxline = GetLineCount() + m_LineDelta;
+
+ // Height for individual lines
+ int lineheight = m_zero.cy;
+
+ // Calculate the number of lines to draw
+ int topline = GetFirstVisibleLine() + m_LineDelta;
+ if( ( topline + ( rect.Height() / lineheight ) ) < maxline )
+ maxline = topline + ( rect.Height() / lineheight );
+
+ if ( m_maxval > 0 && maxline > m_maxval + m_LineDelta )
+ maxline = m_maxval + m_LineDelta;
+
+ m_line.SetTopAndBottom( topline, maxline );
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CLineNumberEdit public implementation
+
+void CLineNumberEdit::SetMarginForegroundColor( COLORREF col, BOOL redraw, BOOL bEnabled /*= TRUE*/ )
+/* ============================================================
+ Function : CLineNumberEdit::SetMarginForegroundColor
+ Description : Sets the text color for the number
+ margin.
+
+ Return : void
+ Parameters : COLORREF col - The new text color
+ BOOL redraw - TRUE if the control
+ should be redrawn
+ (default)
+
+ Usage : Call to set a new text color for the line
+ number margin. The control will be redrawn
+ if it exists.
+
+ ============================================================*/
+{
+
+ m_line.SetFgColor( col, redraw );
+ if (bEnabled)
+ {
+ m_bUseEnabledSystemColours = FALSE;
+ m_EnabledFgCol = col;
+ } else {
+ m_bUseDisabledSystemColours = FALSE;
+ m_DisabledFgCol = col;
+ }
+
+}
+
+void CLineNumberEdit::SetMarginBackgroundColor( COLORREF col, BOOL redraw, BOOL bEnabled /*= TRUE*/ )
+/* ============================================================
+ Function : CLineNumberEdit::SetMarginBackgroundColor
+ Description : Sets the background color for the number
+ margin.
+
+ Return : void
+ Parameters : COLORREF col - The new background color
+ BOOL redraw - TRUE if the control
+ should be redrawn
+ (default)
+
+ Usage : Call to set a new background color for the
+ line number margin. The control will be
+ redrawn if it exists.
+
+ ============================================================*/
+{
+
+ m_line.SetBgColor( col, redraw );
+ if (bEnabled)
+ {
+ m_bUseEnabledSystemColours = FALSE;
+ m_EnabledBgCol = col;
+ } else {
+ m_bUseDisabledSystemColours = FALSE;
+ m_DisabledBgCol = col;
+ }
+
+}
+
+void CLineNumberEdit::SetLineNumberFormat( CString format )
+/* ============================================================
+ Function : CLineNumberEdit::SetLineNumberFormat
+ Description : Changes the way line numbers are presented
+ on screen.
+
+ Return : void
+ Parameters : CString format - The new format string
+
+ Usage : Call with a format string using the same
+ format as CString::Format. It should contain
+ one and only one numeric type.
+
+ ============================================================*/
+{
+
+ m_format = format;
+ m_line.SetLineNumberFormat( format );
+ if( m_hWnd )
+ Prepare();
+
+}
+
+void CLineNumberEdit::SetLineNumberRange( UINT nMin, UINT nMax /*= 0*/ )
+/* ============================================================
+ Function : CLineNumberEdit::SetLineNumberRange
+ Description : Changes the default min and max line numbers.
+
+ Return : void
+ Parameters : int nMin - changes the line offset
+ int nMax - changes the max line number
+
+ Usage : Call to set up the min and max line numbers.
+
+ ============================================================*/
+{
+
+ m_LineDelta = ( int ) nMin;
+ m_maxval = ( int ) nMax;
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CLineNumberStatic
+
+CLineNumberStatic::CLineNumberStatic()
+/* ============================================================
+ Function : CLineNumberStatic::CLineNumberStatic
+ Description : constructor
+
+ Return : void
+ Parameters : none
+
+ Usage :
+
+ ============================================================*/
+{
+
+ m_bgcol = RGB( 255, 255, 248 );
+ m_fgcol = RGB( 0, 0, 0 );
+ m_format = _T( "%05i" );
+ m_topline = 0;
+ m_bottomline = 0;
+}
+
+CLineNumberStatic::~CLineNumberStatic()
+/* ============================================================
+ Function : CLineNumberStatic::~CLineNumberStatic
+ Description : destructor
+
+ Return : void
+ Parameters : none
+
+ Usage :
+
+ ============================================================*/
+{
+}
+
+BEGIN_MESSAGE_MAP(CLineNumberStatic, CStatic)
+ ON_WM_PAINT()
+ ON_WM_ERASEBKGND()
+ ON_WM_LBUTTONDOWN()
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CLineNumberStatic message handlers
+
+void CLineNumberStatic::OnPaint()
+/* ============================================================
+ Function : CLineNumberStatic::OnPaint
+ Description : Handler for WM_PAINT.
+
+ Return : void
+ Parameters : none
+
+ Usage : Called from Windows.
+
+ ============================================================*/
+{
+
+ CPaintDC dcPaint( this );
+
+ CRect rect;
+ GetClientRect( &rect );
+
+ // We double buffer the drawing -
+ // preparing the memory CDC
+ CDC dc;
+ dc.CreateCompatibleDC( &dcPaint );
+ int saved = dc.SaveDC();
+
+ // Create GDI and select objects
+ CBitmap bmp;
+ CPen pen;
+ bmp.CreateCompatibleBitmap( &dcPaint, rect.Width(), rect.Height() );
+ pen.CreatePen( PS_SOLID, 1, m_fgcol );
+ dc.SelectObject( &bmp );
+ dc.SelectObject( &pen );
+
+ // Painting the background
+ dc.FillSolidRect( &rect, m_bgcol );
+ dc.MoveTo( rect.right - 1, 0 );
+ dc.LineTo( rect.right - 1, rect.bottom );
+
+ // Setting other attributes
+ dc.SetTextColor( m_fgcol );
+ dc.SetBkColor( m_bgcol );
+ dc.SelectObject( GetParent()->GetFont() );
+
+ // Output the line numbers
+ if( m_bottomline )
+ {
+ int lineheight = dc.GetTextExtent( _T( "0" ) ).cy;
+ for( int t = m_topline ; t < m_bottomline ; t++ )
+ {
+ CString output;
+ output.Format( m_format, t );
+ int topposition = m_topmargin + lineheight * ( t - m_topline );
+ dc.TextOut( 2, topposition, output );
+ }
+ }
+
+ dcPaint.BitBlt( 0, 0, rect. right, rect.bottom, &dc, 0, 0, SRCCOPY );
+ dc.RestoreDC( saved );
+
+}
+
+BOOL CLineNumberStatic::OnEraseBkgnd( CDC* )
+/* ============================================================
+ Function : CLineNumberStatic::OnEraseBkgnd
+ Description : Mapped to WM_ERASEBKGND. Handled to avoid
+ flicker, as we redraw the complete control
+ in OnPaint
+
+ Return : BOOL - Always TRUE
+ Parameters : CDC* - From Windows
+
+ Usage : Called from Windows.
+
+ ============================================================*/
+{
+
+ return TRUE;
+
+}
+
+void CLineNumberStatic::OnLButtonDown( UINT nFlags, CPoint point )
+/* ============================================================
+ Function : CLineNumberStatic::OnLButtonDown
+ Description : Called when the control is clicked. Will
+ send the urm_SELECTLINE registered message
+ to the parent to select the line clicked on.
+
+ Return : void
+ Parameters : UINT nFlags - Not used
+ CPoint point - Position of cursor
+
+ Usage : Called from Windows.
+
+ ============================================================*/
+{
+
+ // Find the line clicked on
+ CClientDC dc( this );
+ dc.SelectObject( GetParent()->GetFont() );
+ int lineheight = dc.GetTextExtent( _T( "0" ) ).cy;
+ int lineno = ( int ) ( ( double ) point.y / ( double ) lineheight );
+
+ // Select this line in the edit control
+ GetParent()->SendMessage( urm_SELECTLINE, lineno );
+
+ CStatic::OnLButtonDown( nFlags, point );
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CLineNumberStatic public implementation
+
+void CLineNumberStatic::SetBgColor( COLORREF col, BOOL redraw )
+/* ============================================================
+ Function : CLineNumberStatic::SetBgColor
+ Description : This function sets the panel background
+ color
+
+ Return : void
+ Parameters : COLORREF col - New background color
+ BOOL redraw - TRUE if the control
+ should be redrawn
+ (default)
+
+ Usage : Called from the parent.
+
+ ============================================================*/
+{
+
+ m_bgcol = col;
+ if( m_hWnd && redraw )
+ RedrawWindow();
+
+}
+
+void CLineNumberStatic::SetFgColor( COLORREF col, BOOL redraw )
+/* ============================================================
+ Function : CLineNumberStatic::SetFgColor
+ Description : This function sets the panel foreground
+ color
+
+ Return : void
+ Parameters : COLORREF col - New text color
+ BOOL redraw - TRUE if the control
+ should be redrawn
+ (default)
+
+ Usage : Called from the parent.
+
+ ============================================================*/
+{
+
+ m_fgcol = col;
+ if( m_hWnd && redraw )
+ RedrawWindow();
+
+}
+
+void CLineNumberStatic::SetTopAndBottom( int topline, int bottomline )
+/* ============================================================
+ Function : CLineNumberStatic::SetTopAndBottom
+ Description : Sets the top- and bottom line and redraw
+ the control (if it exists)
+
+ Return : void
+ Parameters : int topline - The top line number
+ int bottomline - The bottom line number
+
+ Usage : Called when the top and bottom line is
+ changed in the parent.
+
+ ============================================================*/
+{
+
+ m_topline = topline;
+ m_bottomline = bottomline;
+ if( m_hWnd )
+ RedrawWindow();
+
+}
+
+void CLineNumberStatic::SetTopMargin( int topmargin )
+/* ============================================================
+ Function : CLineNumberStatic::SetTopMargin
+ Description : Sets the top margin for painting.
+
+ Return : void
+ Parameters : int topmargin - The top margin to set
+
+ Usage : Will be called with the value of GetRect
+ from the parent.
+
+ ============================================================*/
+{
+
+ m_topmargin = topmargin;
+
+}
+
+void CLineNumberStatic::SetLineNumberFormat( CString format )
+/* ============================================================
+ Function : CLineNumberStatic::SetLineNumberFormat
+ Description : Sets the format string of the control
+
+ Return : void
+ Parameters : CString format - Format string to use
+
+ Usage : Called from the parent when the format
+ string is changed.
+
+ ============================================================*/
+{
+
+ m_format = format;
+ if( m_hWnd )
+ RedrawWindow();
+
+}
diff --git a/src/apps/mplayerc/LineNumberEdit.h b/src/apps/mplayerc/LineNumberEdit.h
new file mode 100644
index 000000000..4794ead44
--- /dev/null
+++ b/src/apps/mplayerc/LineNumberEdit.h
@@ -0,0 +1,99 @@
+#if !defined(AFX_LINENUMBEREDIT_H__CAB7A465_709C_42B8_80D0_2B0AF6D25AD4__INCLUDED_)
+#define AFX_LINENUMBEREDIT_H__CAB7A465_709C_42B8_80D0_2B0AF6D25AD4__INCLUDED_
+
+/////////////////////////////////////////////////////////////////////////////
+// CLineNumberStatic window
+
+class CLineNumberStatic : public CStatic
+{
+// Construction/destruction
+public:
+ CLineNumberStatic();
+ virtual ~CLineNumberStatic();
+
+// Operations
+public:
+ void SetFgColor( COLORREF col, BOOL redraw );
+ void SetBgColor( COLORREF col, BOOL redraw );
+ void SetTopAndBottom( int topline, int bottomline );
+ void SetTopMargin( int topmargin );
+ void SetLineNumberFormat( CString format );
+
+protected:
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ afx_msg void OnPaint();
+ afx_msg void OnLButtonDown( UINT nFlags, CPoint point );
+ DECLARE_MESSAGE_MAP()
+
+private:
+// Attributes
+ COLORREF m_fgcol;
+ COLORREF m_bgcol;
+ CString m_format;
+
+ int m_topmargin; // Current top margin
+ int m_topline; // Current top line number
+ int m_bottomline; // Current bottom line number
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CLineNumberEdit window
+
+class CLineNumberEdit : public CEdit
+{
+// Construction/destruction
+public:
+ CLineNumberEdit();
+ virtual ~CLineNumberEdit();
+
+// Operations
+public:
+ void SetMarginForegroundColor( COLORREF col, BOOL redraw = TRUE, BOOL bEnabled = TRUE );
+ void SetMarginBackgroundColor( COLORREF col, BOOL redraw = TRUE, BOOL bEnabled = TRUE );
+ void SetLineNumberFormat( CString format );
+ void SetLineNumberRange( UINT nMin, UINT nMax = 0 );
+ void UseSystemColours( BOOL bUseEnabled = TRUE, BOOL bUseDisabled = TRUE );
+
+ int GetLineHeight() {return m_zero.cy;}
+
+protected:
+ virtual void PreSubclassWindow();
+
+ virtual afx_msg void OnEnable( BOOL bEnable );
+ virtual afx_msg void OnSysColorChange();
+ virtual afx_msg void OnChange();
+ virtual afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ virtual afx_msg void OnVscroll();
+ virtual afx_msg void OnSize(UINT nType, int cx, int cy);
+ virtual afx_msg LRESULT OnSetFont(WPARAM wParam, LPARAM lParam); // Maps to WM_SETFONT
+ virtual afx_msg LRESULT OnSetText(WPARAM wParam, LPARAM lParam); // Maps to WM_SETTEXT
+ virtual afx_msg LRESULT OnLineScroll(WPARAM wParam, LPARAM lParam); // Maps to EM_LINESCROLL
+ virtual afx_msg LRESULT OnSelectLine(WPARAM wParam, LPARAM lParam);
+ DECLARE_MESSAGE_MAP()
+
+private:
+ void Prepare();
+ int CalcLineNumberWidth();
+ void UpdateTopAndBottom();
+
+ // Method to set window colour only
+ void SetWindowColour( BOOL bEnable = TRUE );
+
+// Attributes
+ BOOL m_bUseEnabledSystemColours;
+ COLORREF m_EnabledFgCol;
+ COLORREF m_EnabledBgCol;
+ BOOL m_bUseDisabledSystemColours;
+ COLORREF m_DisabledFgCol;
+ COLORREF m_DisabledBgCol;
+
+ CLineNumberStatic m_line;
+ CSize m_zero;
+ int m_maxval;
+ CString m_format;
+ int m_LineDelta; // Introduced to provide an offset to the first line number
+
+};
+
+#endif // !defined(AFX_LINENUMBEREDIT_H__CAB7A465_709C_42B8_80D0_2B0AF6D25AD4__INCLUDED_)
diff --git a/src/apps/mplayerc/MacrovisionKicker.cpp b/src/apps/mplayerc/MacrovisionKicker.cpp
new file mode 100644
index 000000000..2f3e423cb
--- /dev/null
+++ b/src/apps/mplayerc/MacrovisionKicker.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "MacrovisionKicker.h"
+
+//
+// CMacrovisionKicker
+//
+
+CMacrovisionKicker::CMacrovisionKicker(const TCHAR* pName, LPUNKNOWN pUnk)
+ : CUnknown(pName, pUnk)
+{
+}
+
+CMacrovisionKicker::~CMacrovisionKicker()
+{
+}
+
+void CMacrovisionKicker::SetInner(CComPtr<IUnknown> pUnk)
+{
+ m_pInner = pUnk;
+}
+
+STDMETHODIMP CMacrovisionKicker::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ if(riid == __uuidof(IUnknown))
+ return __super::NonDelegatingQueryInterface(riid, ppv);
+ if(riid == __uuidof(IKsPropertySet) && CComQIPtr<IKsPropertySet>(m_pInner))
+ return GetInterface((IKsPropertySet*)this, ppv);
+
+ HRESULT hr = m_pInner ? m_pInner->QueryInterface(riid, ppv) : E_NOINTERFACE;
+
+ return SUCCEEDED(hr) ? hr : __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+// IKsPropertySet
+
+STDMETHODIMP CMacrovisionKicker::Set(REFGUID PropSet, ULONG Id, LPVOID pInstanceData, ULONG InstanceLength, LPVOID pPropertyData, ULONG DataLength)
+{
+ if(CComQIPtr<IKsPropertySet> pKsPS = m_pInner)
+ {
+ if(PropSet == AM_KSPROPSETID_CopyProt && Id == AM_PROPERTY_COPY_MACROVISION
+ /*&& DataLength == 4 && *(DWORD*)pPropertyData*/)
+ {
+ TRACE(_T("Oops, no-no-no, no macrovision please\n"));
+ return S_OK;
+ }
+
+ return pKsPS->Set(PropSet, Id, pInstanceData, InstanceLength, pPropertyData, DataLength);
+ }
+
+ return E_UNEXPECTED;
+}
+
+STDMETHODIMP CMacrovisionKicker::Get(REFGUID PropSet, ULONG Id, LPVOID pInstanceData, ULONG InstanceLength, LPVOID pPropertyData, ULONG DataLength, ULONG* pBytesReturned)
+{
+ if(CComQIPtr<IKsPropertySet> pKsPS = m_pInner)
+ {
+ return pKsPS->Get(PropSet, Id, pInstanceData, InstanceLength, pPropertyData, DataLength, pBytesReturned);
+ }
+
+ return E_UNEXPECTED;
+}
+
+STDMETHODIMP CMacrovisionKicker::QuerySupported(REFGUID PropSet, ULONG Id, ULONG* pTypeSupport)
+{
+ if(CComQIPtr<IKsPropertySet> pKsPS = m_pInner)
+ {
+ return pKsPS->QuerySupported(PropSet, Id, pTypeSupport);
+ }
+
+ return E_UNEXPECTED;
+}
diff --git a/src/apps/mplayerc/MacrovisionKicker.h b/src/apps/mplayerc/MacrovisionKicker.h
new file mode 100644
index 000000000..72b465cf3
--- /dev/null
+++ b/src/apps/mplayerc/MacrovisionKicker.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+class CMacrovisionKicker
+ : public CUnknown
+ , public IKsPropertySet
+{
+ CComPtr<IUnknown> m_pInner;
+
+public:
+ CMacrovisionKicker(const TCHAR* pName, LPUNKNOWN pUnk);
+ virtual ~CMacrovisionKicker();
+
+ void SetInner(CComPtr<IUnknown> pUnk);
+
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ // IKsPropertySet
+ STDMETHODIMP Set(REFGUID PropSet, ULONG Id, LPVOID pInstanceData, ULONG InstanceLength, LPVOID pPropertyData, ULONG DataLength);
+ STDMETHODIMP Get(REFGUID PropSet, ULONG Id, LPVOID pInstanceData, ULONG InstanceLength, LPVOID pPropertyData, ULONG DataLength, ULONG* pBytesReturned);
+ STDMETHODIMP QuerySupported(REFGUID PropSet, ULONG Id, ULONG* pTypeSupport);
+};
+
diff --git a/src/apps/mplayerc/MainFrm.cpp b/src/apps/mplayerc/MainFrm.cpp
new file mode 100644
index 000000000..100b87ec9
--- /dev/null
+++ b/src/apps/mplayerc/MainFrm.cpp
@@ -0,0 +1,10265 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// MainFrm.cpp : implementation of the CMainFrame class
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+
+#include "MainFrm.h"
+
+#include <math.h>
+
+#include <afxpriv.h>
+
+#include <atlconv.h>
+#include <atlrx.h>
+#include <atlsync.h>
+
+#include "OpenFileDlg.h"
+#include "OpenDlg.h"
+#include "SaveDlg.h"
+#include "GoToDlg.h"
+#include "PnSPresetsDlg.h"
+#include "MediaTypesDlg.h"
+#include "SaveTextFileDialog.h"
+#include "SaveThumbnailsDialog.h"
+#include "FavoriteAddDlg.h"
+#include "FavoriteOrganizeDlg.h"
+#include "ConvertDlg.h"
+#include "ShaderCombineDlg.h"
+#include "FullscreenWnd.h"
+
+#include <mtype.h>
+#include <Mpconfig.h>
+#include <ks.h>
+#include <ksmedia.h>
+#include <dvdevcod.h>
+#include <dsound.h>
+
+#include <initguid.h>
+#include <uuids.h>
+#include "..\..\..\include\moreuuids.h"
+#include <Qnetwork.h>
+//#include <qedit.h> // Casimir666 : incompatible avec D3D.h
+
+#include "..\..\DSUtil\DSUtil.h"
+#include "FGManager.h"
+
+#include "textpassthrufilter.h"
+#include "..\..\filters\filters.h"
+#include "..\..\filters\PinInfoWnd.h"
+
+#include "DX7AllocatorPresenter.h"
+#include "DX9AllocatorPresenter.h"
+
+#include "..\..\subtitles\SSF.h"
+#include "ComPropertySheet.h"
+
+
+#define DEFCLIENTW 292
+#define DEFCLIENTH 200
+
+static UINT s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
+static UINT WM_NOTIFYICON = RegisterWindowMessage(TEXT("MYWM_NOTIFYICON"));
+
+#include "..\..\filters\transform\vsfilter\IDirectVobSub.h"
+
+class CSubClock : public CUnknown, public ISubClock
+{
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv)
+ {
+ return
+ QI(ISubClock)
+ CUnknown::NonDelegatingQueryInterface(riid, ppv);
+ }
+
+ REFERENCE_TIME m_rt;
+
+public:
+ CSubClock() : CUnknown(NAME("CSubClock"), NULL) {m_rt = 0;}
+
+ DECLARE_IUNKNOWN;
+
+ // ISubClock
+ STDMETHODIMP SetTime(REFERENCE_TIME rt) {m_rt = rt; return S_OK;}
+ STDMETHODIMP_(REFERENCE_TIME) GetTime() {return(m_rt);}
+};
+
+//
+
+#define SaveMediaState \
+ OAFilterState __fs = GetMediaState(); \
+ \
+ REFERENCE_TIME __rt = 0; \
+ if(m_iMediaLoadState == MLS_LOADED) __rt = GetPos(); \
+ \
+ if(__fs != State_Stopped) \
+ SendMessage(WM_COMMAND, ID_PLAY_STOP); \
+
+
+#define RestoreMediaState \
+ if(m_iMediaLoadState == MLS_LOADED) \
+ { \
+ SeekTo(__rt); \
+ \
+ if(__fs == State_Stopped) \
+ SendMessage(WM_COMMAND, ID_PLAY_STOP); \
+ else if(__fs == State_Paused) \
+ SendMessage(WM_COMMAND, ID_PLAY_PAUSE); \
+ else if(__fs == State_Running) \
+ SendMessage(WM_COMMAND, ID_PLAY_PLAY); \
+ } \
+
+/*
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+*/
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame
+
+IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
+
+BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
+ ON_WM_CREATE()
+ ON_WM_DESTROY()
+ ON_WM_CLOSE()
+
+ ON_REGISTERED_MESSAGE(s_uTaskbarRestart, OnTaskBarRestart)
+ ON_REGISTERED_MESSAGE(WM_NOTIFYICON, OnNotifyIcon)
+
+ ON_WM_SETFOCUS()
+ ON_WM_GETMINMAXINFO()
+ ON_WM_MOVE()
+ ON_WM_MOVING()
+ ON_WM_SIZE()
+ ON_WM_SIZING()
+ ON_MESSAGE_VOID(WM_DISPLAYCHANGE, OnDisplayChange)
+
+ ON_WM_SYSCOMMAND()
+ ON_WM_ACTIVATEAPP()
+ ON_MESSAGE(WM_APPCOMMAND, OnAppCommand)
+
+ ON_WM_TIMER()
+
+ ON_MESSAGE(WM_GRAPHNOTIFY, OnGraphNotify)
+ ON_MESSAGE(WM_REARRANGERENDERLESS, OnRepaintRenderLess)
+ ON_MESSAGE(WM_RESUMEFROMSTATE, OnResumeFromState)
+
+ ON_WM_LBUTTONDOWN()
+ ON_WM_LBUTTONUP()
+ ON_WM_LBUTTONDBLCLK()
+ ON_WM_MBUTTONDOWN()
+ ON_WM_MBUTTONUP()
+ ON_WM_MBUTTONDBLCLK()
+ ON_WM_RBUTTONDOWN()
+ ON_WM_RBUTTONUP()
+ ON_WM_RBUTTONDBLCLK()
+ ON_MESSAGE(WM_XBUTTONDOWN, OnXButtonDown)
+ ON_MESSAGE(WM_XBUTTONUP, OnXButtonUp)
+ ON_MESSAGE(WM_XBUTTONDBLCLK, OnXButtonDblClk)
+ ON_WM_MOUSEWHEEL()
+ ON_WM_MOUSEMOVE()
+
+ ON_WM_NCHITTEST()
+
+ ON_WM_HSCROLL()
+
+ ON_WM_INITMENU()
+ ON_WM_INITMENUPOPUP()
+
+ ON_COMMAND(ID_MENU_PLAYER_SHORT, OnMenuPlayerShort)
+ ON_COMMAND(ID_MENU_PLAYER_LONG, OnMenuPlayerLong)
+ ON_COMMAND(ID_MENU_FILTERS, OnMenuFilters)
+
+ ON_UPDATE_COMMAND_UI(IDC_PLAYERSTATUS, OnUpdatePlayerStatus)
+
+ ON_COMMAND(ID_FILE_POST_OPENMEDIA, OnFilePostOpenmedia)
+ ON_UPDATE_COMMAND_UI(ID_FILE_POST_OPENMEDIA, OnUpdateFilePostOpenmedia)
+ ON_COMMAND(ID_FILE_POST_CLOSEMEDIA, OnFilePostClosemedia)
+ ON_UPDATE_COMMAND_UI(ID_FILE_POST_CLOSEMEDIA, OnUpdateFilePostClosemedia)
+
+ ON_COMMAND(ID_BOSS, OnBossKey)
+
+ ON_COMMAND_RANGE(ID_STREAM_AUDIO_NEXT, ID_STREAM_AUDIO_PREV, OnStreamAudio)
+ ON_COMMAND_RANGE(ID_STREAM_SUB_NEXT, ID_STREAM_SUB_PREV, OnStreamSub)
+ ON_COMMAND(ID_STREAM_SUB_ONOFF, OnStreamSubOnOff)
+ ON_COMMAND_RANGE(ID_OGM_AUDIO_NEXT, ID_OGM_AUDIO_PREV, OnOgmAudio)
+ ON_COMMAND_RANGE(ID_OGM_SUB_NEXT, ID_OGM_SUB_PREV, OnOgmSub)
+ ON_COMMAND_RANGE(ID_DVD_ANGLE_NEXT, ID_DVD_ANGLE_PREV, OnDvdAngle)
+ ON_COMMAND_RANGE(ID_DVD_AUDIO_NEXT, ID_DVD_AUDIO_PREV, OnDvdAudio)
+ ON_COMMAND_RANGE(ID_DVD_SUB_NEXT, ID_DVD_SUB_PREV, OnDvdSub)
+ ON_COMMAND(ID_DVD_SUB_ONOFF, OnDvdSubOnOff)
+
+
+ ON_COMMAND(ID_FILE_OPENQUICK, OnFileOpenQuick)
+ ON_UPDATE_COMMAND_UI(ID_FILE_OPENMEDIA, OnUpdateFileOpen)
+ ON_COMMAND(ID_FILE_OPENMEDIA, OnFileOpenmedia)
+ ON_UPDATE_COMMAND_UI(ID_FILE_OPENMEDIA, OnUpdateFileOpen)
+ ON_WM_COPYDATA()
+ ON_COMMAND(ID_FILE_OPENDVD, OnFileOpendvd)
+ ON_UPDATE_COMMAND_UI(ID_FILE_OPENDVD, OnUpdateFileOpen)
+ ON_COMMAND(ID_FILE_OPENDEVICE, OnFileOpendevice)
+ ON_UPDATE_COMMAND_UI(ID_FILE_OPENDEVICE, OnUpdateFileOpen)
+ ON_COMMAND_RANGE(ID_FILE_OPEN_CD_START, ID_FILE_OPEN_CD_END, OnFileOpenCD)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_FILE_OPEN_CD_START, ID_FILE_OPEN_CD_END, OnUpdateFileOpen)
+ ON_WM_DROPFILES()
+ ON_COMMAND(ID_FILE_SAVE_COPY, OnFileSaveAs)
+ ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_COPY, OnUpdateFileSaveAs)
+ ON_COMMAND(ID_FILE_SAVE_IMAGE, OnFileSaveImage)
+ ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_IMAGE, OnUpdateFileSaveImage)
+ ON_COMMAND(ID_FILE_SAVE_IMAGE_AUTO, OnFileSaveImageAuto)
+ ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_IMAGE_AUTO, OnUpdateFileSaveImage)
+ ON_COMMAND(ID_FILE_SAVE_THUMBNAILS, OnFileSaveThumbnails)
+ ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_THUMBNAILS, OnUpdateFileSaveThumbnails)
+ ON_COMMAND(ID_FILE_CONVERT, OnFileConvert)
+ ON_UPDATE_COMMAND_UI(ID_FILE_CONVERT, OnUpdateFileConvert)
+ ON_COMMAND(ID_FILE_LOAD_SUBTITLE, OnFileLoadsubtitle)
+ ON_UPDATE_COMMAND_UI(ID_FILE_LOAD_SUBTITLE, OnUpdateFileLoadsubtitle)
+ ON_COMMAND(ID_FILE_SAVE_SUBTITLE, OnFileSavesubtitle)
+ ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_SUBTITLE, OnUpdateFileSavesubtitle)
+ ON_COMMAND(ID_FILE_ISDB_SEARCH, OnFileISDBSearch)
+ ON_UPDATE_COMMAND_UI(ID_FILE_ISDB_SEARCH, OnUpdateFileISDBSearch)
+ ON_COMMAND(ID_FILE_ISDB_UPLOAD, OnFileISDBUpload)
+ ON_UPDATE_COMMAND_UI(ID_FILE_ISDB_UPLOAD, OnUpdateFileISDBUpload)
+ ON_COMMAND(ID_FILE_ISDB_DOWNLOAD, OnFileISDBDownload)
+ ON_UPDATE_COMMAND_UI(ID_FILE_ISDB_DOWNLOAD, OnUpdateFileISDBDownload)
+ ON_COMMAND(ID_FILE_PROPERTIES, OnFileProperties)
+ ON_UPDATE_COMMAND_UI(ID_FILE_PROPERTIES, OnUpdateFileProperties)
+ ON_COMMAND(ID_FILE_CLOSEPLAYLIST, OnFileClosePlaylist)
+ ON_COMMAND(ID_FILE_CLOSEMEDIA, OnFileCloseMedia)
+ ON_UPDATE_COMMAND_UI(ID_FILE_CLOSEMEDIA, OnUpdateFileClose)
+
+ ON_COMMAND(ID_VIEW_CAPTIONMENU, OnViewCaptionmenu)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_CAPTIONMENU, OnUpdateViewCaptionmenu)
+ ON_COMMAND_RANGE(ID_VIEW_SEEKER, ID_VIEW_STATUS, OnViewControlBar)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_SEEKER, ID_VIEW_STATUS, OnUpdateViewControlBar)
+ ON_COMMAND(ID_VIEW_SUBRESYNC, OnViewSubresync)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_SUBRESYNC, OnUpdateViewSubresync)
+ ON_COMMAND(ID_VIEW_PLAYLIST, OnViewPlaylist)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_PLAYLIST, OnUpdateViewPlaylist)
+ ON_COMMAND(ID_VIEW_CAPTURE, OnViewCapture)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_CAPTURE, OnUpdateViewCapture)
+ ON_COMMAND(ID_VIEW_SHADEREDITOR, OnViewShaderEditor)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_SHADEREDITOR, OnUpdateViewShaderEditor)
+ ON_COMMAND(ID_VIEW_PRESETS_MINIMAL, OnViewMinimal)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_PRESETS_MINIMAL, OnUpdateViewMinimal)
+ ON_COMMAND(ID_VIEW_PRESETS_COMPACT, OnViewCompact)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_PRESETS_COMPACT, OnUpdateViewCompact)
+ ON_COMMAND(ID_VIEW_PRESETS_NORMAL, OnViewNormal)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_PRESETS_NORMAL, OnUpdateViewNormal)
+ ON_COMMAND(ID_VIEW_FULLSCREEN, OnViewFullscreen)
+ ON_COMMAND(ID_VIEW_FULLSCREEN_SECONDARY, OnViewFullscreenSecondary)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_FULLSCREEN, OnUpdateViewFullscreen)
+ ON_COMMAND_RANGE(ID_VIEW_ZOOM_50, ID_VIEW_ZOOM_200, OnViewZoom)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_ZOOM_50, ID_VIEW_ZOOM_200, OnUpdateViewZoom)
+ ON_COMMAND(ID_VIEW_ZOOM_AUTOFIT, OnViewZoomAutoFit)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_ZOOM_AUTOFIT, OnUpdateViewZoom)
+ ON_COMMAND_RANGE(ID_VIEW_VF_HALF, ID_VIEW_VF_FROMOUTSIDE, OnViewDefaultVideoFrame)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_VF_HALF, ID_VIEW_VF_FROMOUTSIDE, OnUpdateViewDefaultVideoFrame)
+ ON_COMMAND(ID_VIEW_VF_KEEPASPECTRATIO, OnViewKeepaspectratio)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_VF_KEEPASPECTRATIO, OnUpdateViewKeepaspectratio)
+ ON_COMMAND(ID_VIEW_VF_COMPMONDESKARDIFF, OnViewCompMonDeskARDiff)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_VF_COMPMONDESKARDIFF, OnUpdateViewCompMonDeskARDiff)
+ ON_COMMAND_RANGE(ID_VIEW_RESET, ID_PANSCAN_CENTER, OnViewPanNScan)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_RESET, ID_PANSCAN_CENTER, OnUpdateViewPanNScan)
+ ON_COMMAND_RANGE(ID_PANNSCAN_PRESETS_START, ID_PANNSCAN_PRESETS_END, OnViewPanNScanPresets)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_PANNSCAN_PRESETS_START, ID_PANNSCAN_PRESETS_END, OnUpdateViewPanNScanPresets)
+ ON_COMMAND_RANGE(ID_PANSCAN_ROTATEXP, ID_PANSCAN_ROTATEZM, OnViewRotate)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_PANSCAN_ROTATEXP, ID_PANSCAN_ROTATEZM, OnUpdateViewRotate)
+ ON_COMMAND_RANGE(ID_ASPECTRATIO_START, ID_ASPECTRATIO_END, OnViewAspectRatio)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_ASPECTRATIO_START, ID_ASPECTRATIO_END, OnUpdateViewAspectRatio)
+ ON_COMMAND(ID_ASPECTRATIO_NEXT, OnViewAspectRatioNext)
+ ON_COMMAND_RANGE(ID_ONTOP_NEVER, ID_ONTOP_WHILEPLAYING, OnViewOntop)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_ONTOP_NEVER, ID_ONTOP_WHILEPLAYING, OnUpdateViewOntop)
+ ON_COMMAND(ID_VIEW_OPTIONS, OnViewOptions)
+
+ // Casimir666
+ ON_UPDATE_COMMAND_UI(ID_VIEW_TEARING_TEST, OnUpdateViewTearingTest)
+ ON_COMMAND(ID_VIEW_TEARING_TEST, OnViewTearingTest)
+ ON_UPDATE_COMMAND_UI(ID_SHADER_TOGGLE, OnUpdateShaderToggle)
+ ON_COMMAND(ID_SHADER_TOGGLE, OnShaderToggle)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_REMAINING_TIME, OnUpdateViewRemainingTime)
+ ON_COMMAND(ID_VIEW_REMAINING_TIME, OnViewRemainingTime)
+
+ ON_COMMAND(ID_PLAY_PLAY, OnPlayPlay)
+ ON_COMMAND(ID_PLAY_PAUSE, OnPlayPause)
+ ON_COMMAND(ID_PLAY_PLAYPAUSE, OnPlayPlaypause)
+ ON_COMMAND(ID_PLAY_STOP, OnPlayStop)
+ ON_UPDATE_COMMAND_UI(ID_PLAY_PLAY, OnUpdatePlayPauseStop)
+ ON_UPDATE_COMMAND_UI(ID_PLAY_PAUSE, OnUpdatePlayPauseStop)
+ ON_UPDATE_COMMAND_UI(ID_PLAY_PLAYPAUSE, OnUpdatePlayPauseStop)
+ ON_UPDATE_COMMAND_UI(ID_PLAY_STOP, OnUpdatePlayPauseStop)
+ ON_COMMAND_RANGE(ID_PLAY_FRAMESTEP, ID_PLAY_FRAMESTEPCANCEL, OnPlayFramestep)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_FRAMESTEP, ID_PLAY_FRAMESTEPCANCEL, OnUpdatePlayFramestep)
+ ON_COMMAND_RANGE(ID_PLAY_SEEKBACKWARDSMALL, ID_PLAY_SEEKFORWARDLARGE, OnPlaySeek)
+ ON_COMMAND_RANGE(ID_PLAY_SEEKKEYBACKWARD, ID_PLAY_SEEKKEYFORWARD, OnPlaySeekKey)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_SEEKBACKWARDSMALL, ID_PLAY_SEEKFORWARDLARGE, OnUpdatePlaySeek)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_SEEKKEYBACKWARD, ID_PLAY_SEEKKEYFORWARD, OnUpdatePlaySeek)
+ ON_COMMAND(ID_PLAY_GOTO, OnPlayGoto)
+ ON_UPDATE_COMMAND_UI(ID_PLAY_GOTO, OnUpdateGoto)
+ ON_COMMAND_RANGE(ID_PLAY_DECRATE, ID_PLAY_INCRATE, OnPlayChangeRate)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_DECRATE, ID_PLAY_INCRATE, OnUpdatePlayChangeRate)
+ ON_COMMAND(ID_PLAY_RESETRATE, OnPlayResetRate)
+ ON_UPDATE_COMMAND_UI(ID_PLAY_RESETRATE, OnUpdatePlayResetRate)
+ ON_COMMAND_RANGE(ID_PLAY_INCAUDDELAY, ID_PLAY_DECAUDDELAY, OnPlayChangeAudDelay)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_INCAUDDELAY, ID_PLAY_DECAUDDELAY, OnUpdatePlayChangeAudDelay)
+ ON_COMMAND_RANGE(ID_FILTERS_SUBITEM_START, ID_FILTERS_SUBITEM_END, OnPlayFilters)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_FILTERS_SUBITEM_START, ID_FILTERS_SUBITEM_END, OnUpdatePlayFilters)
+ ON_COMMAND_RANGE(ID_SHADERS_START, ID_SHADERS_END, OnPlayShaders)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_SHADERS_START, ID_SHADERS_END, OnUpdatePlayShaders)
+ ON_COMMAND_RANGE(ID_AUDIO_SUBITEM_START, ID_AUDIO_SUBITEM_END, OnPlayAudio)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_AUDIO_SUBITEM_START, ID_AUDIO_SUBITEM_END, OnUpdatePlayAudio)
+ ON_COMMAND_RANGE(ID_SUBTITLES_SUBITEM_START, ID_SUBTITLES_SUBITEM_END, OnPlaySubtitles)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_SUBTITLES_SUBITEM_START, ID_SUBTITLES_SUBITEM_END, OnUpdatePlaySubtitles)
+ ON_COMMAND_RANGE(ID_FILTERSTREAMS_SUBITEM_START, ID_FILTERSTREAMS_SUBITEM_END, OnPlayLanguage)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_FILTERSTREAMS_SUBITEM_START, ID_FILTERSTREAMS_SUBITEM_END, OnUpdatePlayLanguage)
+ ON_COMMAND_RANGE(ID_VOLUME_UP, ID_VOLUME_MUTE, OnPlayVolume)
+ ON_COMMAND_RANGE(ID_VOLUME_BOOST_INC, ID_VOLUME_BOOST_MAX, OnPlayVolumeBoost)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_VOLUME_BOOST_INC, ID_VOLUME_BOOST_MAX, OnUpdatePlayVolumeBoost)
+ ON_COMMAND_RANGE(ID_AFTERPLAYBACK_CLOSE, ID_AFTERPLAYBACK_DONOTHING, OnAfterplayback)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_AFTERPLAYBACK_CLOSE, ID_AFTERPLAYBACK_DONOTHING, OnUpdateAfterplayback)
+
+ ON_COMMAND_RANGE(ID_NAVIGATE_SKIPBACK, ID_NAVIGATE_SKIPFORWARD, OnNavigateSkip)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_SKIPBACK, ID_NAVIGATE_SKIPFORWARD, OnUpdateNavigateSkip)
+ ON_COMMAND_RANGE(ID_NAVIGATE_SKIPBACKPLITEM, ID_NAVIGATE_SKIPFORWARDPLITEM, OnNavigateSkipPlaylistItem)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_SKIPBACKPLITEM, ID_NAVIGATE_SKIPFORWARDPLITEM, OnUpdateNavigateSkipPlaylistItem)
+ ON_COMMAND_RANGE(ID_NAVIGATE_TITLEMENU, ID_NAVIGATE_CHAPTERMENU, OnNavigateMenu)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_TITLEMENU, ID_NAVIGATE_CHAPTERMENU, OnUpdateNavigateMenu)
+ ON_COMMAND_RANGE(ID_NAVIGATE_AUDIO_SUBITEM_START, ID_NAVIGATE_AUDIO_SUBITEM_END, OnNavigateAudio)
+ ON_COMMAND_RANGE(ID_NAVIGATE_SUBP_SUBITEM_START, ID_NAVIGATE_SUBP_SUBITEM_END, OnNavigateSubpic)
+ ON_COMMAND_RANGE(ID_NAVIGATE_ANGLE_SUBITEM_START, ID_NAVIGATE_ANGLE_SUBITEM_END, OnNavigateAngle)
+ ON_COMMAND_RANGE(ID_NAVIGATE_CHAP_SUBITEM_START, ID_NAVIGATE_CHAP_SUBITEM_END, OnNavigateChapters)
+ ON_COMMAND_RANGE(ID_NAVIGATE_MENU_LEFT, ID_NAVIGATE_MENU_LEAVE, OnNavigateMenuItem)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_MENU_LEFT, ID_NAVIGATE_MENU_LEAVE, OnUpdateNavigateMenuItem)
+
+ ON_COMMAND(ID_FAVORITES_ADD, OnFavoritesAdd)
+ ON_UPDATE_COMMAND_UI(ID_FAVORITES_ADD, OnUpdateFavoritesAdd)
+ ON_COMMAND(ID_FAVORITES_ORGANIZE, OnFavoritesOrganize)
+ ON_UPDATE_COMMAND_UI(ID_FAVORITES_ORGANIZE, OnUpdateFavoritesOrganize)
+ ON_COMMAND_RANGE(ID_FAVORITES_FILE_START, ID_FAVORITES_FILE_END, OnFavoritesFile)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_FAVORITES_FILE_START, ID_FAVORITES_FILE_END, OnUpdateFavoritesFile)
+ ON_COMMAND_RANGE(ID_FAVORITES_DVD_START, ID_FAVORITES_DVD_END, OnFavoritesDVD)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_FAVORITES_DVD_START, ID_FAVORITES_DVD_END, OnUpdateFavoritesDVD)
+ ON_COMMAND_RANGE(ID_FAVORITES_DEVICE_START, ID_FAVORITES_DEVICE_END, OnFavoritesDevice)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_FAVORITES_DEVICE_START, ID_FAVORITES_DEVICE_END, OnUpdateFavoritesDevice)
+
+ ON_COMMAND(ID_HELP_HOMEPAGE, OnHelpHomepage)
+ ON_COMMAND(ID_HELP_DOCUMENTATION, OnHelpDocumentation)
+ ON_COMMAND(ID_HELP_DONATE, OnHelpDonate)
+
+ END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame construction/destruction
+
+#pragma warning(disable : 4355)
+
+CMainFrame::CMainFrame() :
+ m_dwRegister(0),
+ m_iMediaLoadState(MLS_CLOSED),
+ m_iPlaybackMode(PM_NONE),
+ m_iSpeedLevel(0),
+ m_rtDurationOverride(-1),
+ m_fFullScreen(false),
+ m_fHideCursor(false),
+ m_lastMouseMove(-1, -1),
+ m_pLastBar(NULL),
+ m_nLoops(0),
+ m_iSubtitleSel(-1),
+ m_ZoomX(1), m_ZoomY(1), m_PosX(0.5), m_PosY(0.5),
+ m_AngleX(0), m_AngleY(0), m_AngleZ(0),
+ m_fCustomGraph(false),
+ m_fRealMediaGraph(false), m_fShockwaveGraph(false), m_fQuicktimeGraph(false),
+ m_fFrameSteppingActive(false),
+ m_fEndOfStream(false),
+ m_fCapturing(false),
+ m_fLiveWM(false),
+ m_fOpeningAborted(false),
+ m_fBuffering(false),
+ m_fileDropTarget(this),
+ m_fTrayIcon(false),
+ m_pFullscreenWnd(NULL),
+ m_pVideoWnd(NULL),
+ m_bD3DFullscreenMode(false),
+ m_bRemainingTime(false)
+{
+}
+
+CMainFrame::~CMainFrame()
+{
+// m_owner.DestroyWindow();
+}
+
+int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if(__super::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ m_popup.LoadMenu(IDR_POPUP);
+ m_popupmain.LoadMenu(IDR_POPUPMAIN);
+
+ GetMenu()->ModifyMenu(ID_FAVORITES, MF_BYCOMMAND|MF_STRING, IDR_MAINFRAME, ResStr(IDS_FAVORITES_POPUP));
+
+ // create a view to occupy the client area of the frame
+ if(!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
+ CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
+ {
+ TRACE0("Failed to create view window\n");
+ return -1;
+ }
+
+ // static bars
+
+ if(!m_wndStatusBar.Create(this)
+ || !m_wndStatsBar.Create(this)
+ || !m_wndInfoBar.Create(this)
+ || !m_wndToolBar.Create(this)
+ || !m_wndSeekBar.Create(this))
+ {
+ TRACE0("Failed to create all control bars\n");
+ return -1; // fail to create
+ }
+
+ m_pFullscreenWnd = new CFullscreenWnd(this);
+
+ m_bars.AddTail(&m_wndSeekBar);
+ m_bars.AddTail(&m_wndToolBar);
+ m_bars.AddTail(&m_wndInfoBar);
+ m_bars.AddTail(&m_wndStatsBar);
+ m_bars.AddTail(&m_wndStatusBar);
+
+ m_wndSeekBar.Enable(false);
+
+ // dockable bars
+
+ EnableDocking(CBRS_ALIGN_ANY);
+
+ m_dockingbars.RemoveAll();
+
+ m_wndSubresyncBar.Create(this, &m_csSubLock);
+ m_wndSubresyncBar.SetBarStyle(m_wndSubresyncBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
+ m_wndSubresyncBar.EnableDocking(CBRS_ALIGN_ANY);
+ m_wndSubresyncBar.SetHeight(200);
+ LoadControlBar(&m_wndSubresyncBar, AFX_IDW_DOCKBAR_TOP);
+
+ m_wndPlaylistBar.Create(this);
+ m_wndPlaylistBar.SetBarStyle(m_wndPlaylistBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
+ m_wndPlaylistBar.EnableDocking(CBRS_ALIGN_ANY);
+ m_wndPlaylistBar.SetHeight(100);
+ LoadControlBar(&m_wndPlaylistBar, AFX_IDW_DOCKBAR_BOTTOM);
+ m_wndPlaylistBar.LoadPlaylist();
+
+ m_wndCaptureBar.Create(this);
+ m_wndCaptureBar.SetBarStyle(m_wndCaptureBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
+ m_wndCaptureBar.EnableDocking(CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT);
+ LoadControlBar(&m_wndCaptureBar, AFX_IDW_DOCKBAR_LEFT);
+
+ m_wndShaderEditorBar.Create(this);
+ m_wndShaderEditorBar.SetBarStyle(m_wndShaderEditorBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
+ m_wndShaderEditorBar.EnableDocking(CBRS_ALIGN_ANY);
+ LoadControlBar(&m_wndShaderEditorBar, AFX_IDW_DOCKBAR_TOP);
+
+ m_fileDropTarget.Register(this);
+
+ GetDesktopWindow()->GetWindowRect(&m_rcDesktop);
+
+ AppSettings& s = AfxGetAppSettings();
+
+ ShowControls(s.nCS);
+
+ SetAlwaysOnTop(s.iOnTop);
+
+ ShowTrayIcon(s.fTrayIcon);
+
+ SetFocus();
+
+ m_pGraphThread = (CGraphThread*)AfxBeginThread(RUNTIME_CLASS(CGraphThread));
+
+ if(m_pGraphThread)
+ m_pGraphThread->SetMainFrame(this);
+
+ if(s.fEnableWebServer)
+ StartWebServer(s.nWebServerPort);
+
+ // Casimir666 : rechargement des Shaders
+ CString strList = AfxGetAppSettings().strShaderList;
+ CString strRes;
+ int curPos= 0;
+
+ strRes = strList.Tokenize (_T("|"), curPos);
+ while (strRes != _T(""))
+ {
+ m_shaderlabels.AddTail (strRes);
+ strRes = strList.Tokenize(_T("|"),curPos);
+ };
+
+ return 0;
+}
+
+void CMainFrame::OnDestroy()
+{
+ ShowTrayIcon(false);
+
+ m_fileDropTarget.Revoke();
+
+ if(m_pGraphThread)
+ {
+ CAMEvent e;
+ m_pGraphThread->PostThreadMessage(CGraphThread::TM_EXIT, 0, (LPARAM)&e);
+ if(!e.Wait(5000))
+ {
+ TRACE(_T("ERROR: Must call TerminateThread() on CMainFrame::m_pGraphThread->m_hThread\n"));
+ TerminateThread(m_pGraphThread->m_hThread, -1);
+ }
+ }
+
+ __super::OnDestroy();
+}
+
+void CMainFrame::OnClose()
+{
+ // Casimir666 : sauvegarde de la liste des shaders
+ POSITION pos;
+ CString strList = "";
+
+ pos = m_shaderlabels.GetHeadPosition();
+ while(pos)
+ {
+ strList += m_shaderlabels.GetAt (pos) + "|";
+ m_dockingbars.GetNext(pos);
+ }
+ AfxGetAppSettings().strShaderList = strList;
+
+ m_wndPlaylistBar.SavePlaylist();
+
+ SaveControlBars();
+
+ ShowWindow(SW_HIDE);
+
+ CloseMedia();
+
+ __super::OnClose();
+}
+
+DROPEFFECT CMainFrame::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
+{
+ return DROPEFFECT_NONE;
+}
+DROPEFFECT CMainFrame::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
+{
+ UINT CF_URL = RegisterClipboardFormat(_T("UniformResourceLocator"));
+ return pDataObject->IsDataAvailable(CF_URL) ? DROPEFFECT_COPY : DROPEFFECT_NONE;
+}
+BOOL CMainFrame::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
+{
+ UINT CF_URL = RegisterClipboardFormat(_T("UniformResourceLocator"));
+
+ BOOL bResult = FALSE;
+
+ if(pDataObject->IsDataAvailable(CF_URL))
+ {
+ FORMATETC fmt = {CF_URL, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ if(HGLOBAL hGlobal = pDataObject->GetGlobalData(CF_URL, &fmt))
+ {
+ LPCSTR pText = (LPCSTR)GlobalLock(hGlobal);
+ if(AfxIsValidString(pText))
+ {
+ CStringA url(pText);
+
+ SetForegroundWindow();
+
+ CAtlList<CString> sl;
+ sl.AddTail(CString(url));
+
+ if(m_wndPlaylistBar.IsWindowVisible())
+ {
+ m_wndPlaylistBar.Append(sl, true);
+ }
+ else
+ {
+ m_wndPlaylistBar.Open(sl, true);
+ OpenCurPlaylistItem();
+ }
+
+ GlobalUnlock(hGlobal);
+ bResult = TRUE;
+ }
+ }
+ }
+
+ return bResult;
+}
+DROPEFFECT CMainFrame::OnDropEx(COleDataObject* pDataObject, DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point)
+{
+ return (DROPEFFECT)-1;
+}
+void CMainFrame::OnDragLeave()
+{
+}
+DROPEFFECT CMainFrame::OnDragScroll(DWORD dwKeyState, CPoint point)
+{
+ return DROPEFFECT_NONE;
+}
+
+void CMainFrame::LoadControlBar(CControlBar* pBar, UINT defDockBarID)
+{
+ if(!pBar) return;
+
+ CString str;
+ pBar->GetWindowText(str);
+ if(str.IsEmpty()) return;
+ CString section = _T("ToolBars\\") + str;
+
+ CWinApp* pApp = AfxGetApp();
+
+ UINT nID = pApp->GetProfileInt(section, _T("DockState"), defDockBarID);
+
+ if(nID != AFX_IDW_DOCKBAR_FLOAT)
+ {
+ DockControlBar(pBar, nID);
+ }
+
+ pBar->ShowWindow(
+ pApp->GetProfileInt(section, _T("Visible"), FALSE)
+ && pBar != &m_wndSubresyncBar
+ && pBar != &m_wndCaptureBar
+ && pBar != &m_wndShaderEditorBar
+ ? SW_SHOW
+ : SW_HIDE);
+
+ if(CSizingControlBar* pSCB = dynamic_cast<CSizingControlBar*>(pBar))
+ {
+ pSCB->LoadState(section + _T("\\State"));
+ m_dockingbars.AddTail(pSCB);
+ }
+}
+
+void CMainFrame::RestoreFloatingControlBars()
+{
+ CWinApp* pApp = AfxGetApp();
+
+ CRect r;
+ GetWindowRect(r);
+
+ POSITION pos = m_dockingbars.GetHeadPosition();
+ while(pos)
+ {
+ CSizingControlBar* pBar = m_dockingbars.GetNext(pos);
+
+ CString str;
+ pBar->GetWindowText(str);
+ if(str.IsEmpty()) return;
+ CString section = _T("ToolBars\\") + str;
+
+ if(pApp->GetProfileInt(section, _T("DockState"), ~AFX_IDW_DOCKBAR_FLOAT) == AFX_IDW_DOCKBAR_FLOAT)
+ {
+ CPoint p;
+ p.x = pApp->GetProfileInt(section, _T("DockPosX"), r.right);
+ p.y = pApp->GetProfileInt(section, _T("DockPosY"), r.top);
+ if(p.x < m_rcDesktop.left) p.x = m_rcDesktop.left;
+ if(p.y < m_rcDesktop.top) p.y = m_rcDesktop.top;
+ if(p.x >= m_rcDesktop.right) p.x = m_rcDesktop.right-1;
+ if(p.y >= m_rcDesktop.bottom) p.y = m_rcDesktop.bottom-1;
+ FloatControlBar(pBar, p);
+ }
+ }
+}
+
+void CMainFrame::SaveControlBars()
+{
+ CWinApp* pApp = AfxGetApp();
+
+ POSITION pos = m_dockingbars.GetHeadPosition();
+ while(pos)
+ {
+ CSizingControlBar* pBar = m_dockingbars.GetNext(pos);
+
+ CString str;
+ pBar->GetWindowText(str);
+ if(str.IsEmpty()) return;
+ CString section = _T("ToolBars\\") + str;
+
+ pApp->WriteProfileInt(section, _T("Visible"), pBar->IsWindowVisible());
+
+ if(CSizingControlBar* pSCB = dynamic_cast<CSizingControlBar*>(pBar))
+ {
+ pSCB->SaveState(section + _T("\\State"));
+ }
+
+ UINT nID = pBar->GetParent()->GetDlgCtrlID();
+
+ if(nID == AFX_IDW_DOCKBAR_FLOAT)
+ {
+ CRect r;
+ pBar->GetParent()->GetParent()->GetWindowRect(r);
+ pApp->WriteProfileInt(section, _T("DockPosX"), r.left);
+ pApp->WriteProfileInt(section, _T("DockPosY"), r.top);
+ }
+
+ pApp->WriteProfileInt(section, _T("DockState"), nID);
+ }
+}
+
+LRESULT CMainFrame::OnTaskBarRestart(WPARAM, LPARAM)
+{
+ m_fTrayIcon = false;
+ ShowTrayIcon(AfxGetAppSettings().fTrayIcon);
+
+ return 0;
+}
+
+LRESULT CMainFrame::OnNotifyIcon(WPARAM wParam, LPARAM lParam)
+{
+ if((UINT)wParam != IDR_MAINFRAME)
+ return -1;
+
+ switch((UINT)lParam)
+ {
+ case WM_LBUTTONDOWN:
+ ShowWindow(SW_SHOW);
+ MoveVideoWindow();
+ SetForegroundWindow();
+ break;
+
+ case WM_LBUTTONDBLCLK:
+ PostMessage(WM_COMMAND, ID_FILE_OPENMEDIA);
+ break;
+
+ case WM_RBUTTONDOWN:
+ {
+ POINT p;
+ GetCursorPos(&p);
+ SetForegroundWindow();
+ m_popupmain.GetSubMenu(0)->TrackPopupMenu(TPM_RIGHTBUTTON|TPM_NOANIMATION, p.x, p.y, this);
+ PostMessage(WM_NULL);
+ break;
+ }
+
+ case WM_MOUSEMOVE:
+ {
+ CString str;
+ GetWindowText(str);
+ SetTrayTip(str);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+void CMainFrame::ShowTrayIcon(bool fShow)
+{
+ BOOL bWasVisible = ShowWindow(SW_HIDE);
+
+ if(fShow)
+ {
+ if(!m_fTrayIcon)
+ {
+ NOTIFYICONDATA tnid;
+ tnid.cbSize = sizeof(NOTIFYICONDATA);
+ tnid.hWnd = m_hWnd;
+ tnid.uID = IDR_MAINFRAME;
+// tnid.hIcon = (HICON)LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
+ tnid.hIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+ tnid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
+ tnid.uCallbackMessage = WM_NOTIFYICON;
+ lstrcpyn(tnid.szTip, TEXT("Media Player Classic"), sizeof(tnid.szTip));
+ Shell_NotifyIcon(NIM_ADD, &tnid);
+
+ m_fTrayIcon = true;
+ }
+ }
+ else
+ {
+ if(m_fTrayIcon)
+ {
+ NOTIFYICONDATA tnid;
+ tnid.cbSize = sizeof(NOTIFYICONDATA);
+ tnid.hWnd = m_hWnd;
+ tnid.uID = IDR_MAINFRAME;
+ Shell_NotifyIcon(NIM_DELETE, &tnid);
+
+ m_fTrayIcon = false;
+ }
+ }
+
+ if(bWasVisible)
+ ShowWindow(SW_SHOW);
+}
+
+void CMainFrame::SetTrayTip(CString str)
+{
+ NOTIFYICONDATA tnid;
+ tnid.cbSize = sizeof(NOTIFYICONDATA);
+ tnid.hWnd = m_hWnd;
+ tnid.uID = IDR_MAINFRAME;
+ tnid.uFlags = NIF_TIP;
+ lstrcpyn(tnid.szTip, str, sizeof(tnid.szTip));
+ Shell_NotifyIcon(NIM_MODIFY, &tnid);
+}
+
+BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if(!__super::PreCreateWindow(cs))
+ return FALSE;
+
+ cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
+ cs.lpszClass = MPC_WND_CLASS_NAME; //AfxRegisterWndClass(0);
+
+ return TRUE;
+}
+
+BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
+{
+ if(pMsg->message == WM_KEYDOWN)
+ {
+/* if(m_fShockwaveGraph
+ && (pMsg->wParam == VK_LEFT || pMsg->wParam == VK_RIGHT
+ || pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN))
+ return FALSE;
+*/
+ if(pMsg->wParam == VK_ESCAPE && m_iMediaLoadState == MLS_LOADED && m_fFullScreen)
+ {
+ OnViewFullscreen();
+ PostMessage(WM_COMMAND, ID_PLAY_PAUSE);
+ return TRUE;
+ }
+ else if(pMsg->wParam == VK_ESCAPE && (IsCaptionMenuHidden()))
+ {
+ PostMessage(WM_COMMAND, ID_VIEW_CAPTIONMENU);
+ return TRUE;
+ }
+ else if(pMsg->wParam == VK_LEFT && pAMTuner)
+ {
+ PostMessage(WM_COMMAND, ID_NAVIGATE_SKIPBACK);
+ return TRUE;
+ }
+ else if(pMsg->wParam == VK_RIGHT && pAMTuner)
+ {
+ PostMessage(WM_COMMAND, ID_NAVIGATE_SKIPFORWARD);
+ return TRUE;
+ }
+ }
+
+ return __super::PreTranslateMessage(pMsg);
+}
+
+void CMainFrame::RecalcLayout(BOOL bNotify)
+{
+ __super::RecalcLayout(bNotify);
+
+ CRect r;
+ GetWindowRect(&r);
+ MINMAXINFO mmi;
+ memset(&mmi, 0, sizeof(mmi));
+ SendMessage(WM_GETMINMAXINFO, 0, (LPARAM)&mmi);
+ r |= CRect(r.TopLeft(), CSize(r.Width(), mmi.ptMinTrackSize.y));
+ MoveWindow(&r);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame diagnostics
+
+#ifdef _DEBUG
+void CMainFrame::AssertValid() const
+{
+ __super::AssertValid();
+}
+
+void CMainFrame::Dump(CDumpContext& dc) const
+{
+ __super::Dump(dc);
+}
+
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame message handlers
+void CMainFrame::OnSetFocus(CWnd* pOldWnd)
+{
+ SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
+
+ // forward focus to the view window
+ if(IsWindow(m_wndView.m_hWnd))
+ m_wndView.SetFocus();
+}
+
+BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
+{
+ // let the view have first crack at the command
+ if(m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
+ return TRUE;
+
+ POSITION pos = m_bars.GetHeadPosition();
+ while(pos)
+ {
+ if(m_bars.GetNext(pos)->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
+ return TRUE;
+ }
+
+ pos = m_dockingbars.GetHeadPosition();
+ while(pos)
+ {
+ if(m_dockingbars.GetNext(pos)->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
+ return TRUE;
+ }
+
+ // otherwise, do default handling
+ return __super::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
+}
+
+void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
+{
+ DWORD style = GetStyle();
+
+ MENUBARINFO mbi;
+ memset(&mbi, 0, sizeof(mbi));
+ mbi.cbSize = sizeof(mbi);
+ ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
+
+ lpMMI->ptMinTrackSize.x = 0;
+ if(!IsCaptionMenuHidden())
+ {
+ lpMMI->ptMinTrackSize.x = 10;
+ CRect r;
+ for(int i = 0; ::GetMenuItemRect(m_hWnd, mbi.hMenu, i, &r); i++)
+ lpMMI->ptMinTrackSize.x += r.Width();
+ lpMMI->ptMinTrackSize.x = max(DEFCLIENTW, lpMMI->ptMinTrackSize.x);
+ }
+ if(style&WS_THICKFRAME) lpMMI->ptMinTrackSize.x += GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2;
+
+ memset(&mbi, 0, sizeof(mbi));
+ mbi.cbSize = sizeof(mbi);
+ ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
+
+ lpMMI->ptMinTrackSize.y = 0;
+ if(style&WS_CAPTION) lpMMI->ptMinTrackSize.y += GetSystemMetrics(SM_CYCAPTION);
+ if(style&WS_THICKFRAME) lpMMI->ptMinTrackSize.y += GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2;
+ lpMMI->ptMinTrackSize.y += (mbi.rcBar.bottom - mbi.rcBar.top);
+ if(!AfxGetAppSettings().fHideCaptionMenu) lpMMI->ptMinTrackSize.y += 3;
+
+ POSITION pos = m_bars.GetHeadPosition();
+ while(pos)
+ {
+ CControlBar* pCB = m_bars.GetNext(pos);
+ if(!IsWindow(pCB->m_hWnd) || !pCB->IsVisible()) continue;
+
+ lpMMI->ptMinTrackSize.y += pCB->CalcFixedLayout(TRUE, TRUE).cy;
+ }
+
+ pos = m_dockingbars.GetHeadPosition();
+ while(pos)
+ {
+ CSizingControlBar* pCB = m_dockingbars.GetNext(pos);
+ if(IsWindow(pCB->m_hWnd) && pCB->IsWindowVisible() && !pCB->IsFloating())
+ lpMMI->ptMinTrackSize.y += pCB->CalcFixedLayout(TRUE, TRUE).cy-2;
+ }
+
+ __super::OnGetMinMaxInfo(lpMMI);
+}
+
+void CMainFrame::OnMove(int x, int y)
+{
+ __super::OnMove(x, y);
+
+ MoveVideoWindow();
+
+ WINDOWPLACEMENT wp;
+ GetWindowPlacement(&wp);
+ if(!m_fFullScreen && wp.flags != WPF_RESTORETOMAXIMIZED && wp.showCmd != SW_SHOWMINIMIZED)
+ GetWindowRect(AfxGetAppSettings().rcLastWindowPos);
+}
+
+void CMainFrame::OnMoving(UINT fwSide, LPRECT pRect)
+{
+ __super::OnMoving(fwSide, pRect);
+
+ if(AfxGetAppSettings().fSnapToDesktopEdges)
+ {
+ const CPoint threshold(3, 3);
+
+ CRect r0 = m_rcDesktop;
+ CRect r1 = r0 + threshold;
+ CRect r2 = r0 - threshold;
+
+ RECT& wr = *pRect;
+ CSize ws = CRect(wr).Size();
+
+ if(wr.left < r1.left && wr.left > r2.left)
+ wr.right = (wr.left = r0.left) + ws.cx;
+
+ if(wr.top < r1.top && wr.top > r2.top)
+ wr.bottom = (wr.top = r0.top) + ws.cy;
+
+ if(wr.right < r1.right && wr.right > r2.right)
+ wr.left = (wr.right = r0.right) - ws.cx;
+
+ if(wr.bottom < r1.bottom && wr.bottom > r2.bottom)
+ wr.top = (wr.bottom = r0.bottom) - ws.cy;
+ }
+}
+
+void CMainFrame::OnSize(UINT nType, int cx, int cy)
+{
+ __super::OnSize(nType, cx, cy);
+
+ m_OSD.OnSize (nType, cx, cy);
+
+ if(nType == SIZE_RESTORED && m_fTrayIcon)
+ {
+ ShowWindow(SW_SHOW);
+ }
+
+ if(!m_fFullScreen)
+ {
+ AppSettings& s = AfxGetAppSettings();
+ if(nType != SIZE_MAXIMIZED && nType != SIZE_MINIMIZED)
+ GetWindowRect(s.rcLastWindowPos);
+ s.lastWindowType = nType;
+ }
+}
+
+void CMainFrame::OnSizing(UINT fwSide, LPRECT pRect)
+{
+ __super::OnSizing(fwSide, pRect);
+
+ AppSettings& s = AfxGetAppSettings();
+
+ bool fCtrl = !!(GetAsyncKeyState(VK_CONTROL)&0x80000000);
+
+ if(m_iMediaLoadState != MLS_LOADED || m_fFullScreen
+ || s.iDefaultVideoSize == DVS_STRETCH
+ || (fCtrl ^ s.fFreeWindowResizing))
+ return;
+
+ CSize wsize(pRect->right - pRect->left, pRect->bottom - pRect->top);
+ CSize vsize = GetVideoSize();
+ CSize fsize(0, 0);
+
+ if(!vsize.cx || !vsize.cy)
+ return;
+
+ // TODO
+ {
+ DWORD style = GetStyle();
+
+ MENUBARINFO mbi;
+ memset(&mbi, 0, sizeof(mbi));
+ mbi.cbSize = sizeof(mbi);
+ ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
+
+ fsize.cx += GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2;
+
+ if(style&WS_CAPTION) fsize.cy += GetSystemMetrics(SM_CYCAPTION);
+ if(style&WS_THICKFRAME) fsize.cy += GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2;
+ fsize.cy += mbi.rcBar.bottom - mbi.rcBar.top;
+ if(!AfxGetAppSettings().fHideCaptionMenu) fsize.cy += 3;
+
+ POSITION pos = m_bars.GetHeadPosition();
+ while(pos)
+ {
+ CControlBar* pCB = m_bars.GetNext(pos);
+ if(IsWindow(pCB->m_hWnd) && pCB->IsVisible())
+ fsize.cy += pCB->CalcFixedLayout(TRUE, TRUE).cy;
+ }
+
+ pos = m_dockingbars.GetHeadPosition();
+ while(pos)
+ {
+ CSizingControlBar* pCB = m_dockingbars.GetNext(pos);
+
+ if(IsWindow(pCB->m_hWnd) && pCB->IsWindowVisible())
+ {
+ if(pCB->IsHorzDocked()) fsize.cy += pCB->CalcFixedLayout(TRUE, TRUE).cy-2;
+ else if(pCB->IsVertDocked()) fsize.cx += pCB->CalcFixedLayout(TRUE, FALSE).cx;
+ }
+ }
+ }
+
+ wsize -= fsize;
+
+ bool fWider = wsize.cy < wsize.cx;
+
+ wsize.SetSize(
+ wsize.cy * vsize.cx / vsize.cy,
+ wsize.cx * vsize.cy / vsize.cx);
+
+ wsize += fsize;
+
+ if(fwSide == WMSZ_TOP || fwSide == WMSZ_BOTTOM || !fWider && (fwSide == WMSZ_TOPRIGHT || fwSide == WMSZ_BOTTOMRIGHT))
+ {
+ pRect->right = pRect->left + wsize.cx;
+ }
+ else if(fwSide == WMSZ_LEFT || fwSide == WMSZ_RIGHT || fWider && (fwSide == WMSZ_BOTTOMLEFT || fwSide == WMSZ_BOTTOMRIGHT))
+ {
+ pRect->bottom = pRect->top + wsize.cy;
+ }
+ else if(!fWider && (fwSide == WMSZ_TOPLEFT || fwSide == WMSZ_BOTTOMLEFT))
+ {
+ pRect->left = pRect->right - wsize.cx;
+ }
+ else if(fWider && (fwSide == WMSZ_TOPLEFT || fwSide == WMSZ_TOPRIGHT))
+ {
+ pRect->top = pRect->bottom - wsize.cy;
+ }
+}
+
+void CMainFrame::OnDisplayChange() // untested, not sure if it's working...
+{
+ TRACE(_T("*** CMainFrame::OnDisplayChange()\n"));
+/*
+ if(m_iMediaLoadState == MLS_LOADED && m_pCAP)
+ m_pCAP->OnDisplayChange();
+*/
+
+ GetDesktopWindow()->GetWindowRect(&m_rcDesktop);
+}
+
+#include <psapi.h>
+
+void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
+{
+ if((nID & 0xFFF0) == SC_SCREENSAVE)
+ {
+ TRACE(_T("SC_SCREENSAVE, nID = %d, lParam = %d\n"), nID, lParam);
+ }
+ else if((nID & 0xFFF0) == SC_MINIMIZE && m_fTrayIcon)
+ {
+ ShowWindow(SW_HIDE);
+ return;
+ }
+
+ __super::OnSysCommand(nID, lParam);
+}
+
+void CMainFrame::OnActivateApp(BOOL bActive, DWORD dwThreadID)
+{
+ __super::OnActivateApp(bActive, dwThreadID);
+
+ MONITORINFO mi;
+ mi.cbSize = sizeof(MONITORINFO);
+ GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
+
+ if(!bActive && (mi.dwFlags&MONITORINFOF_PRIMARY) && m_fFullScreen && m_iMediaLoadState == MLS_LOADED)
+ {
+ bool fExitFullscreen = true;
+
+ if(CWnd* pWnd = GetForegroundWindow())
+ {
+ HMONITOR hMonitor1 = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
+ HMONITOR hMonitor2 = MonitorFromWindow(pWnd->m_hWnd, MONITOR_DEFAULTTONEAREST);
+ if(hMonitor1 && hMonitor2 && hMonitor1 != hMonitor2) fExitFullscreen = false;
+
+ CString title;
+ pWnd->GetWindowText(title);
+
+ CString module;
+
+ if(GetVersion()&0x80000000)
+ {
+ module.ReleaseBufferSetLength(GetWindowModuleFileName(pWnd->m_hWnd, module.GetBuffer(MAX_PATH), MAX_PATH));
+ }
+ else
+ {
+ DWORD pid;
+ GetWindowThreadProcessId(pWnd->m_hWnd, &pid);
+
+ if(HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid))
+ {
+ HMODULE hMod;
+ DWORD cbNeeded;
+
+ if(EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
+ {
+ module.ReleaseBufferSetLength(GetModuleFileNameEx(hProcess, hMod, module.GetBuffer(MAX_PATH), MAX_PATH));
+ }
+
+ CloseHandle(hProcess);
+ }
+ }
+
+ CPath p(module);
+ p.StripPath();
+ module = (LPCTSTR)p;
+ module.MakeLower();
+
+ CString str;
+ str.Format(_T("Focus lost to: %s - %s"), module, title);
+ SendStatusMessage(str, 5000);
+ }
+
+ if(fExitFullscreen) OnViewFullscreen();
+ }
+}
+
+LRESULT CMainFrame::OnAppCommand(WPARAM wParam, LPARAM lParam)
+{
+ UINT cmd = GET_APPCOMMAND_LPARAM(lParam);
+ UINT uDevice = GET_DEVICE_LPARAM(lParam);
+ UINT dwKeys = GET_KEYSTATE_LPARAM(lParam);
+
+ if(uDevice != FAPPCOMMAND_OEM)
+ {
+ AppSettings& s = AfxGetAppSettings();
+
+ BOOL fRet = FALSE;
+
+ POSITION pos = s.wmcmds.GetHeadPosition();
+ while(pos)
+ {
+ wmcmd& wc = s.wmcmds.GetNext(pos);
+ if(wc.appcmd == cmd && TRUE == SendMessage(WM_COMMAND, wc.cmd))
+ fRet = TRUE;
+ }
+
+ if(fRet) return TRUE;
+ }
+
+ return Default();
+}
+
+void CMainFrame::OnTimer(UINT nIDEvent)
+{
+ if(nIDEvent == TIMER_STREAMPOSPOLLER && m_iMediaLoadState == MLS_LOADED)
+ {
+ REFERENCE_TIME rtNow = 0, rtDur = 0;
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ pMS->GetCurrentPosition(&rtNow);
+ pMS->GetDuration(&rtDur);
+
+ FILE_POSITION* FilePosition = AfxGetAppSettings().CurrentFilePosition();
+ if (FilePosition) FilePosition->llPosition = rtNow;
+
+ if(m_rtDurationOverride >= 0) rtDur = m_rtDurationOverride;
+
+ m_wndSeekBar.Enable(rtDur > 0);
+ m_wndSeekBar.SetRange(0, rtDur);
+ m_wndSeekBar.SetPos(rtNow);
+ m_OSD.SetRange (0, rtDur);
+ m_OSD.SetPos (rtNow);
+ }
+ else if(m_iPlaybackMode == PM_CAPTURE)
+ {
+ if(m_fCapturing && m_wndCaptureBar.m_capdlg.m_pMux)
+ {
+ CComQIPtr<IMediaSeeking> pMuxMS = m_wndCaptureBar.m_capdlg.m_pMux;
+ if(!pMuxMS || FAILED(pMuxMS->GetCurrentPosition(&rtNow))) rtNow = 0;
+ }
+
+ if(m_rtDurationOverride >= 0) rtDur = m_rtDurationOverride;
+
+ m_wndSeekBar.Enable(false);
+ m_wndSeekBar.SetRange(0, rtDur);
+ m_wndSeekBar.SetPos(rtNow);
+ m_OSD.SetRange (0, rtDur);
+ m_OSD.SetPos (rtNow);
+/*
+ if(m_fCapturing)
+ {
+ if(rtNow > 10000i64*1000*60*60*3)
+ {
+ m_wndCaptureBar.m_capdlg.OnRecord();
+ }
+ }
+*/
+ }
+
+ if(m_pCAP && m_iPlaybackMode != PM_FILE) m_pCAP->SetTime(/*rtNow*/m_wndSeekBar.GetPos());
+ }
+ else if(nIDEvent == TIMER_STREAMPOSPOLLER2 && m_iMediaLoadState == MLS_LOADED)
+ {
+ __int64 start, stop, pos;
+ m_wndSeekBar.GetRange(start, stop);
+ pos = m_wndSeekBar.GetPosReal();
+
+ GUID tf;
+ pMS->GetTimeFormat(&tf);
+
+ if(m_iPlaybackMode == PM_CAPTURE && !m_fCapturing)
+ {
+ CString str = _T("Live");
+
+ long lChannel = 0, lVivSub = 0, lAudSub = 0;
+ if(pAMTuner
+ && m_wndCaptureBar.m_capdlg.IsTunerActive()
+ && SUCCEEDED(pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub)))
+ {
+ CString ch;
+ ch.Format(_T(" (ch%d)"), lChannel);
+ str += ch;
+ }
+
+ m_wndStatusBar.SetStatusTimer(str);
+ }
+ else
+ {
+ m_wndStatusBar.SetStatusTimer(pos, stop, !!m_wndSubresyncBar.IsWindowVisible(), &tf);
+ if (m_bRemainingTime) m_OSD.DisplayMessage(OSD_TOPLEFT, m_wndStatusBar.GetStatusTimer());
+
+ }
+
+ m_wndSubresyncBar.SetTime(pos);
+
+ if(m_pCAP && GetMediaState() == State_Paused) m_pCAP->Paint(true);
+ }
+ else if(nIDEvent == TIMER_FULLSCREENCONTROLBARHIDER)
+ {
+ CPoint p;
+ GetCursorPos(&p);
+
+ CRect r;
+ GetWindowRect(r);
+ bool fCursorOutside = !r.PtInRect(p);
+
+ CWnd* pWnd = WindowFromPoint(p);
+ if(pWnd && (m_wndView == *pWnd || m_wndView.IsChild(pWnd) || fCursorOutside))
+ {
+ if(AfxGetAppSettings().nShowBarsWhenFullScreenTimeOut >= 0)
+ ShowControls(CS_NONE, false);
+ }
+ }
+ else if(nIDEvent == TIMER_FULLSCREENMOUSEHIDER)
+ {
+ CPoint p;
+ GetCursorPos(&p);
+
+ CRect r;
+ GetWindowRect(r);
+ bool fCursorOutside = !r.PtInRect(p);
+
+ if (m_bD3DFullscreenMode)
+ {
+ TRACE ("==> HIDE!\n");
+ m_pFullscreenWnd->ShowCursor(false);
+ KillTimer(TIMER_FULLSCREENMOUSEHIDER);
+ }
+ else
+ {
+ CWnd* pWnd = WindowFromPoint(p);
+ if(pWnd && (m_wndView == *pWnd || m_wndView.IsChild(pWnd) || fCursorOutside))
+ {
+ m_fHideCursor = true;
+ SetCursor(NULL);
+ }
+ }
+ }
+ else if(nIDEvent == TIMER_STATS)
+ {
+ if(pQP)
+ {
+ CString rate;
+ if(m_iSpeedLevel >= -11 && m_iSpeedLevel <= 3 && m_iSpeedLevel != -4)
+ {
+ CString speeds[] = {_T("1/8"),_T("1/4"),_T("1/2"),_T("1"),_T("2"),_T("4"),_T("8")};
+ rate = speeds[(m_iSpeedLevel >= -3 ? m_iSpeedLevel : (-m_iSpeedLevel - 8)) + 3];
+ if(m_iSpeedLevel < -4) rate = _T("-") + rate;
+ if(!rate.IsEmpty()) rate = _T("(") + rate + _T("X)");
+ }
+
+ CString info;
+ int val;
+
+ pQP->get_AvgFrameRate(&val);
+ info.Format(_T("%d.%02d %s"), val/100, val%100, rate);
+ m_wndStatsBar.SetLine(_T("Frame-rate"), info);
+
+ int avg, dev;
+ pQP->get_AvgSyncOffset(&avg);
+ pQP->get_DevSyncOffset(&dev);
+ info.Format(_T("avg: %d ms, dev: %d ms"), avg, dev);
+ m_wndStatsBar.SetLine(_T("Sync Offset"), info);
+
+ int drawn, dropped;
+ pQP->get_FramesDrawn(&drawn);
+ pQP->get_FramesDroppedInRenderer(&dropped);
+ info.Format(_T("drawn: %d, dropped: %d"), drawn, dropped);
+ m_wndStatsBar.SetLine(_T("Frames"), info);
+
+ pQP->get_Jitter(&val);
+ info.Format(_T("%d ms"), val);
+ m_wndStatsBar.SetLine(_T("Jitter"), info);
+ }
+
+ if(pBI)
+ {
+ CAtlList<CString> sl;
+
+ for(int i = 0, j = pBI->GetCount(); i < j; i++)
+ {
+ int samples, size;
+ if(S_OK == pBI->GetStatus(i, samples, size))
+ {
+ CString str;
+ str.Format(_T("[%d]: %03d/%d KB"), i, samples, size / 1024);
+ sl.AddTail(str);
+ }
+ }
+
+ if(!sl.IsEmpty())
+ {
+ CString str;
+ str.Format(_T("%s (p%d)"), Implode(sl, ' '), pBI->GetPriority());
+
+ m_wndStatsBar.SetLine(_T("Buffers"), str);
+ }
+ }
+
+ CInterfaceList<IBitRateInfo> pBRIs;
+
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ if(CComQIPtr<IBitRateInfo> pBRI = pPin)
+ {
+ pBRIs.AddTail(pBRI);
+ }
+ }
+ EndEnumPins
+
+ if(!pBRIs.IsEmpty())
+ {
+ CAtlList<CString> sl;
+
+ POSITION pos = pBRIs.GetHeadPosition();
+ for(int i = 0; pos; i++)
+ {
+ IBitRateInfo* pBRI = pBRIs.GetNext(pos);
+
+ DWORD cur = pBRI->GetCurrentBitRate() / 1000;
+ DWORD avg = pBRI->GetAverageBitRate() / 1000;
+
+ if(avg == 0) continue;
+
+ CString str;
+ if(cur != avg) str.Format(_T("[%d]: %d/%d Kb/s"), i, avg, cur);
+ else str.Format(_T("[%d]: %d Kb/s"), i, avg);
+ sl.AddTail(str);
+ }
+
+ if(!sl.IsEmpty())
+ {
+ m_wndStatsBar.SetLine(_T("Bitrate"), Implode(sl, ' ') + _T(" (avg/cur)"));
+ }
+
+ break;
+ }
+ }
+ EndEnumFilters
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ SetupChapters();
+ }
+
+ if(m_iPlaybackMode == PM_DVD) // we also use this timer to update the info panel for dvd playback
+ {
+ ULONG ulAvailable, ulCurrent;
+
+ // Location
+
+ CString Location('-');
+
+ DVD_PLAYBACK_LOCATION2 loc;
+ ULONG ulNumOfVolumes, ulVolume;
+ DVD_DISC_SIDE Side;
+ ULONG ulNumOfTitles;
+ ULONG ulNumOfChapters;
+
+ if(SUCCEEDED(pDVDI->GetCurrentLocation(&loc))
+ && SUCCEEDED(pDVDI->GetNumberOfChapters(loc.TitleNum, &ulNumOfChapters))
+ && SUCCEEDED(pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles)))
+ {
+ Location.Format(_T("Volume: %02d/%02d, Title: %02d/%02d, Chapter: %02d/%02d"),
+ ulVolume, ulNumOfVolumes,
+ loc.TitleNum, ulNumOfTitles,
+ loc.ChapterNum, ulNumOfChapters);
+ }
+
+ m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_LOCATION), Location);
+
+ // Video
+
+ CString Video('-');
+
+ DVD_VideoAttributes VATR;
+
+ if(SUCCEEDED(pDVDI->GetCurrentAngle(&ulAvailable, &ulCurrent))
+ && SUCCEEDED(pDVDI->GetCurrentVideoAttributes(&VATR)))
+ {
+ Video.Format(_T("Angle: %02d/%02d, %dx%d %dHz %d:%d"),
+ ulAvailable, ulCurrent,
+ VATR.ulSourceResolutionX, VATR.ulSourceResolutionY, VATR.ulFrameRate,
+ VATR.ulAspectX, VATR.ulAspectY);
+ }
+
+ m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_VIDEO), Video);
+
+ // Audio
+
+ CString Audio('-');
+
+ DVD_AudioAttributes AATR;
+
+ if(SUCCEEDED(pDVDI->GetCurrentAudio(&ulAvailable, &ulCurrent))
+ && SUCCEEDED(pDVDI->GetAudioAttributes(ulCurrent, &AATR)))
+ {
+ CString lang;
+ int len = GetLocaleInfo(AATR.Language, LOCALE_SENGLANGUAGE, lang.GetBuffer(64), 64);
+ lang.ReleaseBufferSetLength(max(len-1, 0));
+
+ switch(AATR.LanguageExtension)
+ {
+ case DVD_AUD_EXT_NotSpecified:
+ default: break;
+ case DVD_AUD_EXT_Captions: lang += _T(" (Captions)"); break;
+ case DVD_AUD_EXT_VisuallyImpaired: lang += _T(" (Visually Impaired)"); break;
+ case DVD_AUD_EXT_DirectorComments1: lang += _T(" (Director Comments 1)"); break;
+ case DVD_AUD_EXT_DirectorComments2: lang += _T(" (Director Comments 2)"); break;
+ }
+
+ CString format = GetDVDAudioFormatName(AATR);
+
+ Audio.Format(_T("%s, %s %dHz %dbits %d channel(s)"),
+ lang,
+ format,
+ AATR.dwFrequency,
+ AATR.bQuantization,
+ AATR.bNumberOfChannels);
+
+ m_wndStatusBar.SetStatusBitmap(
+ AATR.bNumberOfChannels == 1 ? IDB_MONO
+ : AATR.bNumberOfChannels >= 2 ? IDB_STEREO
+ : IDB_NOAUDIO);
+ }
+
+ m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_AUDIO), Audio);
+
+ // Subtitles
+
+ CString Subtitles('-');
+
+ BOOL bIsDisabled;
+ DVD_SubpictureAttributes SATR;
+
+ if(SUCCEEDED(pDVDI->GetCurrentSubpicture(&ulAvailable, &ulCurrent, &bIsDisabled))
+ && SUCCEEDED(pDVDI->GetSubpictureAttributes(ulCurrent, &SATR)))
+ {
+ CString lang;
+ int len = GetLocaleInfo(SATR.Language, LOCALE_SENGLANGUAGE, lang.GetBuffer(64), 64);
+ lang.ReleaseBufferSetLength(max(len-1, 0));
+
+ switch(SATR.LanguageExtension)
+ {
+ case DVD_SP_EXT_NotSpecified:
+ default: break;
+ case DVD_SP_EXT_Caption_Normal: lang += _T(""); break;
+ case DVD_SP_EXT_Caption_Big: lang += _T(" (Big)"); break;
+ case DVD_SP_EXT_Caption_Children: lang += _T(" (Children)"); break;
+ case DVD_SP_EXT_CC_Normal: lang += _T(" (CC)"); break;
+ case DVD_SP_EXT_CC_Big: lang += _T(" (CC Big)"); break;
+ case DVD_SP_EXT_CC_Children: lang += _T(" (CC Children)"); break;
+ case DVD_SP_EXT_Forced: lang += _T(" (Forced)"); break;
+ case DVD_SP_EXT_DirectorComments_Normal: lang += _T(" (Director Comments)"); break;
+ case DVD_SP_EXT_DirectorComments_Big: lang += _T(" (Director Comments, Big)"); break;
+ case DVD_SP_EXT_DirectorComments_Children: lang += _T(" (Director Comments, Children)"); break;
+ }
+
+ if(bIsDisabled) lang = _T("-");
+
+ Subtitles.Format(_T("%s"),
+ lang);
+ }
+
+ m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_SUBTITLES), Subtitles);
+ }
+
+ if(GetMediaState() == State_Running)
+ {
+ UINT fSaverActive = 0;
+ if(SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, (PVOID)&fSaverActive, 0))
+ {
+ SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, 0, SPIF_SENDWININICHANGE); // this might not be needed at all...
+ SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, fSaverActive, 0, SPIF_SENDWININICHANGE);
+ }
+
+ fSaverActive = 0;
+ if(SystemParametersInfo(SPI_GETPOWEROFFACTIVE, 0, (PVOID)&fSaverActive, 0))
+ {
+ SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 0, 0, SPIF_SENDWININICHANGE); // this might not be needed at all...
+ SystemParametersInfo(SPI_SETPOWEROFFACTIVE, fSaverActive, 0, SPIF_SENDWININICHANGE);
+ }
+ }
+ }
+ else if(nIDEvent == TIMER_STATUSERASER)
+ {
+ KillTimer(TIMER_STATUSERASER);
+ m_playingmsg.Empty();
+ }
+
+ __super::OnTimer(nIDEvent);
+}
+
+static bool SetShutdownPrivilege()
+{
+ HANDLE hToken;
+ TOKEN_PRIVILEGES tkp;
+
+ // Get a token for this process.
+
+ if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
+ return(false);
+
+ // Get the LUID for the shutdown privilege.
+
+ LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
+
+ tkp.PrivilegeCount = 1; // one privilege to set
+ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ // Get the shutdown privilege for this process.
+
+ AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
+
+ if(GetLastError() != ERROR_SUCCESS)
+ return false;
+
+ return true;
+}
+
+bool CMainFrame::DoAfterPlaybackEvent()
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ bool fExit = false;
+
+ if(s.nCLSwitches&CLSW_CLOSE)
+ {
+ fExit = true;
+ }
+
+ if(s.nCLSwitches&CLSW_STANDBY)
+ {
+ SetShutdownPrivilege();
+ SetSystemPowerState(TRUE, TRUE);
+ fExit = true; // TODO: unless the app closes, it will call standby or hibernate once again forever, how to avoid that?
+ }
+ else if(s.nCLSwitches&CLSW_HIBERNATE)
+ {
+ SetShutdownPrivilege();
+ SetSystemPowerState(FALSE, TRUE);
+ fExit = true; // TODO: unless the app closes, it will call standby or hibernate once again forever, how to avoid that?
+ }
+ else if(s.nCLSwitches&CLSW_SHUTDOWN)
+ {
+ SetShutdownPrivilege();
+ ExitWindowsEx(EWX_SHUTDOWN|EWX_POWEROFF|EWX_FORCEIFHUNG, 0);
+ fExit = true;
+ }
+ else if(s.nCLSwitches&CLSW_LOGOFF)
+ {
+ SetShutdownPrivilege();
+ ExitWindowsEx(EWX_LOGOFF|EWX_FORCEIFHUNG, 0);
+ fExit = true;
+ }
+
+ if(!fExit) return false;
+
+ SendMessage(WM_COMMAND, ID_FILE_EXIT);
+
+ return true;
+}
+
+//
+// our WM_GRAPHNOTIFY handler
+//
+#include <comdef.h>
+LRESULT CMainFrame::OnGraphNotify(WPARAM wParam, LPARAM lParam)
+{
+ HRESULT hr = S_OK;
+
+ LONG evCode, evParam1, evParam2;
+ while(pME && SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR*)&evParam1, (LONG_PTR*)&evParam2, 0)))
+ {
+ CString str;
+
+ if(m_fCustomGraph)
+ {
+ if(EC_BG_ERROR == evCode)
+ {
+ str = CString((char*)evParam1);
+ }
+ }
+
+ hr = pME->FreeEventParams(evCode, evParam1, evParam2);
+
+ if(EC_COMPLETE == evCode)
+ {
+ AppSettings& s = AfxGetAppSettings();
+
+ if(m_wndPlaylistBar.GetCount() <= 1)
+ {
+ m_nLoops++;
+
+ if(DoAfterPlaybackEvent()) return hr;
+
+ if(s.fLoopForever || m_nLoops < s.nLoops)
+ {
+ if(GetMediaState() == State_Stopped)
+ {
+ SendMessage(WM_COMMAND, ID_PLAY_PLAY);
+ }
+ else
+ {
+ LONGLONG pos = 0;
+ pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
+
+ if(GetMediaState() == State_Paused)
+ {
+ SendMessage(WM_COMMAND, ID_PLAY_PLAY);
+ }
+ }
+ }
+ else
+ {
+ if(s.fRewind) SendMessage(WM_COMMAND, ID_PLAY_STOP);
+ else m_fEndOfStream = true;
+ SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
+
+ if(m_fFullScreen && s.fExitFullScreenAtTheEnd)
+ OnViewFullscreen();
+ }
+ }
+ else if(m_wndPlaylistBar.GetCount() > 1)
+ {
+ if(m_wndPlaylistBar.IsAtEnd())
+ {
+ if(DoAfterPlaybackEvent()) return hr;
+
+ m_nLoops++;
+ }
+
+ if(s.fLoopForever || m_nLoops < s.nLoops)
+ {
+ int nLoops = m_nLoops;
+ PostMessage(WM_COMMAND, ID_NAVIGATE_SKIPFORWARD);
+ m_nLoops = nLoops;
+ }
+ else
+ {
+ if(m_fFullScreen && s.fExitFullScreenAtTheEnd)
+ OnViewFullscreen();
+
+ if(s.fRewind)
+ {
+ AfxGetAppSettings().nCLSwitches |= CLSW_OPEN; // HACK
+ PostMessage(WM_COMMAND, ID_NAVIGATE_SKIPFORWARD);
+ }
+ else
+ {
+ m_fEndOfStream = true;
+ PostMessage(WM_COMMAND, ID_PLAY_PAUSE);
+ }
+ }
+ }
+ }
+ else if(EC_ERRORABORT == evCode)
+ {
+ TRACE(_T("EC_ERRORABORT, hr = %08x\n"), (HRESULT)evParam1);
+// SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+// m_closingmsg = _com_error((HRESULT)evParam1).ErrorMessage();
+ }
+ else if(EC_REPAINT == evCode)
+ {
+ TRACE(_T("EC_REPAINT\n"));
+ }
+ else if(EC_BUFFERING_DATA == evCode)
+ {
+ TRACE(_T("EC_BUFFERING_DATA, %d, %d\n"), (HRESULT)evParam1, evParam2);
+
+ m_fBuffering = ((HRESULT)evParam1 != S_OK);
+ }
+ else if(EC_STEP_COMPLETE == evCode)
+ {
+ if(m_fFrameSteppingActive)
+ {
+ m_fFrameSteppingActive = false;
+ pBA->put_Volume(m_VolumeBeforeFrameStepping);
+ }
+ }
+ else if(EC_DEVICE_LOST == evCode)
+ {
+ CComQIPtr<IBaseFilter> pBF;
+ if(m_iPlaybackMode == PM_CAPTURE
+ && (!pVidCap && pVidCap == (pBF = (IUnknown*)evParam1)
+ || !pAudCap && pAudCap == (pBF = (IUnknown*)evParam1))
+ && evParam2 == 0)
+ {
+ SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+ }
+ }
+ else if(EC_DVD_TITLE_CHANGE == evCode)
+ {
+ // Casimir666 : Mémoriser le chapitre en cours
+ DVD_POSITION* DvdPos = AfxGetAppSettings().CurrentDVDPosition();
+ if (DvdPos) DvdPos->lTitle = (DWORD)evParam1;
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ SetupChapters();
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ m_iDVDTitle = (DWORD)evParam1;
+
+ if(m_iDVDDomain == DVD_DOMAIN_Title)
+ {
+ CString Domain;
+ Domain.Format(_T("Title %d"), m_iDVDTitle);
+ m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_DOMAIN), Domain);
+ }
+ }
+ }
+ else if(EC_DVD_DOMAIN_CHANGE == evCode)
+ {
+ m_iDVDDomain = (DVD_DOMAIN)evParam1;
+
+ CString Domain('-');
+
+ switch(m_iDVDDomain)
+ {
+ case DVD_DOMAIN_FirstPlay:
+ IDvdCmd* pCmd;
+ ULONGLONG llDVDGuid;
+
+ // Casimir666 : Au lancement de positionner a la dernière position lue
+ if (pDVDI && SUCCEEDED (pDVDI->GetDiscID (NULL, &llDVDGuid)))
+ {
+ if (!AfxGetAppSettings().NewDvd (llDVDGuid) && AfxGetAppSettings().fRememberDVDPos)
+ {
+ DVD_POSITION* DvdPos = AfxGetAppSettings().CurrentDVDPosition();
+ hr = pDVDC->PlayAtTimeInTitle (DvdPos->lTitle, &DvdPos->Timecode, DVD_CMD_FLAG_Flush, &pCmd);
+ if (pCmd) pCmd->Release();
+ }
+ }
+ Domain = _T("First Play"); break;
+ case DVD_DOMAIN_VideoManagerMenu: Domain = _T("Video Manager Menu"); break;
+ case DVD_DOMAIN_VideoTitleSetMenu: Domain = _T("Video Title Set Menu"); break;
+ case DVD_DOMAIN_Title: Domain.Format(_T("Title %d"), m_iDVDTitle); break;
+ case DVD_DOMAIN_Stop: Domain = _T("Stop"); break;
+ default: Domain = _T("-"); break;
+ }
+
+ m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_DOMAIN), Domain);
+
+ MoveVideoWindow(); // AR might have changed
+ }
+ else if(EC_DVD_CURRENT_HMSF_TIME == evCode)
+ {
+ double fps = evParam2 == DVD_TC_FLAG_25fps ? 25.0
+ : evParam2 == DVD_TC_FLAG_30fps ? 30.0
+ : evParam2 == DVD_TC_FLAG_DropFrame ? 29.97
+ : 25.0;
+
+ REFERENCE_TIME rtDur = 0;
+
+ DVD_HMSF_TIMECODE tcDur;
+ ULONG ulFlags;
+ if(SUCCEEDED(pDVDI->GetTotalTitleTime(&tcDur, &ulFlags)))
+ rtDur = HMSF2RT(tcDur, fps);
+
+ m_wndSeekBar.Enable(rtDur > 0);
+ m_wndSeekBar.SetRange(0, rtDur);
+ m_OSD.SetRange (0, rtDur);
+
+ REFERENCE_TIME rtNow = HMSF2RT(*((DVD_HMSF_TIMECODE*)&evParam1), fps);
+
+ // Casimir666 : Mémoriser le timecode courant dans le chapitre
+ DVD_POSITION* DvdPos = AfxGetAppSettings().CurrentDVDPosition();
+ if (DvdPos)
+ memcpy (&DvdPos->Timecode, (void*)&evParam1, sizeof(DVD_HMSF_TIMECODE));
+
+ m_wndSeekBar.SetPos(rtNow);
+ m_OSD.SetPos(rtNow);
+
+ if(m_pSubClock) m_pSubClock->SetTime(rtNow);
+ }
+ else if(EC_DVD_ERROR == evCode)
+ {
+ TRACE(_T("EC_DVD_ERROR %d %d\n"), evParam1, evParam2);
+
+ CString err;
+
+ switch(evParam1)
+ {
+ case DVD_ERROR_Unexpected: default: err = _T("DVD: Unexpected error"); break;
+ case DVD_ERROR_CopyProtectFail: err = _T("DVD: Copy-Protect Fail"); break;
+ case DVD_ERROR_InvalidDVD1_0Disc: err = _T("DVD: Invalid DVD 1.x Disc"); break;
+ case DVD_ERROR_InvalidDiscRegion: err = _T("DVD: Invalid Disc Region"); break;
+ case DVD_ERROR_LowParentalLevel: err = _T("DVD: Low Parental Level"); break;
+ case DVD_ERROR_MacrovisionFail: err = _T("DVD: Macrovision Fail"); break;
+ case DVD_ERROR_IncompatibleSystemAndDecoderRegions: err = _T("DVD: Incompatible System And Decoder Regions"); break;
+ case DVD_ERROR_IncompatibleDiscAndDecoderRegions: err = _T("DVD: Incompatible Disc And Decoder Regions"); break;
+ }
+
+ SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+
+ m_closingmsg = err;
+ }
+ else if(EC_DVD_WARNING == evCode)
+ {
+ TRACE(_T("EC_DVD_WARNING %d %d\n"), evParam1, evParam2);
+ }
+ else if(EC_VIDEO_SIZE_CHANGED == evCode)
+ {
+ TRACE(_T("EC_VIDEO_SIZE_CHANGED %dx%d\n"), CSize(evParam1));
+
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(wp);
+ GetWindowPlacement(&wp);
+
+ CSize size(evParam1);
+ m_fAudioOnly = (size.cx <= 0 || size.cy <= 0);
+
+ if(AfxGetAppSettings().fRememberZoomLevel
+ && !(m_fFullScreen || wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_SHOWMINIMIZED))
+ {
+ ZoomVideoWindow();
+ }
+ else
+ {
+ MoveVideoWindow();
+ }
+
+ if(m_iMediaLoadState == MLS_LOADED
+ && !m_fAudioOnly && (AfxGetAppSettings().nCLSwitches&CLSW_FULLSCREEN))
+ {
+ PostMessage(WM_COMMAND, ID_VIEW_FULLSCREEN);
+ AfxGetAppSettings().nCLSwitches &= ~CLSW_FULLSCREEN;
+ }
+ }
+ else if(EC_LENGTH_CHANGED == evCode)
+ {
+ __int64 rtDur = 0;
+ pMS->GetDuration(&rtDur);
+ m_wndPlaylistBar.SetCurTime(rtDur);
+ }
+ else if(!m_fCustomGraph)
+ {
+ TRACE(_T("evCode: %d\n"), evCode);
+ }
+ else if(EC_BG_AUDIO_CHANGED == evCode)
+ {
+ int nAudioChannels = evParam1;
+
+ m_wndStatusBar.SetStatusBitmap(nAudioChannels == 1 ? IDB_MONO
+ : nAudioChannels >= 2 ? IDB_STEREO
+ : IDB_NOAUDIO);
+ }
+ else if(EC_BG_ERROR == evCode)
+ {
+ SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+ m_closingmsg = !str.IsEmpty() ? str : _T("Unspecified graph error");
+ m_wndPlaylistBar.SetCurValid(false);
+ break;
+ }
+ }
+
+ return hr;
+}
+
+LRESULT CMainFrame::OnRepaintRenderLess(WPARAM wParam, LPARAM lParam)
+{
+ MoveVideoWindow();
+ return TRUE;
+}
+
+LRESULT CMainFrame::OnResumeFromState(WPARAM wParam, LPARAM lParam)
+{
+ int iPlaybackMode = (int)wParam;
+
+ if(iPlaybackMode == PM_FILE)
+ {
+ SeekTo(10000i64*int(lParam));
+ }
+ else if(iPlaybackMode == PM_DVD)
+ {
+ CComPtr<IDvdState> pDvdState;
+ pDvdState.Attach((IDvdState*)lParam);
+ if(pDVDC) pDVDC->SetState(pDvdState, DVD_CMD_FLAG_Block, NULL);
+ }
+ else if(iPlaybackMode == PM_CAPTURE)
+ {
+ // not implemented
+ }
+ else
+ {
+ ASSERT(0);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL CMainFrame::OnButton(UINT id, UINT nFlags, CPoint point)
+{
+ SetFocus();
+
+ CRect r;
+ if (m_bD3DFullscreenMode)
+ m_pFullscreenWnd->GetClientRect(r);
+ else
+ {
+ m_wndView.GetClientRect(r);
+ m_wndView.MapWindowPoints(this, &r);
+ }
+
+ if(id != wmcmd::WDOWN && id != wmcmd::WUP && !r.PtInRect(point)) return FALSE;
+
+ BOOL ret = FALSE;
+
+ AppSettings& s = AfxGetAppSettings();
+ POSITION pos = s.wmcmds.GetHeadPosition();
+ while(pos)
+ {
+ wmcmd& wc = s.wmcmds.GetNext(pos);
+ if(wc.mouse == id)
+ {
+ SendMessage(WM_COMMAND, wc.cmd);
+ ret = true;
+ }
+ }
+
+ return ret;
+}
+
+static bool s_fLDown = false;
+
+void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ if (!m_OSD.OnLButtonDown (nFlags, point))
+ {
+ SetFocus();
+
+ bool fClicked = false;
+
+ if(m_iPlaybackMode == PM_DVD)
+ {
+ CPoint p = point - m_wndView.GetVideoRect().TopLeft();
+
+ if(SUCCEEDED(pDVDC->ActivateAtPosition(p))
+ || m_iDVDDomain == DVD_DOMAIN_VideoManagerMenu
+ || m_iDVDDomain == DVD_DOMAIN_VideoTitleSetMenu)
+ fClicked = true;
+ }
+
+ if(!fClicked)
+ {
+ bool fLeftMouseBtnUnassigned = true;
+ AppSettings& s = AfxGetAppSettings();
+ POSITION pos = s.wmcmds.GetHeadPosition();
+ while(pos && fLeftMouseBtnUnassigned)
+ if(s.wmcmds.GetNext(pos).mouse == wmcmd::LDOWN)
+ fLeftMouseBtnUnassigned = false;
+
+ if(!m_fFullScreen && (IsCaptionMenuHidden() || fLeftMouseBtnUnassigned))
+ {
+ PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
+ }
+ else
+ {
+ s_fLDown = true;
+ if(OnButton(wmcmd::LDOWN, nFlags, point))
+ return;
+ }
+ }
+
+ __super::OnLButtonDown(nFlags, point);
+ }
+}
+
+void CMainFrame::OnLButtonUp(UINT nFlags, CPoint point)
+{
+ if (!m_OSD.OnLButtonUp (nFlags, point))
+ {
+ if(!OnButton(wmcmd::LUP, nFlags, point))
+ __super::OnLButtonUp(nFlags, point);
+ }
+}
+
+void CMainFrame::OnLButtonDblClk(UINT nFlags, CPoint point)
+{
+if(s_fLDown)
+{
+ SendMessage(WM_LBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
+s_fLDown = false;
+}
+ if(!OnButton(wmcmd::LDBLCLK, nFlags, point))
+ __super::OnLButtonDblClk(nFlags, point);
+}
+
+void CMainFrame::OnMButtonDown(UINT nFlags, CPoint point)
+{
+ SendMessage(WM_CANCELMODE);
+ if(!OnButton(wmcmd::MDOWN, nFlags, point))
+ __super::OnMButtonDown(nFlags, point);
+}
+
+void CMainFrame::OnMButtonUp(UINT nFlags, CPoint point)
+{
+ if(!OnButton(wmcmd::MUP, nFlags, point))
+ __super::OnMButtonUp(nFlags, point);
+}
+
+void CMainFrame::OnMButtonDblClk(UINT nFlags, CPoint point)
+{
+ SendMessage(WM_MBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
+ if(!OnButton(wmcmd::MDBLCLK, nFlags, point))
+ __super::OnMButtonDblClk(nFlags, point);
+}
+
+void CMainFrame::OnRButtonDown(UINT nFlags, CPoint point)
+{
+ if(!OnButton(wmcmd::RDOWN, nFlags, point))
+ __super::OnRButtonDown(nFlags, point);
+}
+
+void CMainFrame::OnRButtonUp(UINT nFlags, CPoint point)
+{
+ if(!OnButton(wmcmd::RUP, nFlags, point))
+ __super::OnRButtonUp(nFlags, point);
+}
+
+void CMainFrame::OnRButtonDblClk(UINT nFlags, CPoint point)
+{
+ SendMessage(WM_RBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
+ if(!OnButton(wmcmd::RDBLCLK, nFlags, point))
+ __super::OnRButtonDblClk(nFlags, point);
+}
+
+LRESULT CMainFrame::OnXButtonDown(WPARAM wParam, LPARAM lParam)
+{
+ SendMessage(WM_CANCELMODE);
+ UINT fwButton = GET_XBUTTON_WPARAM(wParam);
+ return OnButton(fwButton == XBUTTON1 ? wmcmd::X1DOWN : fwButton == XBUTTON2 ? wmcmd::X2DOWN : wmcmd::NONE,
+ GET_KEYSTATE_WPARAM(wParam), CPoint(lParam));
+}
+
+LRESULT CMainFrame::OnXButtonUp(WPARAM wParam, LPARAM lParam)
+{
+ UINT fwButton = GET_XBUTTON_WPARAM(wParam);
+ return OnButton(fwButton == XBUTTON1 ? wmcmd::X1UP : fwButton == XBUTTON2 ? wmcmd::X2UP : wmcmd::NONE,
+ GET_KEYSTATE_WPARAM(wParam), CPoint(lParam));
+}
+
+LRESULT CMainFrame::OnXButtonDblClk(WPARAM wParam, LPARAM lParam)
+{
+ SendMessage(WM_XBUTTONDOWN, wParam, lParam);
+ UINT fwButton = GET_XBUTTON_WPARAM(wParam);
+ return OnButton(fwButton == XBUTTON1 ? wmcmd::X1DBLCLK : fwButton == XBUTTON2 ? wmcmd::X2DBLCLK : wmcmd::NONE,
+ GET_KEYSTATE_WPARAM(wParam), CPoint(lParam));
+}
+
+BOOL CMainFrame::OnMouseWheel(UINT nFlags, short zDelta, CPoint point)
+{
+ ScreenToClient(&point);
+
+ BOOL fRet =
+ zDelta > 0 ? OnButton(wmcmd::WUP, nFlags, point) :
+ zDelta < 0 ? OnButton(wmcmd::WDOWN, nFlags, point) :
+ FALSE;
+
+ return fRet;
+}
+
+void CMainFrame::OnMouseMove(UINT nFlags, CPoint point)
+{
+ if (!m_OSD.OnMouseMove (nFlags, point))
+ {
+ if(m_iPlaybackMode == PM_DVD)
+ {
+ CPoint vp = point - m_wndView.GetVideoRect().TopLeft();
+ pDVDC->SelectAtPosition(vp);
+ }
+
+ CSize diff = m_lastMouseMove - point;
+
+ if (m_bD3DFullscreenMode && (abs(diff.cx)+abs(diff.cy)) >= 1)
+ {
+ // TRACE ("==> SHOW!\n");
+ m_pFullscreenWnd->ShowCursor(true);
+
+ // Casimir666 : en dehors du menu DVD, cacher le curseur
+ if ( (m_iPlaybackMode == PM_FILE) ||
+ ((m_iPlaybackMode == PM_DVD) && (m_iDVDDomain != DVD_DOMAIN_VideoManagerMenu) && (m_iDVDDomain != DVD_DOMAIN_VideoTitleSetMenu)) )
+ {
+ KillTimer(TIMER_FULLSCREENMOUSEHIDER);
+ SetTimer(TIMER_FULLSCREENMOUSEHIDER, 2000, NULL);
+ }
+ }
+ else if(m_fFullScreen && (abs(diff.cx)+abs(diff.cy)) >= 1)
+ {
+ int nTimeOut = AfxGetAppSettings().nShowBarsWhenFullScreenTimeOut;
+
+ if(nTimeOut < 0)
+ {
+ m_fHideCursor = false;
+ if(AfxGetAppSettings().fShowBarsWhenFullScreen)
+ ShowControls(AfxGetAppSettings().nCS);
+
+ KillTimer(TIMER_FULLSCREENCONTROLBARHIDER);
+ SetTimer(TIMER_FULLSCREENMOUSEHIDER, 2000, NULL);
+ }
+ else if(nTimeOut == 0)
+ {
+ CRect r;
+ GetClientRect(r);
+ r.top = r.bottom;
+
+ POSITION pos = m_bars.GetHeadPosition();
+ for(int i = 1; pos; i <<= 1)
+ {
+ CControlBar* pNext = m_bars.GetNext(pos);
+ CSize s = pNext->CalcFixedLayout(FALSE, TRUE);
+ if(AfxGetAppSettings().nCS&i) r.top -= s.cy;
+ }
+
+
+ // HACK: the controls would cover the menu too early hiding some buttons
+ if(m_iPlaybackMode == PM_DVD
+ && (m_iDVDDomain == DVD_DOMAIN_VideoManagerMenu
+ || m_iDVDDomain == DVD_DOMAIN_VideoTitleSetMenu))
+ r.top = r.bottom - 10;
+
+ m_fHideCursor = false;
+
+ if(r.PtInRect(point))
+ {
+ if(AfxGetAppSettings().fShowBarsWhenFullScreen)
+ ShowControls(AfxGetAppSettings().nCS);
+ }
+ else
+ {
+ if(AfxGetAppSettings().fShowBarsWhenFullScreen)
+ ShowControls(CS_NONE, false);
+ }
+
+ SetTimer(TIMER_FULLSCREENMOUSEHIDER, 2000, NULL);
+ }
+ else
+ {
+ m_fHideCursor = false;
+ if(AfxGetAppSettings().fShowBarsWhenFullScreen)
+ ShowControls(AfxGetAppSettings().nCS);
+
+ SetTimer(TIMER_FULLSCREENCONTROLBARHIDER, nTimeOut*1000, NULL);
+ SetTimer(TIMER_FULLSCREENMOUSEHIDER, max(nTimeOut*1000, 2000), NULL);
+ }
+ }
+
+ m_lastMouseMove = point;
+
+ __super::OnMouseMove(nFlags, point);
+ }
+}
+
+UINT CMainFrame::OnNcHitTest(CPoint point)
+{
+ LRESULT nHitTest = __super::OnNcHitTest(point);
+ return ((IsCaptionMenuHidden()) && nHitTest == HTCLIENT) ? HTCAPTION : nHitTest;
+}
+
+void CMainFrame::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+ if(pScrollBar->IsKindOf(RUNTIME_CLASS(CVolumeCtrl)))
+ {
+ OnPlayVolume(0);
+ }
+ else if(pScrollBar->IsKindOf(RUNTIME_CLASS(CPlayerSeekBar)) && m_iMediaLoadState == MLS_LOADED)
+ {
+ SeekTo(m_wndSeekBar.GetPos(), !!(::GetKeyState(VK_SHIFT)&0x8000));
+ }
+ else if (m_pVideoWnd == m_pVideoWnd)
+ {
+ SeekTo(m_OSD.GetPos(), !!(::GetKeyState(VK_SHIFT)&0x8000));
+ }
+
+ __super::OnHScroll(nSBCode, nPos, pScrollBar);
+}
+
+void CMainFrame::OnInitMenu(CMenu* pMenu)
+{
+ __super::OnInitMenu(pMenu);
+
+ MENUITEMINFO mii;
+ mii.cbSize = sizeof(mii);
+
+ for(UINT i = 0, j = pMenu->GetMenuItemCount(); i < j; i++)
+ {
+ CString str;
+ pMenu->GetMenuString(i, str, MF_BYPOSITION);
+
+ CMenu* pSubMenu = NULL;
+
+ if(str == ResStr(IDS_FAVORITES_POPUP))
+ {
+ SetupFavoritesSubMenu();
+ pSubMenu = &m_favorites;
+ }
+
+ if(pSubMenu)
+ {
+ mii.fMask = MIIM_STATE|MIIM_SUBMENU;
+ mii.fType = MF_POPUP;
+ mii.hSubMenu = pSubMenu->m_hMenu;
+ mii.fState = (pSubMenu->GetMenuItemCount() > 0 ? MF_ENABLED : (MF_DISABLED|MF_GRAYED));
+ pMenu->SetMenuItemInfo(i, &mii, TRUE);
+ }
+ }
+}
+
+void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
+{
+ __super::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
+
+ static CAtlStringMap<UINT> transl;
+
+ if(transl.IsEmpty())
+ {
+ transl[_T("Navigate")] = IDS_NAVIGATE_POPUP;
+ transl[_T("Open Disc")] = IDS_OPENCDROM_POPUP;
+ transl[_T("Filters")] = IDS_FILTERS_POPUP;
+ transl[_T("Audio")] = IDS_AUDIO_POPUP;
+ transl[_T("Subtitles")] = IDS_SUBTITLES_POPUP;
+ transl[_T("Audio Language")] = IDS_AUDIOLANGUAGE_POPUP;
+ transl[_T("Subtitle Language")] = IDS_SUBTITLELANGUAGE_POPUP;
+ transl[_T("Video Angle")] = IDS_VIDEOANGLE_POPUP;
+ transl[_T("Jump To...")] = IDS_JUMPTO_POPUP;
+ transl[_T("Favorites")] = IDS_FAVORITES_POPUP;
+ transl[_T("Shaders")] = IDS_SHADER_POPUP;
+ transl[_T("Video Frame")] = IDS_VIDEOFRAME_POPUP;
+ transl[_T("PanScan")] = IDS_PANSCAN_POPUP;
+ transl[_T("Aspect Ratio")] = IDS_ASPECTRATIO_POPUP;
+ transl[_T("Zoom")] = IDS_ZOOM_POPUP;
+ }
+
+ MENUITEMINFO mii;
+ mii.cbSize = sizeof(mii);
+
+ for(UINT i = 0, j = pPopupMenu->GetMenuItemCount(); i < j; i++)
+ {
+ CString str;
+ pPopupMenu->GetMenuString(i, str, MF_BYPOSITION);
+
+ CString lookupstr = str;
+ lookupstr.Remove('&');
+
+ CMenu* pSubMenu = NULL;
+
+ UINT id;
+ if(transl.Lookup(lookupstr, id))
+ {
+ str = ResStr(id);
+ // pPopupMenu->ModifyMenu(i, MF_BYPOSITION|MF_STRING, 0, str);
+ MENUITEMINFO mii;
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STRING;
+ mii.dwTypeData = (LPTSTR)(LPCTSTR)str;
+ pPopupMenu->SetMenuItemInfo(i, &mii, TRUE);
+ }
+
+ if(str == ResStr(IDS_NAVIGATE_POPUP))
+ {
+ UINT fState = (m_iMediaLoadState == MLS_LOADED
+ && (1/*m_iPlaybackMode == PM_DVD *//*|| (m_iPlaybackMode == PM_FILE && m_PlayList.GetCount() > 0)*/))
+ ? MF_ENABLED
+ : (MF_DISABLED|MF_GRAYED);
+
+ pPopupMenu->EnableMenuItem(i, MF_BYPOSITION|fState);
+ }
+ else if(str == ResStr(IDS_VIDEOFRAME_POPUP)
+ || str == ResStr(IDS_PANSCAN_POPUP)
+ || str == ResStr(IDS_ASPECTRATIO_POPUP)
+ || str == ResStr(IDS_ZOOM_POPUP))
+ {
+ UINT fState = (m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly)
+ ? MF_ENABLED
+ : (MF_DISABLED|MF_GRAYED);
+
+ pPopupMenu->EnableMenuItem(i, MF_BYPOSITION|fState);
+ }
+ else if(str == ResStr(IDS_OPENCDROM_POPUP))
+ {
+ SetupOpenCDSubMenu();
+ pSubMenu = &m_opencds;
+ }
+ else if(str == ResStr(IDS_FILTERS_POPUP))
+ {
+ SetupFiltersSubMenu();
+ pSubMenu = &m_filters;
+ }
+ else if(str == ResStr(IDS_AUDIO_POPUP))
+ {
+ SetupAudioSwitcherSubMenu();
+ pSubMenu = &m_audios;
+ }
+ else if(str == ResStr(IDS_SUBTITLES_POPUP))
+ {
+ SetupSubtitlesSubMenu();
+ pSubMenu = &m_subtitles;
+ }
+ else if(str == ResStr(IDS_AUDIOLANGUAGE_POPUP))
+ {
+ SetupNavAudioSubMenu();
+ pSubMenu = &m_navaudio;
+ }
+ else if(str == ResStr(IDS_SUBTITLELANGUAGE_POPUP))
+ {
+ SetupNavSubtitleSubMenu();
+ pSubMenu = &m_navsubtitle;
+ }
+ else if(str == ResStr(IDS_VIDEOANGLE_POPUP))
+ {
+ SetupNavAngleSubMenu();
+ pSubMenu = &m_navangle;
+ }
+ else if(str == ResStr(IDS_JUMPTO_POPUP))
+ {
+ SetupNavChaptersSubMenu();
+ pSubMenu = &m_navchapters;
+ }
+ else if(str == ResStr(IDS_FAVORITES_POPUP))
+ {
+ SetupFavoritesSubMenu();
+ pSubMenu = &m_favorites;
+ }
+ else if(str == ResStr(IDS_SHADER_POPUP))
+ {
+ SetupShadersSubMenu();
+ pSubMenu = &m_shaders;
+ }
+
+ if(pSubMenu)
+ {
+ mii.fMask = MIIM_STATE|MIIM_SUBMENU;
+ mii.fType = MF_POPUP;
+ mii.hSubMenu = pSubMenu->m_hMenu;
+ mii.fState = (pSubMenu->GetMenuItemCount() > 0 ? MF_ENABLED : (MF_DISABLED|MF_GRAYED));
+ pPopupMenu->SetMenuItemInfo(i, &mii, TRUE);
+ }
+ }
+
+ //
+
+ for(UINT i = 0, j = pPopupMenu->GetMenuItemCount(); i < j; i++)
+ {
+ UINT nID = pPopupMenu->GetMenuItemID(i);
+ if(nID == ID_SEPARATOR || nID == -1
+ || nID >= ID_FAVORITES_FILE_START && nID <= ID_FAVORITES_FILE_END
+ || nID >= ID_NAVIGATE_CHAP_SUBITEM_START && nID <= ID_NAVIGATE_CHAP_SUBITEM_END)
+ continue;
+
+ CString str;
+ pPopupMenu->GetMenuString(i, str, MF_BYPOSITION);
+ int k = str.Find('\t');
+ if(k > 0) str = str.Left(k);
+
+ CString key = CPPageAccelTbl::MakeAccelShortcutLabel(nID);
+ if(!key.IsEmpty()) str += _T("\t") + key;
+
+ if(key.IsEmpty() && i < 0) continue;
+
+ // BUG(?): this disables menu item update ui calls for some reason...
+// pPopupMenu->ModifyMenu(i, MF_BYPOSITION|MF_STRING, nID, str);
+
+ // this works fine
+ MENUITEMINFO mii;
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STRING;
+ mii.dwTypeData = (LPTSTR)(LPCTSTR)str;
+ pPopupMenu->SetMenuItemInfo(i, &mii, TRUE);
+
+ }
+
+ //
+
+ bool fPnSPresets = false;
+
+ for(UINT i = 0, j = pPopupMenu->GetMenuItemCount(); i < j; i++)
+ {
+ UINT nID = pPopupMenu->GetMenuItemID(i);
+
+ if(nID >= ID_PANNSCAN_PRESETS_START && nID < ID_PANNSCAN_PRESETS_END)
+ {
+ do
+ {
+ nID = pPopupMenu->GetMenuItemID(i);
+ pPopupMenu->DeleteMenu(i, MF_BYPOSITION);
+ j--;
+ }
+ while(i < j && nID >= ID_PANNSCAN_PRESETS_START && nID < ID_PANNSCAN_PRESETS_END);
+
+ nID = pPopupMenu->GetMenuItemID(i);
+ }
+
+ if(nID == ID_VIEW_RESET)
+ {
+ fPnSPresets = true;
+ }
+ }
+
+ if(fPnSPresets)
+ {
+ AppSettings& s = AfxGetAppSettings();
+ int i = 0, j = s.m_pnspresets.GetCount();
+ for(; i < j; i++)
+ {
+ int k = 0;
+ CString label = s.m_pnspresets[i].Tokenize(_T(","), k);
+ pPopupMenu->InsertMenu(ID_VIEW_RESET, MF_BYCOMMAND, ID_PANNSCAN_PRESETS_START+i, label);
+ }
+// if(j > 0)
+ {
+ pPopupMenu->InsertMenu(ID_VIEW_RESET, MF_BYCOMMAND, ID_PANNSCAN_PRESETS_START+i, ResStr(IDS_PANSCAN_EDIT));
+ pPopupMenu->InsertMenu(ID_VIEW_RESET, MF_BYCOMMAND|MF_SEPARATOR);
+ }
+ }
+}
+
+BOOL CMainFrame::OnMenu(CMenu* pMenu)
+{
+ if(!pMenu) return FALSE;
+
+ KillTimer(TIMER_FULLSCREENMOUSEHIDER);
+ m_fHideCursor = false;
+
+ CPoint point;
+ GetCursorPos(&point);
+
+ pMenu->TrackPopupMenu(TPM_RIGHTBUTTON|TPM_NOANIMATION, point.x+1, point.y+1, this);
+
+ return TRUE;
+}
+
+void CMainFrame::OnMenuPlayerShort()
+{
+ if(IsCaptionMenuHidden())
+ {
+ OnMenu(m_popupmain.GetSubMenu(0));
+ }
+ else
+ {
+ OnMenu(m_popup.GetSubMenu(0));
+ }
+}
+
+void CMainFrame::OnMenuPlayerLong()
+{
+ OnMenu(m_popupmain.GetSubMenu(0));
+}
+
+void CMainFrame::OnMenuFilters()
+{
+ SetupFiltersSubMenu();
+ OnMenu(&m_filters);
+}
+
+void CMainFrame::OnUpdatePlayerStatus(CCmdUI* pCmdUI)
+{
+ if(m_iMediaLoadState == MLS_LOADING)
+ {
+ pCmdUI->SetText(ResStr(IDS_CONTROLS_OPENING));
+ }
+ else if(m_iMediaLoadState == MLS_LOADED)
+ {
+ CString msg;
+
+ if(!m_playingmsg.IsEmpty())
+ {
+ msg = m_playingmsg;
+ }
+ else if(m_fCapturing)
+ {
+ msg = ResStr(IDS_CONTROLS_CAPTURING);
+
+ if(pAMDF)
+ {
+ long lDropped = 0;
+ pAMDF->GetNumDropped(&lDropped);
+ long lNotDropped = 0;
+ pAMDF->GetNumNotDropped(&lNotDropped);
+
+ if((lDropped + lNotDropped) > 0)
+ {
+ CString str;
+ str.Format(_T(", Total: %d, Dropped: %d"), lDropped + lNotDropped, lDropped);
+ msg += str;
+ }
+ }
+
+ CComPtr<IPin> pPin;
+ if(SUCCEEDED(pCGB->FindPin(m_wndCaptureBar.m_capdlg.m_pDst, PINDIR_INPUT, NULL, NULL, FALSE, 0, &pPin)))
+ {
+ LONGLONG size = 0;
+ if(CComQIPtr<IStream> pStream = pPin)
+ {
+ pStream->Commit(STGC_DEFAULT);
+
+ WIN32_FIND_DATA findFileData;
+ HANDLE h = FindFirstFile(m_wndCaptureBar.m_capdlg.m_file, &findFileData);
+ if(h != INVALID_HANDLE_VALUE)
+ {
+ size = ((LONGLONG)findFileData.nFileSizeHigh << 32) | findFileData.nFileSizeLow;
+
+ CString str;
+ if(size < 1024i64*1024)
+ str.Format(_T(", Size: %I64dKB"), size/1024);
+ else //if(size < 1024i64*1024*1024)
+ str.Format(_T(", Size: %I64dMB"), size/1024/1024);
+ msg += str;
+
+ FindClose(h);
+ }
+ }
+
+ ULARGE_INTEGER FreeBytesAvailable, TotalNumberOfBytes, TotalNumberOfFreeBytes;
+ if(GetDiskFreeSpaceEx(
+ m_wndCaptureBar.m_capdlg.m_file.Left(m_wndCaptureBar.m_capdlg.m_file.ReverseFind('\\')+1),
+ &FreeBytesAvailable, &TotalNumberOfBytes, &TotalNumberOfFreeBytes))
+ {
+ CString str;
+ if(FreeBytesAvailable.QuadPart < 1024i64*1024)
+ str.Format(_T(", Free: %I64dKB"), FreeBytesAvailable.QuadPart/1024);
+ else //if(FreeBytesAvailable.QuadPart < 1024i64*1024*1024)
+ str.Format(_T(", Free: %I64dMB"), FreeBytesAvailable.QuadPart/1024/1024);
+ msg += str;
+ }
+
+ if(m_wndCaptureBar.m_capdlg.m_pMux)
+ {
+ __int64 pos = 0;
+ CComQIPtr<IMediaSeeking> pMuxMS = m_wndCaptureBar.m_capdlg.m_pMux;
+ if(pMuxMS && SUCCEEDED(pMuxMS->GetCurrentPosition(&pos)) && pos > 0)
+ {
+ double bytepersec = 10000000.0 * size / pos;
+ if(bytepersec > 0)
+ m_rtDurationOverride = __int64(10000000.0 * (FreeBytesAvailable.QuadPart+size) / bytepersec);
+ }
+ }
+
+ if(m_wndCaptureBar.m_capdlg.m_pVidBuffer
+ || m_wndCaptureBar.m_capdlg.m_pAudBuffer)
+ {
+ int nFreeVidBuffers = 0, nFreeAudBuffers = 0;
+ if(CComQIPtr<IBufferFilter> pVB = m_wndCaptureBar.m_capdlg.m_pVidBuffer)
+ nFreeVidBuffers = pVB->GetFreeBuffers();
+ if(CComQIPtr<IBufferFilter> pAB = m_wndCaptureBar.m_capdlg.m_pAudBuffer)
+ nFreeAudBuffers = pAB->GetFreeBuffers();
+
+ CString str;
+ str.Format(_T(", Free V/A Buffers: %03d/%03d"), nFreeVidBuffers, nFreeAudBuffers);
+ msg += str;
+ }
+ }
+ }
+ else if(m_fBuffering)
+ {
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ if(CComQIPtr<IAMNetworkStatus, &IID_IAMNetworkStatus> pAMNS = pBF)
+ {
+ long BufferingProgress = 0;
+ if(SUCCEEDED(pAMNS->get_BufferingProgress(&BufferingProgress)) && BufferingProgress > 0)
+ {
+ msg.Format(ResStr(IDS_CONTROLS_BUFFERING), BufferingProgress);
+
+ __int64 start = 0, stop = 0;
+ m_wndSeekBar.GetRange(start, stop);
+ m_fLiveWM = (stop == start);
+ }
+ break;
+ }
+ }
+ EndEnumFilters
+ }
+ else if(pAMOP)
+ {
+ __int64 t = 0, c = 0;
+ if(SUCCEEDED(pAMOP->QueryProgress(&t, &c)) && t > 0 && c < t)
+ msg.Format(ResStr(IDS_CONTROLS_BUFFERING), c*100/t);
+
+ if(m_fUpdateInfoBar)
+ OpenSetupInfoBar();
+ }
+
+ OAFilterState fs = GetMediaState();
+ pCmdUI->SetText(
+ !msg.IsEmpty() ? msg :
+ fs == State_Stopped ? ResStr(IDS_CONTROLS_STOPPED) :
+ (fs == State_Paused || m_fFrameSteppingActive) ? ResStr(IDS_CONTROLS_PAUSED) :
+ fs == State_Running ? ResStr(IDS_CONTROLS_PLAYING) :
+ _T(""));
+ }
+ else if(m_iMediaLoadState == MLS_CLOSING)
+ {
+ pCmdUI->SetText(ResStr(IDS_CONTROLS_CLOSING));
+ }
+ else
+ {
+ pCmdUI->SetText(m_closingmsg);
+ }
+}
+
+void CMainFrame::OnFilePostOpenmedia()
+{
+ OpenSetupInfoBar();
+
+ OpenSetupStatsBar();
+
+ OpenSetupStatusBar();
+
+ // OpenSetupToolBar();
+
+ OpenSetupCaptureBar();
+
+ __int64 rtDur = 0;
+ pMS->GetDuration(&rtDur);
+ m_wndPlaylistBar.SetCurTime(rtDur);
+
+ if(m_iPlaybackMode == PM_CAPTURE)
+ {
+ ShowControlBar(&m_wndSubresyncBar, FALSE, TRUE);
+// ShowControlBar(&m_wndPlaylistBar, FALSE, TRUE);
+// ShowControlBar(&m_wndCaptureBar, TRUE, TRUE);
+ }
+
+ m_iMediaLoadState = MLS_LOADED;
+
+ // IMPORTANT: must not call any windowing msgs before
+ // this point, it will deadlock when OpenMediaPrivate is
+ // still running and the renderer window was created on
+ // the same worker-thread
+
+ {
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(wp);
+ GetWindowPlacement(&wp);
+
+ // restore magnification
+ if(IsWindowVisible() && AfxGetAppSettings().fRememberZoomLevel
+ && !(m_fFullScreen || wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_SHOWMINIMIZED))
+ {
+ ZoomVideoWindow();
+ }
+ }
+
+ if(!m_fAudioOnly && (AfxGetAppSettings().nCLSwitches&CLSW_FULLSCREEN))
+ {
+ SendMessage(WM_COMMAND, ID_VIEW_FULLSCREEN);
+ AfxGetAppSettings().nCLSwitches &= ~CLSW_FULLSCREEN;
+ }
+
+ SendNowPlayingToMSN();
+ SendNowPlayingTomIRC();
+}
+
+void CMainFrame::OnUpdateFilePostOpenmedia(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADING);
+}
+
+void CMainFrame::OnFilePostClosemedia()
+{
+ m_wndView.SetVideoRect();
+ m_wndSeekBar.Enable(false);
+ m_wndSeekBar.SetPos(0);
+ m_wndInfoBar.RemoveAllLines();
+ m_wndStatsBar.RemoveAllLines();
+ m_wndStatusBar.Clear();
+ m_wndStatusBar.ShowTimer(false);
+
+ if(IsWindow(m_wndSubresyncBar.m_hWnd))
+ {
+ ShowControlBar(&m_wndSubresyncBar, FALSE, TRUE);
+ SetSubtitle(NULL);
+ }
+
+ if(IsWindow(m_wndCaptureBar.m_hWnd))
+ {
+ ShowControlBar(&m_wndCaptureBar, FALSE, TRUE);
+ m_wndCaptureBar.m_capdlg.SetupVideoControls(_T(""), NULL, NULL, NULL);
+ m_wndCaptureBar.m_capdlg.SetupAudioControls(_T(""), NULL, CInterfaceArray<IAMAudioInputMixer>());
+ }
+
+ RecalcLayout();
+
+ SetWindowText(ResStr(IDR_MAINFRAME));
+
+ SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
+
+ // this will prevent any further UI updates on the dynamically added menu items
+ SetupFiltersSubMenu();
+ SetupAudioSwitcherSubMenu();
+ SetupSubtitlesSubMenu();
+ SetupNavAudioSubMenu();
+ SetupNavSubtitleSubMenu();
+ SetupNavAngleSubMenu();
+ SetupNavChaptersSubMenu();
+ SetupFavoritesSubMenu();
+
+ SendNowPlayingToMSN();
+}
+
+void CMainFrame::OnUpdateFilePostClosemedia(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(!!m_hWnd && m_iMediaLoadState == MLS_CLOSING);
+}
+
+void CMainFrame::OnBossKey()
+{
+ SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
+ if(m_fFullScreen) SendMessage(WM_COMMAND, ID_VIEW_FULLSCREEN);
+ SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, -1);
+}
+
+void CMainFrame::OnStreamAudio(UINT nID)
+{
+ nID -= ID_STREAM_AUDIO_NEXT;
+
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ CComQIPtr<IAMStreamSelect> pSS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB);
+ if(!pSS) pSS = FindFilter(L"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB); // morgan's switcher
+
+ DWORD cStreams = 0;
+ if(pSS && SUCCEEDED(pSS->Count(&cStreams)) && cStreams > 1)
+ {
+ for(int i = 0; i < (int)cStreams; i++)
+ {
+ AM_MEDIA_TYPE* pmt = NULL;
+ DWORD dwFlags = 0;
+ LCID lcid = 0;
+ DWORD dwGroup = 0;
+ WCHAR* pszName = NULL;
+ if(FAILED(pSS->Info(i, &pmt, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL)))
+ return;
+ if(pmt) DeleteMediaType(pmt);
+ if(pszName) CoTaskMemFree(pszName);
+
+ if(dwFlags&(AMSTREAMSELECTINFO_ENABLED|AMSTREAMSELECTINFO_EXCLUSIVE))
+ {
+ pSS->Enable((i+(nID==0?1:cStreams-1))%cStreams, AMSTREAMSELECTENABLE_ENABLE);
+ break;
+ }
+ }
+ }
+ else if(m_iPlaybackMode == PM_FILE) SendMessage(WM_COMMAND, ID_OGM_AUDIO_NEXT+nID);
+ else if(m_iPlaybackMode == PM_DVD) SendMessage(WM_COMMAND, ID_DVD_AUDIO_NEXT+nID);
+}
+
+void CMainFrame::OnStreamSub(UINT nID)
+{
+ nID -= ID_STREAM_SUB_NEXT;
+
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ int cnt = 0;
+ POSITION pos = m_pSubStreams.GetHeadPosition();
+ while(pos) cnt += m_pSubStreams.GetNext(pos)->GetStreamCount();
+
+ if(cnt > 1)
+ {
+ int i = ((m_iSubtitleSel&0x7fffffff)+(nID==0?1:cnt-1))%cnt;
+ m_iSubtitleSel = i | (m_iSubtitleSel&0x80000000);
+ UpdateSubtitle();
+ SetFocus();
+ }
+ else if(m_iPlaybackMode == PM_FILE) SendMessage(WM_COMMAND, ID_OGM_SUB_NEXT+nID);
+ else if(m_iPlaybackMode == PM_DVD) SendMessage(WM_COMMAND, ID_DVD_SUB_NEXT+nID);
+}
+
+void CMainFrame::OnStreamSubOnOff()
+{
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ int cnt = 0;
+ POSITION pos = m_pSubStreams.GetHeadPosition();
+ while(pos) cnt += m_pSubStreams.GetNext(pos)->GetStreamCount();
+
+ if(cnt > 0)
+ {
+ m_iSubtitleSel ^= 0x80000000;
+ UpdateSubtitle();
+ SetFocus();
+ }
+ else if(m_iPlaybackMode == PM_DVD) SendMessage(WM_COMMAND, ID_DVD_SUB_ONOFF);
+}
+
+void CMainFrame::OnOgmAudio(UINT nID)
+{
+ nID -= ID_OGM_AUDIO_NEXT;
+
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ CComQIPtr<IAMStreamSelect> pSS = FindFilter(CLSID_OggSplitter, pGB);
+ if(!pSS) pSS = FindFilter(L"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB);
+ if(!pSS) return;
+
+ CAtlArray<int> snds;
+ int iSel = -1;
+
+ DWORD cStreams = 0;
+ if(SUCCEEDED(pSS->Count(&cStreams)) && cStreams > 1)
+ {
+ for(int i = 0; i < (int)cStreams; i++)
+ {
+ AM_MEDIA_TYPE* pmt = NULL;
+ DWORD dwFlags = 0;
+ LCID lcid = 0;
+ DWORD dwGroup = 0;
+ WCHAR* pszName = NULL;
+ if(FAILED(pSS->Info(i, &pmt, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL)))
+ return;
+
+ if(dwGroup == 1)
+ {
+ if(dwFlags&(AMSTREAMSELECTINFO_ENABLED|AMSTREAMSELECTINFO_EXCLUSIVE))
+ iSel = snds.GetCount();
+ snds.Add(i);
+ }
+
+ if(pmt) DeleteMediaType(pmt);
+ if(pszName) CoTaskMemFree(pszName);
+
+ }
+
+ int cnt = snds.GetCount();
+ if(cnt > 1 && iSel >= 0)
+ pSS->Enable(snds[(iSel+(nID==0?1:cnt-1))%cnt], AMSTREAMSELECTENABLE_ENABLE);
+ }
+}
+
+void CMainFrame::OnOgmSub(UINT nID)
+{
+ nID -= ID_OGM_SUB_NEXT;
+
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ CComQIPtr<IAMStreamSelect> pSS = FindFilter(CLSID_OggSplitter, pGB);
+ if(!pSS) pSS = FindFilter(L"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB);
+ if(!pSS) return;
+
+ CArray<int> subs;
+ int iSel = -1;
+
+ DWORD cStreams = 0;
+ if(SUCCEEDED(pSS->Count(&cStreams)) && cStreams > 1)
+ {
+ for(int i = 0; i < (int)cStreams; i++)
+ {
+ AM_MEDIA_TYPE* pmt = NULL;
+ DWORD dwFlags = 0;
+ LCID lcid = 0;
+ DWORD dwGroup = 0;
+ WCHAR* pszName = NULL;
+ if(FAILED(pSS->Info(i, &pmt, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL)))
+ return;
+
+ if(dwGroup == 2)
+ {
+ if(dwFlags&(AMSTREAMSELECTINFO_ENABLED|AMSTREAMSELECTINFO_EXCLUSIVE))
+ iSel = subs.GetCount();
+ subs.Add(i);
+ }
+
+ if(pmt) DeleteMediaType(pmt);
+ if(pszName) CoTaskMemFree(pszName);
+
+ }
+
+ int cnt = subs.GetCount();
+ if(cnt > 1 && iSel >= 0)
+ pSS->Enable(subs[(iSel+(nID==0?1:cnt-1))%cnt], AMSTREAMSELECTENABLE_ENABLE);
+ }
+}
+
+void CMainFrame::OnDvdAngle(UINT nID)
+{
+ nID -= ID_DVD_ANGLE_NEXT;
+
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ if(pDVDI && pDVDC)
+ {
+ ULONG ulAnglesAvailable, ulCurrentAngle;
+ if(SUCCEEDED(pDVDI->GetCurrentAngle(&ulAnglesAvailable, &ulCurrentAngle)) && ulAnglesAvailable > 1)
+ {
+ ulCurrentAngle += nID==0 ? 1 : ulAnglesAvailable-1;
+ if(ulCurrentAngle > ulAnglesAvailable) ulCurrentAngle = 1;
+ else if(ulCurrentAngle < 1) ulCurrentAngle = ulAnglesAvailable;
+ pDVDC->SelectAngle(ulCurrentAngle, DVD_CMD_FLAG_Block, NULL);
+ }
+ }
+}
+
+void CMainFrame::OnDvdAudio(UINT nID)
+{
+ HRESULT hr;
+ nID -= ID_DVD_AUDIO_NEXT;
+
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ if(pDVDI && pDVDC)
+ {
+ ULONG nStreamsAvailable, nCurrentStream;
+ if(SUCCEEDED(pDVDI->GetCurrentAudio(&nStreamsAvailable, &nCurrentStream)) && nStreamsAvailable > 1)
+ {
+ DVD_AudioAttributes AATR;
+ UINT nNextStream = (nCurrentStream+(nID==0?1:nStreamsAvailable-1))%nStreamsAvailable;
+
+ hr = pDVDC->SelectAudioStream(nNextStream, DVD_CMD_FLAG_Block, NULL);
+ if (SUCCEEDED(pDVDI->GetAudioAttributes(nNextStream, &AATR)))
+ {
+ CString lang;
+ CString strMessage;
+ int len = GetLocaleInfo(AATR.Language, LOCALE_SENGLANGUAGE, lang.GetBuffer(64), 64);
+ lang.ReleaseBufferSetLength(max(len-1, 0));
+ strMessage.Format (_T("Audio : %s - %s %s"), lang, GetDVDAudioFormatName(AATR), FAILED(hr)?_T("Error"):_T(""));
+ m_OSD.DisplayMessage (OSD_TOPLEFT, strMessage);
+ }
+ }
+ }
+}
+
+void CMainFrame::OnDvdSub(UINT nID)
+{
+ HRESULT hr;
+ nID -= ID_DVD_SUB_NEXT;
+
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ if(pDVDI && pDVDC)
+ {
+ ULONG ulStreamsAvailable, ulCurrentStream;
+ BOOL bIsDisabled;
+ if(SUCCEEDED(pDVDI->GetCurrentSubpicture(&ulStreamsAvailable, &ulCurrentStream, &bIsDisabled))
+ && ulStreamsAvailable > 1)
+ {
+// UINT nNextStream = (ulCurrentStream+(nID==0?1:ulStreamsAvailable-1))%ulStreamsAvailable;
+ int nNextStream;
+
+ if (!bIsDisabled)
+ nNextStream = ulCurrentStream+ (nID==0?1:-1);
+ else
+ nNextStream = (nID==0?0:ulStreamsAvailable-1);
+
+ if (!bIsDisabled && ((nNextStream < 0) || (nNextStream >= ulStreamsAvailable)))
+ {
+ pDVDC->SetSubpictureState(FALSE, DVD_CMD_FLAG_Block, NULL);
+ m_OSD.DisplayMessage (OSD_TOPLEFT, _T("Subtitle : off"));
+ }
+ else
+ {
+ hr = pDVDC->SelectSubpictureStream(nNextStream, DVD_CMD_FLAG_Block, NULL);
+
+ DVD_SubpictureAttributes SATR;
+ pDVDC->SetSubpictureState(TRUE, DVD_CMD_FLAG_Block, NULL);
+ if(SUCCEEDED(pDVDI->GetSubpictureAttributes(nNextStream, &SATR)))
+ {
+ CString lang;
+ CString strMessage;
+ int len = GetLocaleInfo(SATR.Language, LOCALE_SENGLANGUAGE, lang.GetBuffer(64), 64);
+ lang.ReleaseBufferSetLength(max(len-1, 0));
+ strMessage.Format (_T("Subtitle : %s %s"), lang, FAILED(hr)?_T("Error"):_T(""));
+ m_OSD.DisplayMessage (OSD_TOPLEFT, strMessage);
+ }
+ }
+ }
+ }
+}
+
+void CMainFrame::OnDvdSubOnOff()
+{
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ if(pDVDI && pDVDC)
+ {
+ ULONG ulStreamsAvailable, ulCurrentStream;
+ BOOL bIsDisabled;
+ if(SUCCEEDED(pDVDI->GetCurrentSubpicture(&ulStreamsAvailable, &ulCurrentStream, &bIsDisabled)))
+ {
+ pDVDC->SetSubpictureState(bIsDisabled, DVD_CMD_FLAG_Block, NULL);
+ }
+ }
+}
+
+//
+// menu item handlers
+//
+
+// file
+
+void CMainFrame::OnFileOpenQuick()
+{
+ if(m_iMediaLoadState == MLS_LOADING || !IsWindow(m_wndPlaylistBar)) return;
+
+ CString filter;
+ CAtlArray<CString> mask;
+ AfxGetAppSettings().Formats.GetFilter(filter, mask);
+
+ COpenFileDlg fd(mask, true, NULL, NULL,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT|OFN_ENABLEINCLUDENOTIFY,
+ filter, this);
+ if(fd.DoModal() != IDOK) return;
+
+ CAtlList<CString> fns;
+
+ POSITION pos = fd.GetStartPosition();
+ while(pos) fns.AddTail(fd.GetNextPathName(pos));
+
+ bool fMultipleFiles = false;
+
+ if(fns.GetCount() > 1
+ || fns.GetCount() == 1
+ && (fns.GetHead()[fns.GetHead().GetLength()-1] == '\\'
+ || fns.GetHead()[fns.GetHead().GetLength()-1] == '*'))
+ {
+ fMultipleFiles = true;
+ }
+
+ SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+
+ ShowWindow(SW_SHOW);
+ SetForegroundWindow();
+
+ m_wndPlaylistBar.Open(fns, fMultipleFiles);
+
+ if(m_wndPlaylistBar.GetCount() == 1 && m_wndPlaylistBar.IsWindowVisible() && !m_wndPlaylistBar.IsFloating())
+ {
+ ShowControlBar(&m_wndPlaylistBar, FALSE, TRUE);
+ }
+
+ OpenCurPlaylistItem();
+}
+
+void CMainFrame::OnFileOpenmedia()
+{
+ if(m_iMediaLoadState == MLS_LOADING || !IsWindow(m_wndPlaylistBar) || m_bD3DFullscreenMode) return;
+
+ COpenDlg dlg;
+ if(dlg.DoModal() != IDOK || dlg.m_fns.GetCount() == 0) return;
+
+ SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+
+ ShowWindow(SW_SHOW);
+ SetForegroundWindow();
+
+ if(dlg.m_fAppendPlaylist)
+ {
+ m_wndPlaylistBar.Append(dlg.m_fns, dlg.m_fMultipleFiles);
+ return;
+ }
+
+ m_wndPlaylistBar.Open(dlg.m_fns, dlg.m_fMultipleFiles);
+
+ if(m_wndPlaylistBar.GetCount() == 1 && m_wndPlaylistBar.IsWindowVisible() && !m_wndPlaylistBar.IsFloating())
+ {
+ ShowControlBar(&m_wndPlaylistBar, FALSE, TRUE);
+ }
+
+ OpenCurPlaylistItem();
+}
+
+void CMainFrame::OnUpdateFileOpen(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState != MLS_LOADING);
+}
+
+BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCDS)
+{
+ if(m_iMediaLoadState == MLS_LOADING || !IsWindow(m_wndPlaylistBar))
+ return FALSE;
+
+ if(pCDS->dwData != 0x6ABE51 || pCDS->cbData < sizeof(DWORD))
+ return FALSE;
+
+ DWORD len = *((DWORD*)pCDS->lpData);
+ TCHAR* pBuff = (TCHAR*)((DWORD*)pCDS->lpData + 1);
+ TCHAR* pBuffEnd = (TCHAR*)((BYTE*)pBuff + pCDS->cbData - sizeof(DWORD));
+
+ CAtlList<CString> cmdln;
+
+ while(len-- > 0)
+ {
+ CString str;
+ while(pBuff < pBuffEnd && *pBuff) str += *pBuff++;
+ pBuff++;
+ cmdln.AddTail(str);
+ }
+
+ AppSettings& s = AfxGetAppSettings();
+
+ s.ParseCommandLine(cmdln);
+
+ POSITION pos = s.slFilters.GetHeadPosition();
+ while(pos)
+ {
+ CString fullpath = MakeFullPath(s.slFilters.GetNext(pos));
+
+ CPath tmp(fullpath);
+ tmp.RemoveFileSpec();
+ tmp.AddBackslash();
+ CString path = tmp;
+
+ WIN32_FIND_DATA fd = {0};
+ HANDLE hFind = FindFirstFile(fullpath, &fd);
+ if(hFind != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) continue;
+
+ CFilterMapper2 fm2(false);
+ fm2.Register(path + fd.cFileName);
+ while(!fm2.m_filters.IsEmpty())
+ {
+ if(FilterOverride* f = fm2.m_filters.RemoveTail())
+ {
+ f->fTemporary = true;
+
+ bool fFound = false;
+
+ POSITION pos2 = s.filters.GetHeadPosition();
+ while(pos2)
+ {
+ FilterOverride* f2 = s.filters.GetNext(pos2);
+ if(f2->type == FilterOverride::EXTERNAL && !f2->path.CompareNoCase(f->path))
+ {
+ fFound = true;
+ break;
+ }
+ }
+
+ if(!fFound)
+ {
+ CAutoPtr<FilterOverride> p(f);
+ s.filters.AddHead(p);
+ }
+ }
+ }
+ }
+ while(FindNextFile(hFind, &fd));
+
+ FindClose(hFind);
+ }
+ }
+
+ bool fSetForegroundWindow = false;
+
+ if((s.nCLSwitches&CLSW_DVD) && !s.slFiles.IsEmpty())
+ {
+ SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+ fSetForegroundWindow = true;
+
+ CAutoPtr<OpenDVDData> p(new OpenDVDData());
+ if(p) {p->path = s.slFiles.GetHead(); p->subs.AddTailList(&s.slSubs);}
+ OpenMedia(p);
+ }
+ else if(s.nCLSwitches&CLSW_CD)
+ {
+ SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+ fSetForegroundWindow = true;
+
+ CAtlList<CString> sl;
+
+ if(!s.slFiles.IsEmpty())
+ {
+ GetCDROMType(s.slFiles.GetHead()[0], sl);
+ }
+ else
+ {
+ CString dir;
+ dir.ReleaseBufferSetLength(GetCurrentDirectory(MAX_PATH, dir.GetBuffer(MAX_PATH)));
+
+ GetCDROMType(dir[0], sl);
+
+ for(TCHAR drive = 'C'; sl.IsEmpty() && drive <= 'Z'; drive++)
+ {
+ GetCDROMType(drive, sl);
+ }
+ }
+
+ m_wndPlaylistBar.Open(sl, true);
+ OpenCurPlaylistItem();
+ }
+ else if(!s.slFiles.IsEmpty())
+ {
+ bool fMulti = s.slFiles.GetCount() > 1;
+
+ CAtlList<CString> sl;
+ sl.AddTailList(&s.slFiles);
+ if(!fMulti) sl.AddTailList(&s.slDubs);
+
+ if((s.nCLSwitches&CLSW_ADD) && m_wndPlaylistBar.GetCount() > 0)
+ {
+ m_wndPlaylistBar.Append(sl, fMulti, &s.slSubs);
+
+ if(s.nCLSwitches&(CLSW_OPEN|CLSW_PLAY))
+ {
+ m_wndPlaylistBar.SetLast();
+ OpenCurPlaylistItem();
+ }
+ }
+ else
+ {
+ SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+ fSetForegroundWindow = true;
+
+ m_wndPlaylistBar.Open(sl, fMulti, &s.slSubs);
+ OpenCurPlaylistItem((s.nCLSwitches&CLSW_STARTVALID) ? s.rtStart : 0);
+
+ s.nCLSwitches &= ~CLSW_STARTVALID;
+ s.rtStart = 0;
+ }
+ }
+ else
+ {
+ s.nCLSwitches = CLSW_NONE;
+ }
+
+ if(fSetForegroundWindow && !(s.nCLSwitches&CLSW_NOFOCUS))
+ SetForegroundWindow();
+
+ s.nCLSwitches &= ~CLSW_NOFOCUS;
+
+ return TRUE;
+}
+
+int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData)
+{
+ switch(uMsg)
+ {
+ case BFFM_INITIALIZED:
+ //Initial directory is set here
+ SendMessage(hwnd, BFFM_SETSELECTION, TRUE,(LPARAM)(LPCTSTR)AfxGetAppSettings().sDVDPath);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+
+void CMainFrame::OnFileOpendvd()
+{
+ if ((m_iMediaLoadState == MLS_LOADING) || m_bD3DFullscreenMode) return;
+
+ /*
+ SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+ SetForegroundWindow();
+
+ ShowWindow(SW_SHOW);
+
+ CAutoPtr<OpenDVDData> p(new OpenDVDData());
+ if(p)
+ {
+ AppSettings& s = AfxGetAppSettings();
+ if(s.fUseDVDPath && !s.sDVDPath.IsEmpty())
+ {
+ p->path = s.sDVDPath;
+ p->path.Replace('/', '\\');
+ if(p->path[p->path.GetLength()-1] != '\\') p->path += '\\';
+ }
+ }
+ OpenMedia(p);*/
+
+ AppSettings& s = AfxGetAppSettings();
+ TCHAR path[MAX_PATH];
+
+ BROWSEINFO bi;
+ bi.hwndOwner = m_hWnd;
+ bi.pidlRoot = NULL;
+ bi.pszDisplayName = path;
+ bi.lpszTitle = _T("Select the path for the DVD:");
+ bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_VALIDATE | BIF_USENEWUI | BIF_NONEWFOLDERBUTTON;
+ bi.lpfn = BrowseCallbackProc;
+ bi.lParam = 0;
+ bi.iImage = 0;
+
+ static LPITEMIDLIST iil;
+
+ if(iil = SHBrowseForFolder(&bi))
+ {
+ CAutoPtr<OpenDVDData> p(new OpenDVDData());
+
+ SHGetPathFromIDList(iil, path);
+
+ s.sDVDPath = path;
+ p->path = path;
+ p->path.Replace('/', '\\');
+ if(p->path[p->path.GetLength()-1] != '\\') p->path += '\\';
+
+ OpenMedia(p);
+ }
+}
+
+void CMainFrame::OnFileOpendevice()
+{
+ if(m_iMediaLoadState == MLS_LOADING) return;
+
+ COpenCapDeviceDlg capdlg;
+ if(capdlg.DoModal() != IDOK)
+ return;
+
+ SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+ SetForegroundWindow();
+
+ ShowWindow(SW_SHOW);
+
+ m_wndPlaylistBar.Empty();
+
+ CAutoPtr<OpenDeviceData> p(new OpenDeviceData());
+ if(p) {p->DisplayName[0] = capdlg.m_vidstr; p->DisplayName[1] = capdlg.m_audstr;}
+ OpenMedia(p);
+}
+
+void CMainFrame::OnFileOpenCD(UINT nID)
+{
+ nID -= ID_FILE_OPEN_CD_START;
+
+ nID++;
+ for(TCHAR drive = 'C'; drive <= 'Z'; drive++)
+ {
+ CAtlList<CString> sl;
+
+ switch(GetCDROMType(drive, sl))
+ {
+ case CDROM_Audio:
+ case CDROM_VideoCD:
+ case CDROM_DVDVideo:
+ nID--;
+ break;
+ default:
+ break;
+ }
+
+ if(nID == 0)
+ {
+ SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+ SetForegroundWindow();
+
+ ShowWindow(SW_SHOW);
+
+ m_wndPlaylistBar.Open(sl, true);
+ OpenCurPlaylistItem();
+
+ break;
+ }
+ }
+}
+
+void CMainFrame::OnDropFiles(HDROP hDropInfo)
+{
+ SetForegroundWindow();
+
+ if(m_wndPlaylistBar.IsWindowVisible())
+ {
+ m_wndPlaylistBar.OnDropFiles(hDropInfo);
+ return;
+ }
+
+ CAtlList<CString> sl;
+
+ UINT nFiles = ::DragQueryFile(hDropInfo, (UINT)-1, NULL, 0);
+
+ for(UINT iFile = 0; iFile < nFiles; iFile++)
+ {
+ CString fn;
+ fn.ReleaseBuffer(::DragQueryFile(hDropInfo, iFile, fn.GetBuffer(MAX_PATH), MAX_PATH));
+ sl.AddTail(fn);
+ }
+
+ ::DragFinish(hDropInfo);
+
+ if(sl.IsEmpty()) return;
+
+ if(sl.GetCount() == 1 && m_iMediaLoadState == MLS_LOADED && m_pCAP)
+ {
+ if(LoadSubtitle(sl.GetHead()))
+ {
+ SetSubtitle(m_pSubStreams.GetTail());
+ CPath p(sl.GetHead());
+ p.StripPath();
+ SendStatusMessage(CString((LPCTSTR)p) + _T(" loaded successfully"), 3000);
+ return;
+ }
+ }
+
+ m_wndPlaylistBar.Open(sl, true);
+ OpenCurPlaylistItem();
+}
+
+void CMainFrame::OnFileSaveAs()
+{
+ CString ext, in = m_wndPlaylistBar.GetCur(), out = in;
+
+ if(out.Find(_T("://")) < 0)
+ {
+ ext = CString(CPath(out).GetExtension()).MakeLower();
+ if(ext == _T(".cda")) out = out.Left(out.GetLength()-4) + _T(".wav");
+ else if(ext == _T(".ifo")) out = out.Left(out.GetLength()-4) + _T(".vob");
+ }
+ else
+ {
+ out.Empty();
+ }
+
+ CFileDialog fd(FALSE, 0, out,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST,
+ _T("All files (*.*)|*.*||"), this, 0);
+ if(fd.DoModal() != IDOK || !in.CompareNoCase(fd.GetPathName())) return;
+
+ CPath p(fd.GetPathName());
+ if(!ext.IsEmpty()) p.AddExtension(ext);
+
+ OAFilterState fs = State_Stopped;
+ pMC->GetState(0, &fs);
+ if(fs == State_Running) pMC->Pause();
+
+ CSaveDlg dlg(in, p);
+ dlg.DoModal();
+
+ if(fs == State_Running) pMC->Run();
+}
+
+void CMainFrame::OnUpdateFileSaveAs(CCmdUI* pCmdUI)
+{
+ if(m_iMediaLoadState != MLS_LOADED || m_iPlaybackMode != PM_FILE)
+ {
+ pCmdUI->Enable(FALSE);
+ return;
+ }
+
+ CString fn = m_wndPlaylistBar.GetCur();
+ CString ext = fn.Mid(fn.ReverseFind('.')+1).MakeLower();
+
+ if(fn.Find(_T("://")) >= 0)
+ {
+ pCmdUI->Enable(FALSE);
+ return;
+ }
+
+ if((GetVersion()&0x80000000) && (ext == _T("cda") || ext == _T("ifo")))
+ {
+ pCmdUI->Enable(FALSE);
+ return;
+ }
+
+ pCmdUI->Enable(TRUE);
+}
+
+bool CMainFrame::GetDIB(BYTE** ppData, long& size, bool fSilent)
+{
+ if(!ppData) return false;
+
+ *ppData = NULL;
+ size = 0;
+
+ bool fNeedsToPause = !m_pCAP;
+ if(fNeedsToPause) fNeedsToPause = !IsVMR7InGraph(pGB);
+ if(fNeedsToPause) fNeedsToPause = !IsVMR9InGraph(pGB);
+
+ OAFilterState fs = GetMediaState();
+
+ if(!(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && (fs == State_Paused || fs == State_Running)))
+ return false;
+
+ if(fs == State_Running && fNeedsToPause)
+ {
+ pMC->Pause();
+ GetMediaState(); // wait for completion of the pause command
+ }
+
+ HRESULT hr = S_OK;
+ CString errmsg;
+
+ do
+ {
+ if(m_pCAP)
+ {
+ hr = m_pCAP->GetDIB(NULL, (DWORD*)&size);
+ if(FAILED(hr)) {errmsg.Format(_T("GetDIB failed, hr = %08x"), hr); break;}
+
+ if(!(*ppData = new BYTE[size])) return false;
+
+ hr = m_pCAP->GetDIB(*ppData, (DWORD*)&size);
+ if(FAILED(hr)) {errmsg.Format(_T("GetDIB failed, hr = %08x"), hr); break;}
+ }
+ else
+ {
+ hr = pBV->GetCurrentImage(&size, NULL);
+ if(FAILED(hr) || size == 0) {errmsg.Format(_T("GetCurrentImage failed, hr = %08x"), hr); break;}
+
+ if(!(*ppData = new BYTE[size])) return false;
+
+ hr = pBV->GetCurrentImage(&size, (long*)*ppData);
+ if(FAILED(hr)) {errmsg.Format(_T("GetCurrentImage failed, hr = %08x"), hr); break;}
+ }
+ }
+ while(0);
+
+ if(!fSilent)
+ {
+ if(!errmsg.IsEmpty())
+ {
+ AfxMessageBox(errmsg, MB_OK);
+ }
+ }
+
+ if(fs == State_Running && GetMediaState() != State_Running)
+ {
+ pMC->Run();
+ }
+
+ if(FAILED(hr))
+ {
+ if(*ppData) {ASSERT(0); delete [] *ppData; *ppData = NULL;} // huh?
+ return false;
+ }
+
+ return true;
+}
+
+#include "jpeg.h"
+
+void CMainFrame::SaveDIB(LPCTSTR fn, BYTE* pData, long size)
+{
+ CString ext = CString(CPath(fn).GetExtension()).MakeLower();
+
+ if(ext == _T(".bmp"))
+ {
+ if(FILE* f = _tfopen(fn, _T("wb")))
+ {
+ BITMAPINFO* bi = (BITMAPINFO*)pData;
+
+ BITMAPFILEHEADER bfh;
+ bfh.bfType = 'MB';
+ bfh.bfOffBits = sizeof(bfh) + sizeof(bi->bmiHeader);
+ bfh.bfSize = sizeof(bfh) + size;
+ bfh.bfReserved1 = bfh.bfReserved2 = 0;
+
+ if(bi->bmiHeader.biBitCount <= 8)
+ {
+ if(bi->bmiHeader.biClrUsed) bfh.bfOffBits += bi->bmiHeader.biClrUsed * sizeof(bi->bmiColors[0]);
+ else bfh.bfOffBits += (1 << bi->bmiHeader.biBitCount) * sizeof(bi->bmiColors[0]);
+ }
+
+ fwrite(&bfh, 1, sizeof(bfh), f);
+ fwrite(pData, 1, size, f);
+
+ fclose(f);
+ }
+ else
+ {
+ AfxMessageBox(_T("Cannot create file"), MB_OK);
+ }
+ }
+ else if(ext == _T(".jpg"))
+ {
+ CJpegEncoderFile(fn).Encode(pData);
+ }
+
+ CPath p(fn);
+
+ if(CDC* pDC = m_wndStatusBar.m_status.GetDC())
+ {
+ CRect r;
+ m_wndStatusBar.m_status.GetClientRect(r);
+ p.CompactPath(pDC->m_hDC, r.Width());
+ m_wndStatusBar.m_status.ReleaseDC(pDC);
+ }
+
+ SendStatusMessage((LPCTSTR)p, 3000);
+}
+
+void CMainFrame::SaveImage(LPCTSTR fn)
+{
+ BYTE* pData = NULL;
+ long size = 0;
+
+ if(GetDIB(&pData, size))
+ {
+ SaveDIB(fn, pData, size);
+ delete [] pData;
+ }
+}
+
+void CMainFrame::SaveThumbnails(LPCTSTR fn)
+{
+ if(!pMC || !pMS || m_iPlaybackMode != PM_FILE /*&& m_iPlaybackMode != PM_DVD*/)
+ return;
+
+ REFERENCE_TIME rtPos = GetPos();
+ REFERENCE_TIME rtDur = GetDur();
+
+ if(rtDur <= 0)
+ {
+ AfxMessageBox(_T("Cannot create thumbnails for files with no duration"));
+ return;
+ }
+
+ pMC->Pause();
+ GetMediaState(); // wait for completion of the pause command
+
+ //
+
+ CSize video, wh(0, 0), arxy(0, 0);
+
+ if(m_pCAP)
+ {
+ wh = m_pCAP->GetVideoSize(false);
+ arxy = m_pCAP->GetVideoSize(true);
+ }
+ else
+ {
+ pBV->GetVideoSize(&wh.cx, &wh.cy);
+
+ long arx = 0, ary = 0;
+ CComQIPtr<IBasicVideo2> pBV2 = pBV;
+ if(pBV2 && SUCCEEDED(pBV2->GetPreferredAspectRatio(&arx, &ary)) && arx > 0 && ary > 0)
+ arxy.SetSize(arx, ary);
+ }
+
+ if(wh.cx <= 0 || wh.cy <= 0)
+ {
+ AfxMessageBox(_T("Failed to get video frame size"));
+ return;
+ }
+
+ // with the overlay mixer IBasicVideo2 won't tell the new AR when changed dynamically
+ DVD_VideoAttributes VATR;
+ if(m_iPlaybackMode == PM_DVD && SUCCEEDED(pDVDI->GetCurrentVideoAttributes(&VATR)))
+ arxy.SetSize(VATR.ulAspectX, VATR.ulAspectY);
+
+ video = (arxy.cx <= 0 || arxy.cy <= 0) ? wh : CSize(MulDiv(wh.cy, arxy.cx, arxy.cy), wh.cy);
+
+ //
+
+ AppSettings& s = AfxGetAppSettings();
+
+ int cols = s.ThumbCols, rows = s.ThumbRows;
+
+ int margin = 5;
+ int infoheight = 70;
+ int width = s.ThumbWidth;
+ int height = width * video.cy / video.cx * rows / cols + infoheight;
+
+ int dibsize = sizeof(BITMAPINFOHEADER) + width*height*4;
+
+ CAutoVectorPtr<BYTE> dib;
+ if(!dib.Allocate(dibsize))
+ {
+ AfxMessageBox(_T("Out of memory, go buy some more!"));
+ return;
+ }
+
+ BITMAPINFOHEADER* bih = (BITMAPINFOHEADER*)(BYTE*)dib;
+ memset(bih, 0, sizeof(BITMAPINFOHEADER));
+ bih->biSize = sizeof(BITMAPINFOHEADER);
+ bih->biWidth = width;
+ bih->biHeight = height;
+ bih->biPlanes = 1;
+ bih->biBitCount = 32;
+ bih->biCompression = BI_RGB;
+ bih->biSizeImage = width*height*4;
+ memsetd(bih + 1, 0xffffff, bih->biSizeImage);
+
+ SubPicDesc spd;
+ spd.w = width;
+ spd.h = height;
+ spd.bpp = 32;
+ spd.pitch = -width*4;
+ spd.bits = (BYTE*)(bih + 1) + (width*4)*(height-1);
+
+ {
+ BYTE* p = (BYTE*)spd.bits;
+ for(int y = 0; y < spd.h; y++, p += spd.pitch)
+ for(int x = 0; x < spd.w; x++)
+ ((DWORD*)p)[x] = 0x010101 * (0xe0 + 0x08*y/spd.h + 0x18*(spd.w-x)/spd.w);
+ }
+
+ CCritSec csSubLock;
+ RECT bbox;
+
+ for(int i = 1, pics = cols*rows; i <= pics; i++)
+ {
+ REFERENCE_TIME rt = rtDur * i / (pics+1);
+ DVD_HMSF_TIMECODE hmsf = RT2HMSF(rt, 25);
+
+ SeekTo(rt);
+
+ m_VolumeBeforeFrameStepping = m_wndToolBar.Volume;
+ pBA->put_Volume(-10000);
+
+ HRESULT hr = pFS ? pFS->Step(1, NULL) : E_FAIL;
+
+ if(FAILED(hr))
+ {
+ pBA->put_Volume(m_VolumeBeforeFrameStepping);
+ AfxMessageBox(_T("Cannot frame step, try a different video renderer."));
+ return;
+ }
+
+ HANDLE hGraphEvent = NULL;
+ pME->GetEventHandle((OAEVENT*)&hGraphEvent);
+
+ while(hGraphEvent && WaitForSingleObject(hGraphEvent, INFINITE) == WAIT_OBJECT_0)
+ {
+ LONG evCode = 0, evParam1, evParam2;
+ while(SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR*)&evParam1, (LONG_PTR*)&evParam2, 0)))
+ {
+ pME->FreeEventParams(evCode, evParam1, evParam2);
+ if(EC_STEP_COMPLETE == evCode) hGraphEvent = NULL;
+ }
+ }
+
+ pBA->put_Volume(m_VolumeBeforeFrameStepping);
+
+ int col = (i-1)%cols;
+ int row = (i-1)/cols;
+
+ CSize s((width-margin*2)/cols, (height-margin*2-infoheight)/rows);
+ CPoint p(margin+col*s.cx, margin+row*s.cy+infoheight);
+ CRect r(p, s);
+ r.DeflateRect(margin, margin);
+
+ CRenderedTextSubtitle rts(&csSubLock);
+ rts.CreateDefaultStyle(0);
+ rts.m_dstScreenSize.SetSize(width, height);
+ STSStyle* style = new STSStyle();
+ style->marginRect.SetRectEmpty();
+ rts.AddStyle(_T("thumbs"), style);
+
+ CStringW str;
+ str.Format(L"{\\an7\\1c&Hffffff&\\4a&Hb0&\\bord1\\shad4\\be1}{\\p1}m %d %d l %d %d %d %d %d %d{\\p}",
+ r.left, r.top, r.right, r.top, r.right, r.bottom, r.left, r.bottom);
+ rts.Add(str, true, 0, 1, _T("thumbs"));
+ str.Format(L"{\\an3\\1c&Hffffff&\\3c&H000000&\\alpha&H80&\\fs16\\b1\\bord2\\shad0\\pos(%d,%d)}%02d:%02d:%02d",
+ r.right-5, r.bottom-3, hmsf.bHours, hmsf.bMinutes, hmsf.bSeconds);
+ rts.Add(str, true, 1, 2, _T("thumbs"));
+
+ rts.Render(spd, 0, 25, bbox);
+
+ BYTE* pData = NULL;
+ long size = 0;
+ if(!GetDIB(&pData, size)) return;
+
+ BITMAPINFO* bi = (BITMAPINFO*)pData;
+
+ if(bi->bmiHeader.biBitCount != 32)
+ {
+ delete [] pData;
+ CString str;
+ str.Format(_T("Invalid image format, cannot create thumbnails out of %d bpp dibs."), bi->bmiHeader.biBitCount);
+ AfxMessageBox(str);
+ return;
+ }
+
+ int sw = bi->bmiHeader.biWidth;
+ int sh = abs(bi->bmiHeader.biHeight);
+ int sp = sw*4;
+ const BYTE* src = pData + sizeof(bi->bmiHeader);
+ if(bi->bmiHeader.biHeight >= 0) {src += sp*(sh-1); sp = -sp;}
+
+ int dw = spd.w;
+ int dh = spd.h;
+ int dp = spd.pitch;
+ BYTE* dst = (BYTE*)spd.bits + spd.pitch*r.top + r.left*4;
+
+ for(DWORD h = r.bottom - r.top, y = 0, yd = (sh<<8)/h; h > 0; y += yd, h--)
+ {
+ DWORD yf = y&0xff;
+ DWORD yi = y>>8;
+
+ DWORD* s0 = (DWORD*)(src + yi*sp);
+ DWORD* s1 = (DWORD*)(src + yi*sp + sp);
+ DWORD* d = (DWORD*)dst;
+
+ for(DWORD w = r.right - r.left, x = 0, xd = (sw<<8)/w; w > 0; x += xd, w--)
+ {
+ DWORD xf = x&0xff;
+ DWORD xi = x>>8;
+
+ DWORD c0 = s0[xi];
+ DWORD c1 = s0[xi+1];
+ DWORD c2 = s1[xi];
+ DWORD c3 = s1[xi+1];
+
+ c0 = ((c0&0xff00ff) + ((((c1&0xff00ff) - (c0&0xff00ff)) * xf) >> 8)) & 0xff00ff
+ | ((c0&0x00ff00) + ((((c1&0x00ff00) - (c0&0x00ff00)) * xf) >> 8)) & 0x00ff00;
+
+ c2 = ((c2&0xff00ff) + ((((c3&0xff00ff) - (c2&0xff00ff)) * xf) >> 8)) & 0xff00ff
+ | ((c2&0x00ff00) + ((((c3&0x00ff00) - (c2&0x00ff00)) * xf) >> 8)) & 0x00ff00;
+
+ c0 = ((c0&0xff00ff) + ((((c2&0xff00ff) - (c0&0xff00ff)) * yf) >> 8)) & 0xff00ff
+ | ((c0&0x00ff00) + ((((c2&0x00ff00) - (c0&0x00ff00)) * yf) >> 8)) & 0x00ff00;
+
+ *d++ = c0;
+ }
+
+ dst += dp;
+ }
+
+ rts.Render(spd, 10000, 25, bbox);
+
+ delete [] pData;
+ }
+
+ {
+ CRenderedTextSubtitle rts(&csSubLock);
+ rts.CreateDefaultStyle(0);
+ rts.m_dstScreenSize.SetSize(width, height);
+ STSStyle* style = new STSStyle();
+ style->marginRect.SetRect(margin*2, margin*2, margin*2, height-infoheight-margin);
+ rts.AddStyle(_T("thumbs"), style);
+
+ CStringW str;
+ str.Format(L"{\\an9\\fs%d\\b1\\bord0\\shad0\\1c&Hffffff&}%s", infoheight-10, width >= 550 ? L"Media Player Classic" : L"MPC");
+
+ rts.Add(str, true, 0, 1, _T("thumbs"), _T(""), _T(""), CRect(0,0,0,0), -1);
+
+ DVD_HMSF_TIMECODE hmsf = RT2HMSF(rtDur, 25);
+
+ CPath path(m_wndPlaylistBar.GetCur());
+ path.StripPath();
+ CStringW fn = (LPCTSTR)path;
+
+ CStringW fs;
+ WIN32_FIND_DATA wfd;
+ HANDLE hFind = FindFirstFile(m_wndPlaylistBar.GetCur(), &wfd);
+ if(hFind != INVALID_HANDLE_VALUE)
+ {
+ FindClose(hFind);
+
+ __int64 size = (__int64(wfd.nFileSizeHigh)<<32)|wfd.nFileSizeLow;
+ __int64 shortsize = size;
+ CStringW measure = _T("B");
+ if(shortsize > 10240) shortsize /= 1024, measure = L"KB";
+ if(shortsize > 10240) shortsize /= 1024, measure = L"MB";
+ if(shortsize > 10240) shortsize /= 1024, measure = L"GB";
+ fs.Format(L"File Size: %I64d%s (%I64d bytes)\\N", shortsize, measure, size);
+ }
+
+ CStringW ar;
+ if(arxy.cx > 0 && arxy.cy > 0 && arxy.cx != wh.cx && arxy.cy != wh.cy)
+ ar.Format(L"(%d:%d)", arxy.cx, arxy.cy);
+
+ str.Format(L"{\\an7\\1c&H000000&\\fs16\\b0\\bord0\\shad0}File Name: %s\\N%sResolution: %dx%d %s\\NDuration: %02d:%02d:%02d",
+ fn, fs, wh.cx, wh.cy, ar, hmsf.bHours, hmsf.bMinutes, hmsf.bSeconds);
+ rts.Add(str, true, 0, 1, _T("thumbs"));
+
+ rts.Render(spd, 0, 25, bbox);
+ }
+
+ SaveDIB(fn, (BYTE*)dib, dibsize);
+
+ SeekTo(rtPos);
+}
+
+static CString MakeSnapshotFileName(LPCTSTR prefix)
+{
+ CTime t = CTime::GetCurrentTime();
+ CString fn;
+ fn.Format(_T("%s%s%s"), prefix, t.Format(_T("%Y%m%d%H%M%S")), AfxGetAppSettings().SnapShotExt);
+ return fn;
+}
+
+void CMainFrame::OnFileSaveImage()
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ CPath psrc(s.SnapShotPath);
+ psrc.Combine(s.SnapShotPath, MakeSnapshotFileName(_T("snapshot")));
+
+ CFileDialog fd(FALSE, 0, (LPCTSTR)psrc,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST,
+ _T("Bitmaps (*.bmp)|*.bmp|Jpeg (*.jpg)|*.jpg||"), this, 0);
+
+ if(s.SnapShotExt == _T(".bmp")) fd.m_pOFN->nFilterIndex = 1;
+ else if(s.SnapShotExt == _T(".jpg")) fd.m_pOFN->nFilterIndex = 2;
+
+ if(fd.DoModal() != IDOK) return;
+
+ if(fd.m_pOFN->nFilterIndex == 1) s.SnapShotExt = _T(".bmp");
+ else if(fd.m_pOFN->nFilterIndex = 2) s.SnapShotExt = _T(".jpg");
+
+ CPath pdst(fd.GetPathName());
+ if(pdst.GetExtension().MakeLower() != s.SnapShotExt) pdst = CPath((LPCTSTR)pdst + s.SnapShotExt);
+ CString path = (LPCTSTR)pdst;
+ pdst.RemoveFileSpec();
+ s.SnapShotPath = (LPCTSTR)pdst;
+
+ SaveImage(path);
+}
+
+void CMainFrame::OnFileSaveImageAuto()
+{
+ CString fn;
+ fn.Format(_T("%s\\%s"), AfxGetAppSettings().SnapShotPath, MakeSnapshotFileName(_T("snapshot")));
+ SaveImage(fn);
+}
+
+void CMainFrame::OnUpdateFileSaveImage(CCmdUI* pCmdUI)
+{
+ OAFilterState fs = GetMediaState();
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && (fs == State_Paused || fs == State_Running));
+}
+
+void CMainFrame::OnFileSaveThumbnails()
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ CPath psrc(s.SnapShotPath);
+ psrc.Combine(s.SnapShotPath, MakeSnapshotFileName(_T("thumbs")));
+
+ CSaveThumbnailsDialog fd(
+ s.ThumbRows, s.ThumbCols, s.ThumbWidth,
+ 0, (LPCTSTR)psrc,
+ _T("Bitmaps (*.bmp)|*.bmp|Jpeg (*.jpg)|*.jpg||"), this);
+
+ if(s.SnapShotExt == _T(".bmp")) fd.m_pOFN->nFilterIndex = 1;
+ else if(s.SnapShotExt == _T(".jpg")) fd.m_pOFN->nFilterIndex = 2;
+
+ if(fd.DoModal() != IDOK) return;
+
+ if(fd.m_pOFN->nFilterIndex == 1) s.SnapShotExt = _T(".bmp");
+ else if(fd.m_pOFN->nFilterIndex = 2) s.SnapShotExt = _T(".jpg");
+
+ s.ThumbRows = fd.m_rows;
+ s.ThumbCols = fd.m_cols;
+ s.ThumbWidth = fd.m_width;
+
+ CPath pdst(fd.GetPathName());
+ if(pdst.GetExtension().MakeLower() != s.SnapShotExt) pdst = CPath((LPCTSTR)pdst + s.SnapShotExt);
+ CString path = (LPCTSTR)pdst;
+ pdst.RemoveFileSpec();
+ s.SnapShotPath = (LPCTSTR)pdst;
+
+ SaveThumbnails(path);
+}
+
+void CMainFrame::OnUpdateFileSaveThumbnails(CCmdUI* pCmdUI)
+{
+ OAFilterState fs = GetMediaState();
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && (m_iPlaybackMode == PM_FILE /*|| m_iPlaybackMode == PM_DVD*/));
+}
+
+void CMainFrame::OnFileConvert()
+{
+ CConvertDlg().DoModal();
+}
+
+void CMainFrame::OnUpdateFileConvert(CCmdUI* pCmdUI)
+{
+ // TODO: Add your command update UI handler code here
+}
+
+void CMainFrame::OnFileLoadsubtitle()
+{
+ if(!m_pCAP)
+ {
+ AfxMessageBox(_T("To load subtitles you have change the video renderer type and reopen the file.\n")
+ _T("- DirectShow: VMR7/VMR9 renderless or Haali's\n")
+ _T("- RealMedia: Special renderer for RealMedia, or open it through DirectShow\n")
+ _T("- Quicktime: DX7 or DX9 renderer for QuickTime\n")
+ _T("- ShockWave: n/a\n")
+ , MB_OK);
+ return;
+ }
+
+ static TCHAR BASED_CODE szFilter[] =
+ _T(".srt .sub .ssa .ass .smi .psb .txt .idx .usf .xss|")
+ _T("*.srt;*.sub;*.ssa;*.ass;*smi;*.psb;*.txt;*.idx;*.usf;*.xss||");
+
+ CFileDialog fd(TRUE, NULL, NULL,
+ OFN_EXPLORER | OFN_ENABLESIZING | OFN_HIDEREADONLY,
+ szFilter, this, 0);
+
+ if(fd.DoModal() != IDOK) return;
+
+ if(LoadSubtitle(fd.GetPathName()))
+ SetSubtitle(m_pSubStreams.GetTail());
+}
+
+void CMainFrame::OnUpdateFileLoadsubtitle(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && /*m_pCAP &&*/ !m_fAudioOnly);
+}
+
+void CMainFrame::OnFileSavesubtitle()
+{
+ int i = m_iSubtitleSel;
+
+ POSITION pos = m_pSubStreams.GetHeadPosition();
+ while(pos && i >= 0)
+ {
+ CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
+
+ if(i < pSubStream->GetStreamCount())
+ {
+ CLSID clsid;
+ if(FAILED(pSubStream->GetClassID(&clsid)))
+ continue;
+
+ if(clsid == __uuidof(CVobSubFile))
+ {
+ CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)pSubStream;
+
+ CFileDialog fd(FALSE, NULL, NULL,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST,
+ _T("VobSub (*.idx, *.sub)|*.idx;*.sub||"), this, 0);
+
+ if(fd.DoModal() == IDOK)
+ {
+ CAutoLock cAutoLock(&m_csSubLock);
+ pVSF->Save(fd.GetPathName());
+ }
+
+ return;
+ }
+ else if(clsid == __uuidof(CRenderedTextSubtitle))
+ {
+ CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)pSubStream;
+
+ CString filter;
+ filter += _T("Subripper (*.srt)|*.srt|");
+ filter += _T("Microdvd (*.sub)|*.sub|");
+ filter += _T("Sami (*.smi)|*.smi|");
+ filter += _T("Psb (*.psb)|*.psb|");
+ filter += _T("Sub Station Alpha (*.ssa)|*.ssa|");
+ filter += _T("Advanced Sub Station Alpha (*.ass)|*.ass|");
+ filter += _T("|");
+
+ CSaveTextFileDialog fd(pRTS->m_encoding, NULL, NULL, filter, this);
+
+ if(fd.DoModal() == IDOK)
+ {
+ CAutoLock cAutoLock(&m_csSubLock);
+ pRTS->SaveAs(fd.GetPathName(), (exttype)(fd.m_ofn.nFilterIndex-1), m_pCAP->GetFPS(), fd.GetEncoding());
+ }
+
+ return;
+ }
+ }
+
+ i -= pSubStream->GetStreamCount();
+ }
+}
+
+void CMainFrame::OnUpdateFileSavesubtitle(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iSubtitleSel >= 0);
+}
+
+///////////////
+
+#include "SubtitleDlDlg.h"
+#include "ISDb.h"
+
+void CMainFrame::OnFileISDBSearch()
+{
+ CStringA url = "http://" + AfxGetAppSettings().ISDb + "/index.php?";
+ CStringA args = makeargs(m_wndPlaylistBar.m_pl);
+ ShellExecute(m_hWnd, _T("open"), CString(url+args), NULL, NULL, SW_SHOWDEFAULT);
+}
+
+void CMainFrame::OnUpdateFileISDBSearch(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(TRUE);
+}
+
+void CMainFrame::OnFileISDBUpload()
+{
+ CStringA url = "http://" + AfxGetAppSettings().ISDb + "/ul.php?";
+ CStringA args = makeargs(m_wndPlaylistBar.m_pl);
+ ShellExecute(m_hWnd, _T("open"), CString(url+args), NULL, NULL, SW_SHOWDEFAULT);
+}
+
+void CMainFrame::OnUpdateFileISDBUpload(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(m_wndPlaylistBar.GetCount() > 0);
+}
+
+void CMainFrame::OnFileISDBDownload()
+{
+ filehash fh;
+ if(!hash(m_wndPlaylistBar.GetCur(), fh))
+ {
+ MessageBeep(-1);
+ return;
+ }
+
+ // TODO: put this on a worker thread
+
+ CStringA url = "http://" + AfxGetAppSettings().ISDb + "/index.php?";
+ CStringA args;
+ args.Format("player=mpc&name[0]=%s&size[0]=%016I64x&hash[0]=%016I64x",
+ UrlEncode(CStringA(fh.name)), fh.size, fh.hash);
+
+ try
+ {
+ CInternetSession is;
+
+ CStringA str;
+ if(!OpenUrl(is, CString(url+args), str))
+ {
+ MessageBeep(-1);
+ return;
+ }
+
+ CStringA ticket;
+ CList<isdb_movie> movies;
+ isdb_movie m;
+ isdb_subtitle s;
+
+ CAtlList<CStringA> sl;
+ Explode(str, sl, '\n');
+
+ POSITION pos = sl.GetHeadPosition();
+ while(pos)
+ {
+ str = sl.GetNext(pos);
+
+ CStringA param = str.Left(max(0, str.Find('=')));
+ CStringA value = str.Mid(str.Find('=')+1);
+
+ if(param == "ticket") ticket = value;
+ else if(param == "movie") {m.reset(); Explode(value, m.titles, '|');}
+ else if(param == "subtitle") {s.reset(); s.id = atoi(value);}
+ else if(param == "name") s.name = value;
+ else if(param == "discs") s.discs = atoi(value);
+ else if(param == "disc_no") s.disc_no = atoi(value);
+ else if(param == "format") s.format = value;
+ else if(param == "iso639_2") s.iso639_2 = value;
+ else if(param == "language") s.language = value;
+ else if(param == "nick") s.nick = value;
+ else if(param == "email") s.email = value;
+ else if(param == "" && value == "endsubtitle") {m.subs.AddTail(s);}
+ else if(param == "" && value == "endmovie") {movies.AddTail(m);}
+ else if(param == "" && value == "end") break;
+ }
+
+ CSubtitleDlDlg dlg(movies, this);
+ if(IDOK == dlg.DoModal())
+ {
+ if(dlg.m_fReplaceSubs)
+ m_pSubStreams.RemoveAll();
+
+ CComPtr<ISubStream> pSubStreamToSet;
+
+ POSITION pos = dlg.m_selsubs.GetHeadPosition();
+ while(pos)
+ {
+ isdb_subtitle& s = dlg.m_selsubs.GetNext(pos);
+
+ CStringA url = "http://" + AfxGetAppSettings().ISDb + "/dl.php?";
+ CStringA args;
+ args.Format("id=%d&ticket=%s", s.id, UrlEncode(ticket));
+
+ if(OpenUrl(is, CString(url+args), str))
+ {
+ CAutoPtr<CRenderedTextSubtitle> pRTS(new CRenderedTextSubtitle(&m_csSubLock));
+ if(pRTS && pRTS->Open((BYTE*)(LPCSTR)str, str.GetLength(), DEFAULT_CHARSET, CString(s.name)) && pRTS->GetStreamCount() > 0)
+ {
+ CComPtr<ISubStream> pSubStream = pRTS.Detach();
+ m_pSubStreams.AddTail(pSubStream);
+ if(!pSubStreamToSet) pSubStreamToSet = pSubStream;
+ }
+ }
+ }
+
+ if(pSubStreamToSet)
+ SetSubtitle(pSubStreamToSet);
+ }
+ }
+ catch(CInternetException* ie)
+ {
+ ie->Delete();
+ return;
+ }
+}
+
+void CMainFrame::OnUpdateFileISDBDownload(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && m_pCAP && !m_fAudioOnly);
+}
+
+void CMainFrame::OnFileProperties()
+{
+ CPPageFileInfoSheet m_fileinfo(m_wndPlaylistBar.GetCur(), this);
+ m_fileinfo.DoModal();
+}
+
+void CMainFrame::OnUpdateFileProperties(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && m_iPlaybackMode == PM_FILE);
+}
+
+void CMainFrame::OnFileCloseMedia()
+{
+ CloseMedia();
+}
+
+void CMainFrame::OnUpdateViewTearingTest(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable (TRUE);
+}
+
+void CMainFrame::OnViewTearingTest()
+{
+ AfxGetMyApp()->m_fTearingTest = ! AfxGetMyApp()->m_fTearingTest;
+}
+
+void CMainFrame::OnUpdateViewRemainingTime(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable (m_iMediaLoadState != MLS_CLOSED);
+}
+
+void CMainFrame::OnViewRemainingTime()
+{
+ m_bRemainingTime = !m_bRemainingTime;
+ if (!m_bRemainingTime) m_OSD.ClearMessage();
+}
+
+void CMainFrame::OnUpdateShaderToggle(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable (TRUE);
+}
+
+void CMainFrame::OnShaderToggle()
+{
+ static bool bToggleShader = false;
+
+ if (bToggleShader)
+ {
+ SetShaders();
+ m_OSD.DisplayMessage (OSD_TOPRIGHT, _T("Pixel Shader on"));
+ }
+ else
+ {
+ m_pCAP->SetPixelShader(NULL, NULL);
+ m_OSD.DisplayMessage (OSD_TOPRIGHT, _T("Pixel Shader off"));
+ }
+
+ bToggleShader = !bToggleShader;
+}
+
+void CMainFrame::OnFileClosePlaylist()
+{
+ SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+ RestoreDefaultWindowRect();
+}
+
+void CMainFrame::OnUpdateFileClose(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED || m_iMediaLoadState == MLS_LOADING);
+}
+
+// view
+
+void CMainFrame::OnViewCaptionmenu()
+{
+ bool fHideCaptionMenu = AfxGetAppSettings().fHideCaptionMenu;
+
+ AfxGetAppSettings().fHideCaptionMenu = !fHideCaptionMenu;
+
+ if(m_fFullScreen) return;
+
+ DWORD dwRemove = 0, dwAdd = 0;
+ HMENU hMenu;
+
+ if(!fHideCaptionMenu)
+ {
+ dwRemove = WS_CAPTION;
+ hMenu = NULL;
+ }
+ else
+ {
+ dwAdd = WS_CAPTION;
+ hMenu = m_hMenuDefault;
+ }
+
+ ModifyStyle(dwRemove, dwAdd, SWP_NOZORDER);
+ ::SetMenu(m_hWnd, hMenu);
+ SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
+
+ MoveVideoWindow();
+}
+
+void CMainFrame::OnUpdateViewCaptionmenu(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(!AfxGetAppSettings().fHideCaptionMenu);
+}
+
+void CMainFrame::OnViewControlBar(UINT nID)
+{
+ nID -= ID_VIEW_SEEKER;
+ ShowControls(AfxGetAppSettings().nCS ^ (1<<nID));
+}
+
+void CMainFrame::OnUpdateViewControlBar(CCmdUI* pCmdUI)
+{
+ UINT nID = pCmdUI->m_nID - ID_VIEW_SEEKER;
+ pCmdUI->SetCheck(!!(AfxGetAppSettings().nCS & (1<<nID)));
+}
+
+
+void CMainFrame::OnViewSubresync()
+{
+ ShowControlBar(&m_wndSubresyncBar, !m_wndSubresyncBar.IsWindowVisible(), TRUE);
+}
+
+void CMainFrame::OnUpdateViewSubresync(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(m_wndSubresyncBar.IsWindowVisible());
+ pCmdUI->Enable(m_pCAP && m_iSubtitleSel >= 0);
+}
+
+void CMainFrame::OnViewPlaylist()
+{
+ ShowControlBar(&m_wndPlaylistBar, !m_wndPlaylistBar.IsWindowVisible(), TRUE);
+}
+
+void CMainFrame::OnUpdateViewPlaylist(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(m_wndPlaylistBar.IsWindowVisible());
+ pCmdUI->Enable(m_iMediaLoadState == MLS_CLOSED && m_iMediaLoadState != MLS_LOADED
+ || m_iMediaLoadState == MLS_LOADED /*&& (m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)*/);
+}
+
+void CMainFrame::OnViewCapture()
+{
+ ShowControlBar(&m_wndCaptureBar, !m_wndCaptureBar.IsWindowVisible(), TRUE);
+}
+
+void CMainFrame::OnUpdateViewCapture(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(m_wndCaptureBar.IsWindowVisible());
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && m_iPlaybackMode == PM_CAPTURE);
+}
+
+void CMainFrame::OnViewShaderEditor()
+{
+ ShowControlBar(&m_wndShaderEditorBar, !m_wndShaderEditorBar.IsWindowVisible(), TRUE);
+}
+
+void CMainFrame::OnUpdateViewShaderEditor(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(m_wndShaderEditorBar.IsWindowVisible());
+ pCmdUI->Enable(TRUE);
+}
+
+void CMainFrame::OnViewMinimal()
+{
+ if(!AfxGetAppSettings().fHideCaptionMenu)
+ SendMessage(WM_COMMAND, ID_VIEW_CAPTIONMENU);
+ ShowControls(0);
+}
+
+void CMainFrame::OnUpdateViewMinimal(CCmdUI* pCmdUI)
+{
+}
+
+void CMainFrame::OnViewCompact()
+{
+ if(AfxGetAppSettings().fHideCaptionMenu)
+ SendMessage(WM_COMMAND, ID_VIEW_CAPTIONMENU);
+ ShowControls(CS_TOOLBAR);
+}
+
+void CMainFrame::OnUpdateViewCompact(CCmdUI* pCmdUI)
+{
+}
+
+void CMainFrame::OnViewNormal()
+{
+ if(AfxGetAppSettings().fHideCaptionMenu)
+ SendMessage(WM_COMMAND, ID_VIEW_CAPTIONMENU);
+ ShowControls(CS_SEEKBAR|CS_TOOLBAR|CS_STATUSBAR|CS_INFOBAR);
+}
+
+void CMainFrame::OnUpdateViewNormal(CCmdUI* pCmdUI)
+{
+}
+
+void CMainFrame::OnViewFullscreen()
+{
+ ToggleFullscreen(true, true);
+}
+
+void CMainFrame::OnViewFullscreenSecondary()
+{
+ ToggleFullscreen(true, false);
+}
+
+void CMainFrame::OnUpdateViewFullscreen(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly || m_fFullScreen);
+ pCmdUI->SetCheck(m_fFullScreen);
+}
+
+void CMainFrame::OnViewZoom(UINT nID)
+{
+ ZoomVideoWindow(nID == ID_VIEW_ZOOM_50 ? 0.5 : nID == ID_VIEW_ZOOM_200 ? 2.0 : 1.0);
+}
+
+void CMainFrame::OnUpdateViewZoom(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
+}
+
+void CMainFrame::OnViewZoomAutoFit()
+{
+ ZoomVideoWindow(GetZoomAutoFitScale());
+}
+
+void CMainFrame::OnViewDefaultVideoFrame(UINT nID)
+{
+ AfxGetAppSettings().iDefaultVideoSize = nID - ID_VIEW_VF_HALF;
+ m_ZoomX = m_ZoomY = 1;
+ m_PosX = m_PosY = 0.5;
+ MoveVideoWindow();
+}
+
+void CMainFrame::OnUpdateViewDefaultVideoFrame(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
+ pCmdUI->SetRadio(AfxGetAppSettings().iDefaultVideoSize == (pCmdUI->m_nID - ID_VIEW_VF_HALF));
+}
+
+void CMainFrame::OnViewKeepaspectratio()
+{
+ AfxGetAppSettings().fKeepAspectRatio = !AfxGetAppSettings().fKeepAspectRatio;
+ MoveVideoWindow();
+}
+
+void CMainFrame::OnUpdateViewKeepaspectratio(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
+ pCmdUI->SetCheck(AfxGetAppSettings().fKeepAspectRatio);
+}
+
+void CMainFrame::OnViewCompMonDeskARDiff()
+{
+ AfxGetAppSettings().fCompMonDeskARDiff = !AfxGetAppSettings().fCompMonDeskARDiff;
+ MoveVideoWindow();
+}
+
+void CMainFrame::OnUpdateViewCompMonDeskARDiff(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
+ pCmdUI->SetCheck(AfxGetAppSettings().fCompMonDeskARDiff);
+}
+
+void CMainFrame::OnViewPanNScan(UINT nID)
+{
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ int x = 0, y = 0;
+ int dx = 0, dy = 0;
+
+ switch(nID)
+ {
+ case ID_VIEW_RESET: m_ZoomX = m_ZoomY = 1.0; m_PosX = m_PosY = 0.5; m_AngleX = m_AngleY = m_AngleZ = 0; break;
+ case ID_VIEW_INCSIZE: x = y = 1; break;
+ case ID_VIEW_DECSIZE: x = y = -1; break;
+ case ID_VIEW_INCWIDTH: x = 1; break;
+ case ID_VIEW_DECWIDTH: x = -1; break;
+ case ID_VIEW_INCHEIGHT: y = 1; break;
+ case ID_VIEW_DECHEIGHT: y = -1; break;
+ case ID_PANSCAN_CENTER: m_PosX = m_PosY = 0.5; break;
+ case ID_PANSCAN_MOVELEFT: dx = -1; break;
+ case ID_PANSCAN_MOVERIGHT: dx = 1; break;
+ case ID_PANSCAN_MOVEUP: dy = -1; break;
+ case ID_PANSCAN_MOVEDOWN: dy = 1; break;
+ case ID_PANSCAN_MOVEUPLEFT: dx = dy = -1; break;
+ case ID_PANSCAN_MOVEUPRIGHT: dx = 1; dy = -1; break;
+ case ID_PANSCAN_MOVEDOWNLEFT: dx = -1; dy = 1; break;
+ case ID_PANSCAN_MOVEDOWNRIGHT: dx = dy = 1; break;
+ default: break;
+ }
+
+ if(x > 0 && m_ZoomX < 3) m_ZoomX *= 1.02;
+ if(x < 0 && m_ZoomX > 0.2) m_ZoomX /= 1.02;
+ if(y > 0 && m_ZoomY < 3) m_ZoomY *= 1.02;
+ if(y < 0 && m_ZoomY > 0.2) m_ZoomY /= 1.02;
+
+ if(dx < 0 && m_PosX > 0) m_PosX = max(m_PosX - 0.005*m_ZoomX, 0);
+ if(dx > 0 && m_PosX < 1) m_PosX = min(m_PosX + 0.005*m_ZoomX, 1);
+ if(dy < 0 && m_PosY > 0) m_PosY = max(m_PosY - 0.005*m_ZoomY, 0);
+ if(dy > 0 && m_PosY < 1) m_PosY = min(m_PosY + 0.005*m_ZoomY, 1);
+
+ MoveVideoWindow(true);
+}
+
+void CMainFrame::OnUpdateViewPanNScan(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
+}
+
+void CMainFrame::OnViewPanNScanPresets(UINT nID)
+{
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ AppSettings& s = AfxGetAppSettings();
+
+ nID -= ID_PANNSCAN_PRESETS_START;
+
+ if(nID == s.m_pnspresets.GetCount())
+ {
+ CPnSPresetsDlg dlg;
+ dlg.m_pnspresets.Copy(s.m_pnspresets);
+ if(dlg.DoModal() == IDOK)
+ {
+ s.m_pnspresets.Copy(dlg.m_pnspresets);
+ s.UpdateData(true);
+ }
+ return;
+ }
+
+ m_PosX = 0.5;
+ m_PosY = 0.5;
+ m_ZoomX = 1.0;
+ m_ZoomY = 1.0;
+
+ CString str = s.m_pnspresets[nID];
+
+ int i = 0, j = 0;
+ for(CString token = str.Tokenize(_T(","), i); !token.IsEmpty(); token = str.Tokenize(_T(","), i), j++)
+ {
+ float f = 0;
+ if(_stscanf(token, _T("%f"), &f) != 1) continue;
+
+ switch(j)
+ {
+ case 0: break;
+ case 1: m_PosX = f; break;
+ case 2: m_PosY = f; break;
+ case 3: m_ZoomX = f; break;
+ case 4: m_ZoomY = f; break;
+ default: break;
+ }
+ }
+
+ if(j != 5) return;
+
+ m_PosX = min(max(m_PosX, 0), 1);
+ m_PosY = min(max(m_PosY, 0), 1);
+ m_ZoomX = min(max(m_ZoomX, 0.2), 3);
+ m_ZoomY = min(max(m_ZoomY, 0.2), 3);
+
+ MoveVideoWindow(true);
+}
+
+void CMainFrame::OnUpdateViewPanNScanPresets(CCmdUI* pCmdUI)
+{
+ int nID = pCmdUI->m_nID - ID_PANNSCAN_PRESETS_START;
+ AppSettings& s = AfxGetAppSettings();
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && nID >= 0 && nID <= s.m_pnspresets.GetCount());
+}
+
+void CMainFrame::OnViewRotate(UINT nID)
+{
+ if(!m_pCAP) return;
+
+ switch(nID)
+ {
+ case ID_PANSCAN_ROTATEXP: m_AngleX += 2; break;
+ case ID_PANSCAN_ROTATEXM: m_AngleX -= 2; break;
+ case ID_PANSCAN_ROTATEYP: m_AngleY += 2; break;
+ case ID_PANSCAN_ROTATEYM: m_AngleY -= 2; break;
+ case ID_PANSCAN_ROTATEZP: m_AngleZ += 2; break;
+ case ID_PANSCAN_ROTATEZM: m_AngleZ -= 2; break;
+ default: return;
+ }
+
+ m_pCAP->SetVideoAngle(Vector(DegToRad(m_AngleX), DegToRad(m_AngleY), DegToRad(m_AngleZ)));
+
+ CString info;
+ info.Format(_T("x: %d, y: %d, z: %d"), m_AngleX, m_AngleY, m_AngleZ);
+ SendStatusMessage(info, 3000);
+}
+
+void CMainFrame::OnUpdateViewRotate(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && m_pCAP);
+}
+
+// FIXME
+const static SIZE s_ar[] = {{0,0}, {4,3}, {5,4}, {16,9}};
+
+void CMainFrame::OnViewAspectRatio(UINT nID)
+{
+ CSize& ar = AfxGetAppSettings().AspectRatio;
+
+ ar = s_ar[nID - ID_ASPECTRATIO_START];
+
+ CString info;
+ if(ar.cx && ar.cy) info.Format(_T("Aspect Ratio: %d:%d"), ar.cx, ar.cy);
+ else info.Format(_T("Aspect Ratio: Default"));
+ SendStatusMessage(info, 3000);
+
+ MoveVideoWindow();
+}
+
+void CMainFrame::OnUpdateViewAspectRatio(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetRadio(AfxGetAppSettings().AspectRatio == s_ar[pCmdUI->m_nID - ID_ASPECTRATIO_START]);
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
+}
+
+void CMainFrame::OnViewAspectRatioNext()
+{
+ CSize& ar = AfxGetAppSettings().AspectRatio;
+
+ UINT nID = ID_ASPECTRATIO_START;
+
+ for(int i = 0; i < countof(s_ar); i++)
+ {
+ if(ar == s_ar[i])
+ {
+ nID += (i + 1) % countof(s_ar);
+ break;
+ }
+ }
+
+ OnViewAspectRatio(nID);
+}
+
+void CMainFrame::OnViewOntop(UINT nID)
+{
+ nID -= ID_ONTOP_NEVER;
+ if(AfxGetAppSettings().iOnTop == nID)
+ nID = !nID;
+ SetAlwaysOnTop(nID);
+}
+
+void CMainFrame::OnUpdateViewOntop(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetRadio(AfxGetAppSettings().iOnTop == (pCmdUI->m_nID - ID_ONTOP_NEVER));
+}
+
+void CMainFrame::OnViewOptions()
+{
+ ShowOptions();
+}
+
+// play
+
+#include "IPinHook.h"
+
+void CMainFrame::OnPlayPlay()
+{
+ if(m_iMediaLoadState == MLS_LOADED)
+ {
+ if(GetMediaState() == State_Stopped) m_iSpeedLevel = 0;
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ m_iSpeedLevel = 0;
+ if(m_fEndOfStream) SendMessage(WM_COMMAND, ID_PLAY_STOP);
+ pMS->SetRate (1.0);
+ pMC->Run();
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ double dRate = 1.0;
+ m_iSpeedLevel = 0;
+
+ pDVDC->PlayForwards(dRate, DVD_CMD_FLAG_Block, NULL);
+ pDVDC->Pause(FALSE);
+ pMC->Run();
+ }
+ else if(m_iPlaybackMode == PM_CAPTURE)
+ {
+ pMC->Stop(); // audio preview won't be in sync if we run it from paused state
+ pMC->Run();
+ }
+
+ SetTimer(TIMER_STREAMPOSPOLLER, 40, NULL);
+ SetTimer(TIMER_STREAMPOSPOLLER2, 500, NULL);
+ SetTimer(TIMER_STATS, 1000, NULL);
+
+ if(m_fFrameSteppingActive) // FIXME
+ {
+ m_fFrameSteppingActive = false;
+ pBA->put_Volume(m_VolumeBeforeFrameStepping);
+ }
+
+ SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
+ }
+
+ MoveVideoWindow();
+}
+
+void CMainFrame::OnPlayPause()
+{
+ if(m_iMediaLoadState == MLS_LOADED)
+ {
+ SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ pMC->Pause();
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ pMC->Pause();
+ }
+ else if(m_iPlaybackMode == PM_CAPTURE)
+ {
+ pMC->Pause();
+ }
+
+ SetTimer(TIMER_STREAMPOSPOLLER, 40, NULL);
+ SetTimer(TIMER_STREAMPOSPOLLER2, 500, NULL);
+ SetTimer(TIMER_STATS, 1000, NULL);
+ }
+
+ MoveVideoWindow();
+}
+
+void CMainFrame::OnPlayPlaypause()
+{
+ OAFilterState fs = GetMediaState();
+ if(fs == State_Running) SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
+ else if(fs == State_Stopped || fs == State_Paused) SendMessage(WM_COMMAND, ID_PLAY_PLAY);
+}
+
+void CMainFrame::OnPlayStop()
+{
+ if(m_iMediaLoadState == MLS_LOADED)
+ {
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ LONGLONG pos = 0;
+ pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
+ pMC->Stop();
+
+ // BUG: after pause or stop the netshow url source filter won't continue
+ // on the next play command, unless we cheat it by setting the file name again.
+ //
+ // Note: WMPx may be using some undocumented interface to restart streaming.
+
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ CComQIPtr<IAMNetworkStatus, &IID_IAMNetworkStatus> pAMNS = pBF;
+ CComQIPtr<IFileSourceFilter> pFSF = pBF;
+ if(pAMNS && pFSF)
+ {
+ WCHAR* pFN = NULL;
+ AM_MEDIA_TYPE mt;
+ if(SUCCEEDED(pFSF->GetCurFile(&pFN, &mt)) && pFN && *pFN)
+ {
+ pFSF->Load(pFN, NULL);
+ CoTaskMemFree(pFN);
+ }
+ break;
+ }
+ }
+ EndEnumFilters
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ pDVDC->SetOption(DVD_ResetOnStop, TRUE);
+ pMC->Stop();
+ pDVDC->SetOption(DVD_ResetOnStop, FALSE);
+ }
+ else if(m_iPlaybackMode == PM_CAPTURE)
+ {
+ pMC->Stop();
+ }
+
+ m_iSpeedLevel = 0;
+
+ if(m_fFrameSteppingActive) // FIXME
+ {
+ m_fFrameSteppingActive = false;
+ pBA->put_Volume(m_VolumeBeforeFrameStepping);
+ }
+
+ m_fEndOfStream = false;
+ }
+
+ m_nLoops = 0;
+
+ if(m_hWnd)
+ {
+ KillTimer(TIMER_STREAMPOSPOLLER2);
+ KillTimer(TIMER_STREAMPOSPOLLER);
+ KillTimer(TIMER_STATS);
+
+ MoveVideoWindow();
+
+ if(m_iMediaLoadState == MLS_LOADED)
+ {
+ __int64 start, stop;
+ m_wndSeekBar.GetRange(start, stop);
+ GUID tf;
+ pMS->GetTimeFormat(&tf);
+ m_wndStatusBar.SetStatusTimer(m_wndSeekBar.GetPosReal(), stop, !!m_wndSubresyncBar.IsWindowVisible(), &tf);
+
+ SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
+ }
+ }
+}
+
+void CMainFrame::OnUpdatePlayPauseStop(CCmdUI* pCmdUI)
+{
+ OAFilterState fs = m_fFrameSteppingActive ? State_Paused : GetMediaState();
+
+ pCmdUI->SetCheck(fs == State_Running && pCmdUI->m_nID == ID_PLAY_PLAY
+ || fs == State_Paused && pCmdUI->m_nID == ID_PLAY_PAUSE
+ || fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_STOP
+ || (fs == State_Paused || fs == State_Running) && pCmdUI->m_nID == ID_PLAY_PLAYPAUSE);
+
+ bool fEnable = false;
+
+ if(fs >= 0)
+ {
+ if(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)
+ {
+ fEnable = true;
+
+ if(fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_PAUSE && m_fRealMediaGraph) fEnable = false; // can't go into paused state from stopped with rm
+ else if(m_fCapturing) fEnable = false;
+ else if(m_fLiveWM && pCmdUI->m_nID == ID_PLAY_PAUSE) fEnable = false;
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ fEnable = m_iDVDDomain != DVD_DOMAIN_VideoManagerMenu
+ && m_iDVDDomain != DVD_DOMAIN_VideoTitleSetMenu;
+
+ if(fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_PAUSE) fEnable = false;
+ }
+ }
+
+ pCmdUI->Enable(fEnable);
+}
+
+void CMainFrame::OnPlayFramestep(UINT nID)
+{
+ REFERENCE_TIME rt;
+
+ if(pFS && m_fQuicktimeGraph)
+ {
+ if(GetMediaState() != State_Paused)
+ SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
+
+ pFS->Step(nID == ID_PLAY_FRAMESTEP ? 1 : -1, NULL);
+ }
+ else if(pFS && nID == ID_PLAY_FRAMESTEP)
+ {
+ if(GetMediaState() != State_Paused)
+ SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
+
+ m_fFrameSteppingActive = true;
+
+ m_VolumeBeforeFrameStepping = m_wndToolBar.Volume;
+ pBA->put_Volume(-10000);
+
+ pFS->Step(1, NULL);
+ }
+ else if(S_OK == pMS->IsFormatSupported(&TIME_FORMAT_FRAME))
+ {
+ if(GetMediaState() != State_Paused)
+ SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
+
+ pMS->SetTimeFormat(&TIME_FORMAT_FRAME);
+ pMS->GetCurrentPosition(&rt);
+ if(nID == ID_PLAY_FRAMESTEP) rt++;
+ else if(nID == ID_PLAY_FRAMESTEPCANCEL) rt--;
+ pMS->SetPositions(&rt, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
+ pMS->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
+ }
+}
+
+void CMainFrame::OnUpdatePlayFramestep(CCmdUI* pCmdUI)
+{
+ bool fEnable = false;
+
+ if(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly
+ && (m_iPlaybackMode != PM_DVD || m_iDVDDomain == DVD_DOMAIN_Title)
+ && m_iPlaybackMode != PM_CAPTURE
+ && !m_fLiveWM)
+ {
+ REFTIME AvgTimePerFrame = 0;
+ if(S_OK == pMS->IsFormatSupported(&TIME_FORMAT_FRAME)
+ || pCmdUI->m_nID == ID_PLAY_FRAMESTEP && pFS && pFS->CanStep(0, NULL) == S_OK
+ || m_fQuicktimeGraph && pFS)
+ {
+ fEnable = true;
+ }
+ }
+
+ pCmdUI->Enable(fEnable);
+}
+
+void CMainFrame::OnPlaySeek(UINT nID)
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ REFERENCE_TIME dt =
+ nID == ID_PLAY_SEEKBACKWARDSMALL ? -10000i64*s.nJumpDistS :
+ nID == ID_PLAY_SEEKFORWARDSMALL ? +10000i64*s.nJumpDistS :
+ nID == ID_PLAY_SEEKBACKWARDMED ? -10000i64*s.nJumpDistM :
+ nID == ID_PLAY_SEEKFORWARDMED ? +10000i64*s.nJumpDistM :
+ nID == ID_PLAY_SEEKBACKWARDLARGE ? -10000i64*s.nJumpDistL :
+ nID == ID_PLAY_SEEKFORWARDLARGE ? +10000i64*s.nJumpDistL :
+ 0;
+
+ if(!dt) return;
+
+ // HACK: the custom graph should support frame based seeking instead
+ if(m_fShockwaveGraph) dt /= 10000i64*100;
+
+ SeekTo(m_wndSeekBar.GetPos() + dt);
+}
+
+static int rangebsearch(REFERENCE_TIME val, CAtlArray<REFERENCE_TIME>& rta)
+{
+ int i = 0, j = rta.GetCount() - 1, ret = -1;
+
+ if(j >= 0 && val >= rta[j]) return(j);
+
+ while(i < j)
+ {
+ int mid = (i + j) >> 1;
+ REFERENCE_TIME midt = rta[mid];
+ if(val == midt) {ret = mid; break;}
+ else if(val < midt) {ret = -1; if(j == mid) mid--; j = mid;}
+ else if(val > midt) {ret = mid; if(i == mid) mid++; i = mid;}
+ }
+
+ return(ret);
+}
+
+void CMainFrame::OnPlaySeekKey(UINT nID)
+{
+ if(m_kfs.GetCount() > 0)
+ {
+ HRESULT hr;
+
+ if(GetMediaState() == State_Stopped)
+ SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
+
+ REFERENCE_TIME rtCurrent, rtDur;
+ hr = pMS->GetCurrentPosition(&rtCurrent);
+ hr = pMS->GetDuration(&rtDur);
+
+ int dec = 1;
+ int i = rangebsearch(rtCurrent, m_kfs);
+ if(i > 0) dec = (UINT)max(min(rtCurrent - m_kfs[i-1], 10000000), 0);
+
+ rtCurrent =
+ nID == ID_PLAY_SEEKKEYBACKWARD ? max(rtCurrent - dec, 0) :
+ nID == ID_PLAY_SEEKKEYFORWARD ? rtCurrent : 0;
+
+ i = rangebsearch(rtCurrent, m_kfs);
+
+ if(nID == ID_PLAY_SEEKKEYBACKWARD)
+ rtCurrent = m_kfs[max(i, 0)];
+ else if(nID == ID_PLAY_SEEKKEYFORWARD && i < m_kfs.GetCount()-1)
+ rtCurrent = m_kfs[i+1];
+ else
+ return;
+
+ // HACK: if d3d or something changes fpu control word the values of
+ // m_kfs may be different now (if it was asked again), adding a little
+ // to the seek position eliminates this error usually.
+
+ rtCurrent += 10;
+
+ hr = pMS->SetPositions(
+ &rtCurrent, AM_SEEKING_AbsolutePositioning|AM_SEEKING_SeekToKeyFrame,
+ NULL, AM_SEEKING_NoPositioning);
+ }
+}
+
+void CMainFrame::OnUpdatePlaySeek(CCmdUI* pCmdUI)
+{
+ bool fEnable = false;
+
+ OAFilterState fs = GetMediaState();
+
+ if(m_iMediaLoadState == MLS_LOADED && (fs == State_Paused || fs == State_Running))
+ {
+ fEnable = true;
+ if(m_iPlaybackMode == PM_DVD && (m_iDVDDomain != DVD_DOMAIN_Title || fs != State_Running)) fEnable = false;
+ else if(m_iPlaybackMode == PM_CAPTURE) fEnable = false;
+ }
+
+ pCmdUI->Enable(fEnable);
+}
+
+void CMainFrame::OnPlayGoto()
+{
+ if ((m_iMediaLoadState != MLS_LOADED) || m_bD3DFullscreenMode)
+ return;
+
+ REFTIME atpf = 0;
+ if(FAILED(pBV->get_AvgTimePerFrame(&atpf)) || atpf < 0)
+ {
+ atpf = 0;
+
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ if(atpf > 0) break;
+
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ if(atpf > 0) break;
+
+ AM_MEDIA_TYPE mt;
+ pPin->ConnectionMediaType(&mt);
+
+ if(mt.majortype == MEDIATYPE_Video && mt.formattype == FORMAT_VideoInfo)
+ {
+ atpf = (REFTIME)((VIDEOINFOHEADER*)mt.pbFormat)->AvgTimePerFrame / 10000000i64;
+ }
+ else if(mt.majortype == MEDIATYPE_Video && mt.formattype == FORMAT_VideoInfo2)
+ {
+ atpf = (REFTIME)((VIDEOINFOHEADER2*)mt.pbFormat)->AvgTimePerFrame / 10000000i64;
+ }
+ }
+ EndEnumPins
+ }
+ EndEnumFilters
+ }
+
+ CGoToDlg dlg((int)(m_wndSeekBar.GetPos()/10000), atpf > 0 ? (float)(1.0/atpf) : 0);
+ if(IDOK != dlg.DoModal() || dlg.m_time < 0) return;
+
+ SeekTo(10000i64 * dlg.m_time);
+}
+
+void CMainFrame::OnUpdateGoto(CCmdUI* pCmdUI)
+{
+ bool fEnable = false;
+
+ if(m_iMediaLoadState == MLS_LOADED)
+ {
+ fEnable = true;
+ if(m_iPlaybackMode == PM_DVD && m_iDVDDomain != DVD_DOMAIN_Title) fEnable = false;
+ else if(m_iPlaybackMode == PM_CAPTURE) fEnable = false;
+ }
+
+ pCmdUI->Enable(fEnable);
+}
+
+void CMainFrame::OnPlayChangeRate(UINT nID)
+{
+ if(m_iMediaLoadState != MLS_LOADED)
+ return;
+
+ if(m_iPlaybackMode == PM_CAPTURE)
+ {
+ if(GetMediaState() != State_Running)
+ SendMessage(WM_COMMAND, ID_PLAY_PLAY);
+
+ long lChannelMin = 0, lChannelMax = 0;
+ pAMTuner->ChannelMinMax(&lChannelMin, &lChannelMax);
+ long lChannel = 0, lVivSub = 0, lAudSub = 0;
+ pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub);
+
+ long lFreqOrg = 0, lFreqNew = -1;
+ pAMTuner->get_VideoFrequency(&lFreqOrg);
+
+// long lSignalStrength;
+ do
+ {
+ if(nID == ID_PLAY_DECRATE) lChannel--;
+ else if(nID == ID_PLAY_INCRATE) lChannel++;
+
+// if(lChannel < lChannelMin) lChannel = lChannelMax;
+// if(lChannel > lChannelMax) lChannel = lChannelMin;
+
+ if(lChannel < lChannelMin || lChannel > lChannelMax)
+ break;
+
+ if(FAILED(pAMTuner->put_Channel(lChannel, AMTUNER_SUBCHAN_DEFAULT, AMTUNER_SUBCHAN_DEFAULT)))
+ break;
+
+ long flFoundSignal;
+ pAMTuner->AutoTune(lChannel, &flFoundSignal);
+
+ pAMTuner->get_VideoFrequency(&lFreqNew);
+ }
+ while(FALSE);
+/* SUCCEEDED(pAMTuner->SignalPresent(&lSignalStrength))
+ && (lSignalStrength != AMTUNER_SIGNALPRESENT || lFreqNew == lFreqOrg));*/
+
+ }
+ else
+ {
+ int iNewSpeedLevel;
+
+ if(nID == ID_PLAY_INCRATE) iNewSpeedLevel = m_iSpeedLevel+1;
+ else if(nID == ID_PLAY_DECRATE) iNewSpeedLevel = m_iSpeedLevel-1;
+ else return;
+
+ HRESULT hr = E_FAIL;
+
+ if((iNewSpeedLevel == -4) && (m_iPlaybackMode == PM_FILE))
+ {
+ if(GetMediaState() != State_Paused)
+ SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
+
+ if(GetMediaState() == State_Paused) hr = S_OK;
+ }
+ else
+ {
+ double dRate;
+
+ if(GetMediaState() != State_Running)
+ SendMessage(WM_COMMAND, ID_PLAY_PLAY);
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ dRate = pow(2.0, iNewSpeedLevel >= -3 ? iNewSpeedLevel : (-iNewSpeedLevel - 8));
+ if(fabs(dRate - 1.0) < 0.01) dRate = 1.0;
+ hr = pMS->SetRate(dRate);
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ dRate = pow(2.0, abs(iNewSpeedLevel));
+ if(iNewSpeedLevel >= 0)
+ hr = pDVDC->PlayForwards(dRate, DVD_CMD_FLAG_Block, NULL);
+ else
+ hr = pDVDC->PlayBackwards(dRate, DVD_CMD_FLAG_Block, NULL);
+ }
+
+ if(SUCCEEDED(hr))
+ {
+ CString strMessage;
+ m_iSpeedLevel = iNewSpeedLevel;
+
+ if (dRate == 1.0)
+ m_OSD.DisplayMessage (OSD_TOPRIGHT, _T("Play"));
+ else
+ {
+ strMessage.Format (_T("%s x %.01f"), (iNewSpeedLevel > 0)?_T(">"):_T("<"), fabs(dRate));
+ m_OSD.DisplayMessage (OSD_TOPRIGHT, strMessage);
+ }
+ }
+ }
+
+ }
+}
+
+void CMainFrame::OnUpdatePlayChangeRate(CCmdUI* pCmdUI)
+{
+ bool fEnable = false;
+
+ if(m_iMediaLoadState == MLS_LOADED)
+ {
+ bool fInc = pCmdUI->m_nID == ID_PLAY_INCRATE;
+
+ fEnable = true;
+ if(fInc && m_iSpeedLevel >= 7) fEnable = false;
+ else if(!fInc && m_iPlaybackMode == PM_FILE && m_iSpeedLevel <= -4) fEnable = false;
+ else if(!fInc && m_iPlaybackMode == PM_DVD && m_iSpeedLevel <= -11) fEnable = false;
+ else if(m_iPlaybackMode == PM_DVD && m_iDVDDomain != DVD_DOMAIN_Title) fEnable = false;
+ else if(m_fRealMediaGraph || m_fShockwaveGraph) fEnable = false;
+ else if(m_iPlaybackMode == PM_CAPTURE && (!m_wndCaptureBar.m_capdlg.IsTunerActive() || m_fCapturing)) fEnable = false;
+ else if(m_fLiveWM) fEnable = false;
+ }
+
+ pCmdUI->Enable(fEnable);
+}
+
+void CMainFrame::OnPlayResetRate()
+{
+ if(m_iMediaLoadState != MLS_LOADED)
+ return;
+
+ HRESULT hr = E_FAIL;
+
+ if(GetMediaState() != State_Running)
+ SendMessage(WM_COMMAND, ID_PLAY_PLAY);
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ hr = pMS->SetRate(1.0);
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ hr = pDVDC->PlayForwards(1.0, DVD_CMD_FLAG_Block, NULL);
+ }
+
+ if(SUCCEEDED(hr))
+ m_iSpeedLevel = 0;
+}
+
+void CMainFrame::OnUpdatePlayResetRate(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED);
+}
+
+void CMainFrame::OnPlayChangeAudDelay(UINT nID)
+{
+ if(CComQIPtr<IAudioSwitcherFilter> pASF = FindFilter(__uuidof(CAudioSwitcherFilter), pGB))
+ {
+ REFERENCE_TIME rtShift = pASF->GetAudioTimeShift();
+ rtShift +=
+ nID == ID_PLAY_INCAUDDELAY ? 100000 :
+ nID == ID_PLAY_DECAUDDELAY ? -100000 :
+ 0;
+ pASF->SetAudioTimeShift(rtShift);
+
+ CString str;
+ str.Format(_T("Audio Delay: %I64dms"), rtShift/10000);
+ SendStatusMessage(str, 3000);
+ }
+}
+
+void CMainFrame::OnUpdatePlayChangeAudDelay(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(!!pGB /*&& !!FindFilter(__uuidof(CAudioSwitcherFilter), pGB)*/);
+}
+
+void CMainFrame::OnPlayFilters(UINT nID)
+{
+// ShowPPage(m_spparray[nID - ID_FILTERS_SUBITEM_START], m_hWnd);
+
+ CComPtr<IUnknown> pUnk = m_pparray[nID - ID_FILTERS_SUBITEM_START];
+
+ CComPropertySheet ps(ResStr(IDS_PROPSHEET_PROPERTIES), this);
+
+ if(CComQIPtr<ISpecifyPropertyPages> pSPP = pUnk)
+ {
+ ps.AddPages(pSPP);
+ }
+
+ if(CComQIPtr<IBaseFilter> pBF = pUnk)
+ {
+ HRESULT hr;
+ CComPtr<IPropertyPage> pPP = new CInternalPropertyPageTempl<CPinInfoWnd>(NULL, &hr);
+ ps.AddPage(pPP, pBF);
+ }
+
+ if(ps.GetPageCount() > 0)
+ {
+ ps.DoModal();
+ OpenSetupStatusBar();
+ }
+}
+
+void CMainFrame::OnUpdatePlayFilters(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(!m_fCapturing);
+}
+
+void CMainFrame::OnPlayShaders(UINT nID)
+{
+ if(nID == ID_SHADERS_START+2)
+ {
+ ShowControlBar(&m_wndShaderEditorBar, TRUE, TRUE);
+ return;
+ }
+
+ if(!m_pCAP) return;
+
+ if(nID == ID_SHADERS_START)
+ {
+ m_shaderlabels.RemoveAll();
+ }
+ else if(nID == ID_SHADERS_START+1)
+ {
+ if(IDOK != CShaderCombineDlg(m_shaderlabels, this).DoModal())
+ return;
+ }
+ else if(nID >= ID_SHADERS_START+3)
+ {
+ MENUITEMINFO mii;
+ memset(&mii, 0, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA;
+ m_shaders.GetMenuItemInfo(nID, &mii);
+
+ m_shaderlabels.RemoveAll();
+ m_shaderlabels.AddTail(((const AppSettings::Shader*)mii.dwItemData)->label);
+ }
+
+ SetShaders();
+}
+
+void CMainFrame::OnUpdatePlayShaders(CCmdUI* pCmdUI)
+{
+ if(pCmdUI->m_nID >= ID_SHADERS_START)
+ {
+ pCmdUI->Enable(!!m_pCAP);
+
+ if(pCmdUI->m_nID == ID_SHADERS_START)
+ {
+ pCmdUI->SetRadio(m_shaderlabels.IsEmpty());
+ }
+ else if(pCmdUI->m_nID == ID_SHADERS_START+1)
+ {
+ pCmdUI->SetRadio(m_shaderlabels.GetCount() > 1);
+ }
+ else if(pCmdUI->m_nID == ID_SHADERS_START+2)
+ {
+ pCmdUI->Enable(TRUE);
+ }
+ else
+ {
+ MENUITEMINFO mii;
+ memset(&mii, 0, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA;
+ m_shaders.GetMenuItemInfo(pCmdUI->m_nID, &mii);
+
+ pCmdUI->SetRadio(m_shaderlabels.GetCount() == 1
+ && m_shaderlabels.GetHead() == ((AppSettings::Shader*)mii.dwItemData)->label);
+ }
+ }
+}
+
+void CMainFrame::OnPlayAudio(UINT nID)
+{
+ int i = (int)nID - (1 + ID_AUDIO_SUBITEM_START);
+
+ CComQIPtr<IAMStreamSelect> pSS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB);
+ if(!pSS) pSS = FindFilter(L"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB);
+
+ if(i == -1)
+ {
+ ShowOptions(CPPageAudioSwitcher::IDD);
+ }
+ else if(i >= 0 && pSS)
+ {
+ pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE);
+ }
+}
+
+void CMainFrame::OnUpdatePlayAudio(CCmdUI* pCmdUI)
+{
+ UINT nID = pCmdUI->m_nID;
+ int i = (int)nID - (1 + ID_AUDIO_SUBITEM_START);
+
+ CComQIPtr<IAMStreamSelect> pSS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB);
+ if(!pSS) pSS = FindFilter(L"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB);
+
+ /*if(i == -1)
+ {
+ // TODO****
+ }
+ else*/ if(i >= 0 && pSS)
+ {
+ DWORD flags = 0;
+
+ if(SUCCEEDED(pSS->Info(i, NULL, &flags, NULL, NULL, NULL, NULL, NULL)))
+ {
+ if(flags&AMSTREAMSELECTINFO_EXCLUSIVE) pCmdUI->SetRadio(TRUE);
+ else if(flags&AMSTREAMSELECTINFO_ENABLED) pCmdUI->SetCheck(TRUE);
+ else pCmdUI->SetCheck(FALSE);
+ }
+ else
+ {
+ pCmdUI->Enable(FALSE);
+ }
+ }
+}
+
+void CMainFrame::OnPlaySubtitles(UINT nID)
+{
+ int i = (int)nID - (4 + ID_SUBTITLES_SUBITEM_START);
+
+ if(i == -4)
+ {
+ ShowOptions(CPPageSubtitles::IDD);
+ }
+ else if(i == -3)
+ {
+ int i = m_iSubtitleSel;
+
+ POSITION pos = m_pSubStreams.GetHeadPosition();
+ while(pos && i >= 0)
+ {
+ CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
+
+ if(i < pSubStream->GetStreamCount())
+ {
+ CLSID clsid;
+ if(FAILED(pSubStream->GetClassID(&clsid)))
+ continue;
+
+ if(clsid == __uuidof(CRenderedTextSubtitle))
+ {
+ CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)pSubStream;
+
+ CAutoPtrArray<CPPageSubStyle> pages;
+ CAtlArray<STSStyle*> styles;
+
+ POSITION pos = pRTS->m_styles.GetStartPosition();
+ for(int i = 0; pos; i++)
+ {
+ CString key;
+ STSStyle* val;
+ pRTS->m_styles.GetNextAssoc(pos, key, val);
+
+ CAutoPtr<CPPageSubStyle> page(new CPPageSubStyle());
+ page->InitStyle(key, *val);
+ pages.Add(page);
+ styles.Add(val);
+ }
+
+ CPropertySheet dlg(_T("Styles..."), this);
+ for(int i = 0; i < (int)pages.GetCount(); i++)
+ dlg.AddPage(pages[i]);
+
+ if(dlg.DoModal() == IDOK)
+ {
+ for(int j = 0; j < (int)pages.GetCount(); j++)
+ pages[j]->GetStyle(*styles[j]);
+ UpdateSubtitle(false);
+ }
+
+ return;
+ }
+ }
+
+ i -= pSubStream->GetStreamCount();
+ }
+ }
+ else if(i == -2)
+ {
+ ReloadSubtitle();
+ }
+ else if(i == -1)
+ {
+ if(m_iSubtitleSel == -1) m_iSubtitleSel = 0;
+ else m_iSubtitleSel ^= (1<<31);
+ UpdateSubtitle();
+ }
+ else if(i >= 0)
+ {
+ m_iSubtitleSel = i;
+ UpdateSubtitle();
+ }
+
+ AfxGetAppSettings().fEnableSubtitles = !(m_iSubtitleSel & 0x80000000);
+}
+
+void CMainFrame::OnUpdatePlaySubtitles(CCmdUI* pCmdUI)
+{
+ UINT nID = pCmdUI->m_nID;
+ int i = (int)nID - (4 + ID_SUBTITLES_SUBITEM_START);
+
+ pCmdUI->Enable(m_pCAP && !m_fAudioOnly);
+
+ if(i == -3)
+ {
+ pCmdUI->Enable(FALSE);
+
+ int i = m_iSubtitleSel;
+
+ POSITION pos = m_pSubStreams.GetHeadPosition();
+ while(pos && i >= 0)
+ {
+ CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
+
+ if(i < pSubStream->GetStreamCount())
+ {
+ CLSID clsid;
+ if(FAILED(pSubStream->GetClassID(&clsid)))
+ continue;
+
+ if(clsid == __uuidof(CRenderedTextSubtitle))
+ {
+ pCmdUI->Enable(TRUE);
+ break;
+ }
+ }
+
+ i -= pSubStream->GetStreamCount();
+ }
+ }
+ else if(i == -1)
+ {
+ pCmdUI->SetCheck(m_iSubtitleSel >= 0);
+ }
+ else if(i >= 0)
+ {
+ pCmdUI->SetRadio(i == abs(m_iSubtitleSel));
+ }
+}
+
+void CMainFrame::OnPlayLanguage(UINT nID)
+{
+ nID -= ID_FILTERSTREAMS_SUBITEM_START;
+ CComPtr<IAMStreamSelect> pAMSS = m_ssarray[nID];
+ UINT i = nID;
+ while(i > 0 && pAMSS == m_ssarray[i-1]) i--;
+ if(FAILED(pAMSS->Enable(nID-i, AMSTREAMSELECTENABLE_ENABLE)))
+ MessageBeep(-1);
+
+ OpenSetupStatusBar();
+}
+
+void CMainFrame::OnUpdatePlayLanguage(CCmdUI* pCmdUI)
+{
+ UINT nID = pCmdUI->m_nID;
+ nID -= ID_FILTERSTREAMS_SUBITEM_START;
+ CComPtr<IAMStreamSelect> pAMSS = m_ssarray[nID];
+ UINT i = nID;
+ while(i > 0 && pAMSS == m_ssarray[i-1]) i--;
+ DWORD flags = 0;
+ pAMSS->Info(nID-i, NULL, &flags, NULL, NULL, NULL, NULL, NULL);
+ if(flags&AMSTREAMSELECTINFO_EXCLUSIVE) pCmdUI->SetRadio(TRUE);
+ else if(flags&AMSTREAMSELECTINFO_ENABLED) pCmdUI->SetCheck(TRUE);
+ else pCmdUI->SetCheck(FALSE);
+}
+
+void CMainFrame::OnPlayVolume(UINT nID)
+{
+ if(m_iMediaLoadState == MLS_LOADED)
+ pBA->put_Volume(m_wndToolBar.Volume);
+}
+
+void CMainFrame::OnPlayVolumeBoost(UINT nID)
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ int i = (int)(50.0f*log10(s.AudioBoost));
+
+ switch(nID)
+ {
+ case ID_VOLUME_BOOST_INC: i = min(i+10, 100); break;
+ case ID_VOLUME_BOOST_DEC: i = max(i-10, 0); break;
+ case ID_VOLUME_BOOST_MIN: i = 0; break;
+ case ID_VOLUME_BOOST_MAX: i = 100; break;
+ }
+
+ s.AudioBoost = pow(10.0f, (float)i/50);
+
+ if(CComQIPtr<IAudioSwitcherFilter> pASF = FindFilter(__uuidof(CAudioSwitcherFilter), pGB))
+ {
+ bool fNormalize, fNormalizeRecover;
+ float boost;
+ pASF->GetNormalizeBoost(fNormalize, fNormalizeRecover, boost);
+ pASF->SetNormalizeBoost(fNormalize, fNormalizeRecover, s.AudioBoost);
+ }
+}
+
+void CMainFrame::OnUpdatePlayVolumeBoost(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable();
+}
+
+void CMainFrame::OnAfterplayback(UINT nID)
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ s.nCLSwitches &= ~CLSW_AFTERPLAYBACK_MASK;
+
+ switch(nID)
+ {
+ case ID_AFTERPLAYBACK_CLOSE: s.nCLSwitches |= CLSW_CLOSE; break;
+ case ID_AFTERPLAYBACK_STANDBY: s.nCLSwitches |= CLSW_STANDBY; break;
+ case ID_AFTERPLAYBACK_HIBERNATE: s.nCLSwitches |= CLSW_HIBERNATE; break;
+ case ID_AFTERPLAYBACK_SHUTDOWN: s.nCLSwitches |= CLSW_SHUTDOWN; break;
+ case ID_AFTERPLAYBACK_LOGOFF: s.nCLSwitches |= CLSW_LOGOFF; break;
+ }
+}
+
+void CMainFrame::OnUpdateAfterplayback(CCmdUI* pCmdUI)
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ bool fChecked = false;
+
+ switch(pCmdUI->m_nID)
+ {
+ case ID_AFTERPLAYBACK_CLOSE: fChecked = !!(s.nCLSwitches & CLSW_CLOSE); break;
+ case ID_AFTERPLAYBACK_STANDBY: fChecked = !!(s.nCLSwitches & CLSW_STANDBY); break;
+ case ID_AFTERPLAYBACK_HIBERNATE: fChecked = !!(s.nCLSwitches & CLSW_HIBERNATE); break;
+ case ID_AFTERPLAYBACK_SHUTDOWN: fChecked = !!(s.nCLSwitches & CLSW_SHUTDOWN); break;
+ case ID_AFTERPLAYBACK_LOGOFF: fChecked = !!(s.nCLSwitches & CLSW_LOGOFF); break;
+ case ID_AFTERPLAYBACK_DONOTHING: fChecked = !(s.nCLSwitches & CLSW_AFTERPLAYBACK_MASK); break;
+ }
+
+ pCmdUI->SetRadio(fChecked);
+}
+
+// navigate
+
+void CMainFrame::OnNavigateSkip(UINT nID)
+{
+ if(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)
+ {
+ if(m_iPlaybackMode == PM_FILE) SetupChapters();
+
+ if(DWORD nChapters = m_pCB->ChapGetCount())
+ {
+ REFERENCE_TIME rtCur;
+ pMS->GetCurrentPosition(&rtCur);
+
+ REFERENCE_TIME rt = rtCur;
+ CComBSTR name;
+ long i;
+
+ if(nID == ID_NAVIGATE_SKIPBACK)
+ {
+ rt -= 30000000;
+ i = m_pCB->ChapLookup(&rt, &name);
+ }
+ else if(nID == ID_NAVIGATE_SKIPFORWARD)
+ {
+ i = m_pCB->ChapLookup(&rt, &name) + 1;
+ name.Empty();
+ if(i < nChapters) m_pCB->ChapGet(i, &rt, &name);
+ }
+
+ if(i >= 0 && i < nChapters)
+ {
+ SeekTo(rt);
+ SendStatusMessage(_T("Chapter: ") + CString(name), 3000);
+ return;
+ }
+ }
+
+ if(nID == ID_NAVIGATE_SKIPBACK)
+ {
+ SendMessage(WM_COMMAND, ID_NAVIGATE_SKIPBACKPLITEM);
+ }
+ else if(nID == ID_NAVIGATE_SKIPFORWARD)
+ {
+ SendMessage(WM_COMMAND, ID_NAVIGATE_SKIPFORWARDPLITEM);
+ }
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ m_iSpeedLevel = 0;
+
+ if(GetMediaState() != State_Running)
+ SendMessage(WM_COMMAND, ID_PLAY_PLAY);
+
+ ULONG ulNumOfVolumes, ulVolume;
+ DVD_DISC_SIDE Side;
+ ULONG ulNumOfTitles = 0;
+ pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles);
+
+ DVD_PLAYBACK_LOCATION2 Location;
+ pDVDI->GetCurrentLocation(&Location);
+
+ ULONG ulNumOfChapters = 0;
+ pDVDI->GetNumberOfChapters(Location.TitleNum, &ulNumOfChapters);
+
+ if(nID == ID_NAVIGATE_SKIPBACK)
+ {
+ if(Location.ChapterNum == 1 && Location.TitleNum > 1)
+ {
+ pDVDI->GetNumberOfChapters(Location.TitleNum-1, &ulNumOfChapters);
+ pDVDC->PlayChapterInTitle(Location.TitleNum-1, ulNumOfChapters, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
+ }
+ else
+ {
+ pDVDC->PlayPrevChapter(DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
+ }
+ }
+ else if(nID == ID_NAVIGATE_SKIPFORWARD)
+ {
+ if(Location.ChapterNum == ulNumOfChapters && Location.TitleNum < ulNumOfTitles)
+ {
+ pDVDC->PlayChapterInTitle(Location.TitleNum+1, 1, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
+ }
+ else
+ {
+ pDVDC->PlayNextChapter(DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
+ }
+ }
+/*
+ if(nID == ID_NAVIGATE_SKIPBACK)
+ pDVDC->PlayPrevChapter(DVD_CMD_FLAG_Block, NULL);
+ else if(nID == ID_NAVIGATE_SKIPFORWARD)
+ pDVDC->PlayNextChapter(DVD_CMD_FLAG_Block, NULL);
+*/
+ }
+}
+
+void CMainFrame::OnUpdateNavigateSkip(CCmdUI* pCmdUI)
+{
+ // moved to the timer callback function, that runs less frequent
+// if(m_iPlaybackMode == PM_FILE) SetupChapters();
+
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED
+ && ((m_iPlaybackMode == PM_DVD
+ && m_iDVDDomain != DVD_DOMAIN_VideoManagerMenu
+ && m_iDVDDomain != DVD_DOMAIN_VideoTitleSetMenu)
+ || (m_iPlaybackMode == PM_FILE && (m_wndPlaylistBar.GetCount() > 1/*0*/ || m_pCB->ChapGetCount() > 1))
+ || (m_iPlaybackMode == PM_CAPTURE && !m_fCapturing))); // TODO
+}
+
+void CMainFrame::OnNavigateSkipPlaylistItem(UINT nID)
+{
+ if(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)
+ {
+ if(m_wndPlaylistBar.GetCount() == 1)
+ {
+ SendMessage(WM_COMMAND, ID_PLAY_STOP); // do not remove this, unless you want a circular call with OnPlayPlay()
+ SendMessage(WM_COMMAND, ID_PLAY_PLAY);
+ }
+ else
+ {
+ if(nID == ID_NAVIGATE_SKIPBACKPLITEM)
+ {
+ m_wndPlaylistBar.SetPrev();
+ }
+ else if(nID == ID_NAVIGATE_SKIPFORWARDPLITEM)
+ {
+ m_wndPlaylistBar.SetNext();
+ }
+
+ OpenCurPlaylistItem();
+ }
+ }
+}
+
+void CMainFrame::OnUpdateNavigateSkipPlaylistItem(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED
+ && ((m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE && !m_fCapturing) && m_wndPlaylistBar.GetCount() > 1/*0*/));
+}
+
+void CMainFrame::OnNavigateMenu(UINT nID)
+{
+ nID -= ID_NAVIGATE_TITLEMENU;
+
+ if(m_iMediaLoadState != MLS_LOADED || m_iPlaybackMode != PM_DVD)
+ return;
+
+ m_iSpeedLevel = 0;
+
+ if(GetMediaState() != State_Running)
+ SendMessage(WM_COMMAND, ID_PLAY_PLAY);
+
+ pDVDC->ShowMenu((DVD_MENU_ID)(nID+2), DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
+}
+
+void CMainFrame::OnUpdateNavigateMenu(CCmdUI* pCmdUI)
+{
+ UINT nID = pCmdUI->m_nID - ID_NAVIGATE_TITLEMENU;
+ ULONG ulUOPs;
+
+ if(m_iMediaLoadState != MLS_LOADED || m_iPlaybackMode != PM_DVD
+ || FAILED(pDVDI->GetCurrentUOPS(&ulUOPs)))
+ {
+ pCmdUI->Enable(FALSE);
+ return;
+ }
+
+ pCmdUI->Enable(!(ulUOPs & (UOP_FLAG_ShowMenu_Title << nID)));
+}
+
+void CMainFrame::OnNavigateAudio(UINT nID)
+{
+ nID -= ID_NAVIGATE_AUDIO_SUBITEM_START;
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ OnNavStreamSelectSubMenu(nID, 1);
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ pDVDC->SelectAudioStream(nID, DVD_CMD_FLAG_Block, NULL);
+ }
+}
+
+void CMainFrame::OnNavigateSubpic(UINT nID)
+{
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ OnNavStreamSelectSubMenu(nID - ID_NAVIGATE_SUBP_SUBITEM_START, 2);
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ int i = (int)nID - (1 + ID_NAVIGATE_SUBP_SUBITEM_START);
+
+ if(i == -1)
+ {
+ ULONG ulStreamsAvailable, ulCurrentStream;
+ BOOL bIsDisabled;
+ if(SUCCEEDED(pDVDI->GetCurrentSubpicture(&ulStreamsAvailable, &ulCurrentStream, &bIsDisabled)))
+ pDVDC->SetSubpictureState(bIsDisabled, DVD_CMD_FLAG_Block, NULL);
+ }
+ else
+ {
+ pDVDC->SelectSubpictureStream(i, DVD_CMD_FLAG_Block, NULL);
+ pDVDC->SetSubpictureState(TRUE, DVD_CMD_FLAG_Block, NULL);
+ }
+ }
+}
+
+void CMainFrame::OnNavigateAngle(UINT nID)
+{
+ nID -= ID_NAVIGATE_ANGLE_SUBITEM_START;
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ OnNavStreamSelectSubMenu(nID, 0);
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ pDVDC->SelectAngle(nID+1, DVD_CMD_FLAG_Block, NULL);
+ }
+}
+
+void CMainFrame::OnNavigateChapters(UINT nID)
+{
+ nID -= ID_NAVIGATE_CHAP_SUBITEM_START;
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ if((int)nID >= 0 && nID < m_pCB->ChapGetCount())
+ {
+ REFERENCE_TIME rt;
+ CComBSTR name;
+ if(SUCCEEDED(m_pCB->ChapGet(nID, &rt, &name)))
+ {
+ SeekTo(rt);
+ SendStatusMessage(_T("Chapter: ") + CString(name), 3000);
+ }
+ return;
+ }
+
+ nID -= m_pCB->ChapGetCount();
+
+ if((int)nID >= 0 && (int)nID < m_wndPlaylistBar.GetCount()
+ && m_wndPlaylistBar.GetSelIdx() != (int)nID)
+ {
+ m_wndPlaylistBar.SetSelIdx(nID);
+ OpenCurPlaylistItem();
+ }
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ ULONG ulNumOfVolumes, ulVolume;
+ DVD_DISC_SIDE Side;
+ ULONG ulNumOfTitles = 0;
+ pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles);
+
+ DVD_PLAYBACK_LOCATION2 Location;
+ pDVDI->GetCurrentLocation(&Location);
+
+ ULONG ulNumOfChapters = 0;
+ pDVDI->GetNumberOfChapters(Location.TitleNum, &ulNumOfChapters);
+
+ nID++;
+
+ if(nID > 0 && nID <= ulNumOfTitles)
+ {
+ pDVDC->PlayTitle(nID, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL); // sometimes this does not do anything ...
+ pDVDC->PlayChapterInTitle(nID, 1, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL); // ... but this does!
+ return;
+ }
+
+ nID -= ulNumOfTitles;
+
+ if(nID > 0 && nID <= ulNumOfChapters)
+ {
+ pDVDC->PlayChapter(nID, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
+ return;
+ }
+ }
+}
+
+void CMainFrame::OnNavigateMenuItem(UINT nID)
+{
+ nID -= ID_NAVIGATE_MENU_LEFT;
+
+ if(m_iPlaybackMode == PM_DVD)
+ {
+ switch(nID)
+ {
+ case 0: pDVDC->SelectRelativeButton(DVD_Relative_Left); break;
+ case 1: pDVDC->SelectRelativeButton(DVD_Relative_Right); break;
+ case 2: pDVDC->SelectRelativeButton(DVD_Relative_Upper); break;
+ case 3: pDVDC->SelectRelativeButton(DVD_Relative_Lower); break;
+ case 4:
+ if (m_iDVDDomain != DVD_DOMAIN_Title) // Casimir666 : pour télécommande
+ pDVDC->ActivateButton();
+ else
+ OnPlayPlay();
+ break;
+ case 5: pDVDC->ReturnFromSubmenu(DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL); break;
+ case 6: pDVDC->Resume(DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL); break;
+ default: break;
+ }
+ }
+ else if (m_iPlaybackMode = PM_FILE) OnPlayPlay();
+}
+
+void CMainFrame::OnUpdateNavigateMenuItem(CCmdUI* pCmdUI)
+{
+ UINT nID = pCmdUI->m_nID - ID_NAVIGATE_MENU_LEFT;
+ pCmdUI->Enable((m_iMediaLoadState == MLS_LOADED) && ((m_iPlaybackMode == PM_DVD) || (m_iPlaybackMode == PM_FILE)));
+}
+
+// favorites
+
+class CDVDStateStream : public CUnknown, public IStream
+{
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv)
+ {
+ return
+ QI(IStream)
+ CUnknown::NonDelegatingQueryInterface(riid, ppv);
+ }
+
+ __int64 m_pos;
+
+public:
+ CDVDStateStream() : CUnknown(NAME("CDVDStateStream"), NULL) {m_pos = 0;}
+
+ DECLARE_IUNKNOWN;
+
+ CAtlArray<BYTE> m_data;
+
+ // ISequentialStream
+ STDMETHODIMP Read(void* pv, ULONG cb, ULONG* pcbRead)
+ {
+ __int64 cbRead = min(m_data.GetCount() - m_pos, (__int64)cb);
+ cbRead = max(cbRead, 0);
+ memcpy(pv, &m_data[(INT_PTR)m_pos], (int)cbRead);
+ if(pcbRead) *pcbRead = (ULONG)cbRead;
+ m_pos += cbRead;
+ return S_OK;
+ }
+ STDMETHODIMP Write(const void* pv, ULONG cb, ULONG* pcbWritten)
+ {
+ BYTE* p = (BYTE*)pv;
+ ULONG cbWritten = -1;
+ while(++cbWritten < cb)
+ m_data.Add(*p++);
+ if(pcbWritten) *pcbWritten = cbWritten;
+ return S_OK;
+ }
+
+ // IStream
+ STDMETHODIMP Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) {return E_NOTIMPL;}
+ STDMETHODIMP SetSize(ULARGE_INTEGER libNewSize) {return E_NOTIMPL;}
+ STDMETHODIMP CopyTo(IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten) {return E_NOTIMPL;}
+ STDMETHODIMP Commit(DWORD grfCommitFlags) {return E_NOTIMPL;}
+ STDMETHODIMP Revert() {return E_NOTIMPL;}
+ STDMETHODIMP LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {return E_NOTIMPL;}
+ STDMETHODIMP UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {return E_NOTIMPL;}
+ STDMETHODIMP Stat(STATSTG* pstatstg, DWORD grfStatFlag) {return E_NOTIMPL;}
+ STDMETHODIMP Clone(IStream** ppstm) {return E_NOTIMPL;}
+};
+
+
+void CMainFrame::OnFavoritesAdd()
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ CString fn = m_wndPlaylistBar.GetCur();
+ if(fn.IsEmpty()) return;
+
+ CString desc = fn;
+ desc.Replace('\\', '/');
+ int i = desc.Find(_T("://")), j = desc.Find(_T("?")), k = desc.ReverseFind('/');
+ if(i >= 0) desc = j >= 0 ? desc.Left(j) : desc;
+ else if(k >= 0) desc = desc.Mid(k+1);
+
+ CFavoriteAddDlg dlg(desc, fn);
+ if(dlg.DoModal() != IDOK) return;
+
+ CString str = dlg.m_name;
+ str.Remove(';');
+
+ CString pos(_T("0"));
+ if(dlg.m_fRememberPos)
+ pos.Format(_T("%I64d"), GetPos());
+
+ str += ';';
+ str += pos;
+
+ CPlaylistItem pli;
+ if(m_wndPlaylistBar.GetCur(pli))
+ {
+ POSITION pos = pli.m_fns.GetHeadPosition();
+ while(pos) str += _T(";") + pli.m_fns.GetNext(pos);
+ }
+
+ s.AddFav(FAV_FILE, str);
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ WCHAR path[MAX_PATH];
+ ULONG len = 0;
+ pDVDI->GetDVDDirectory(path, MAX_PATH, &len);
+ CString fn = path;
+ fn.TrimRight(_T("/\\"));
+
+ DVD_PLAYBACK_LOCATION2 Location;
+ pDVDI->GetCurrentLocation(&Location);
+ CString desc;
+ desc.Format(_T("%s - T%02d C%02d - %02d:%02d:%02d"), fn, Location.TitleNum, Location.ChapterNum,
+ Location.TimeCode.bHours, Location.TimeCode.bMinutes, Location.TimeCode.bSeconds);
+
+ CFavoriteAddDlg dlg(fn, desc);
+ if(dlg.DoModal() != IDOK) return;
+
+ CString str = dlg.m_name;
+ str.Remove(';');
+
+ CString pos(_T("0"));
+ if(dlg.m_fRememberPos)
+ {
+ CDVDStateStream stream;
+ stream.AddRef();
+
+ CComPtr<IDvdState> pStateData;
+ CComQIPtr<IPersistStream> pPersistStream;
+ if(SUCCEEDED(pDVDI->GetState(&pStateData))
+ && (pPersistStream = pStateData)
+ && SUCCEEDED(OleSaveToStream(pPersistStream, (IStream*)&stream)))
+ {
+ pos = BinToCString(stream.m_data.GetData(), stream.m_data.GetCount());
+ }
+ }
+
+ str += ';';
+ str += pos;
+
+ str += ';';
+ str += fn;
+
+ s.AddFav(FAV_DVD, str);
+ }
+ else if(m_iPlaybackMode == PM_CAPTURE)
+ {
+ // TODO
+ }
+}
+
+void CMainFrame::OnUpdateFavoritesAdd(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_DVD);
+}
+
+void CMainFrame::OnFavoritesOrganize()
+{
+ CFavoriteOrganizeDlg dlg;
+ dlg.DoModal();
+}
+
+void CMainFrame::OnUpdateFavoritesOrganize(CCmdUI* pCmdUI)
+{
+ // TODO: Add your command update UI handler code here
+}
+
+void CMainFrame::OnFavoritesFile(UINT nID)
+{
+ nID -= ID_FAVORITES_FILE_START;
+
+ CAtlList<CString> sl;
+ AfxGetAppSettings().GetFav(FAV_FILE, sl);
+
+ if(POSITION pos = sl.FindIndex(nID))
+ {
+ CAtlList<CString> fns;
+ REFERENCE_TIME rtStart = 0;
+
+ int i = 0, j = 0;
+ for(CString s1 = sl.GetAt(pos), s2 = s1.Tokenize(_T(";"), i);
+ !s2.IsEmpty();
+ s2 = s1.Tokenize(_T(";"), i), j++)
+ {
+ if(j == 0) ; // desc
+ else if(j == 1) _stscanf(s2, _T("%I64d"), &rtStart); // pos
+ else fns.AddTail(s2); // subs
+ }
+
+ m_wndPlaylistBar.Open(fns, false);
+ OpenCurPlaylistItem(max(rtStart, 0));
+ }
+}
+
+void CMainFrame::OnUpdateFavoritesFile(CCmdUI* pCmdUI)
+{
+ UINT nID = pCmdUI->m_nID - ID_FAVORITES_FILE_START;
+}
+
+void CMainFrame::OnFavoritesDVD(UINT nID)
+{
+ nID -= ID_FAVORITES_DVD_START;
+
+ CAtlList<CString> sl;
+ AfxGetAppSettings().GetFav(FAV_DVD, sl);
+
+ if(POSITION pos = sl.FindIndex(nID))
+ {
+ CString fn;
+
+ CDVDStateStream stream;
+ stream.AddRef();
+
+ int i = 0, j = 0;
+ for(CString s1 = sl.GetAt(pos), s2 = s1.Tokenize(_T(";"), i);
+ !s2.IsEmpty();
+ s2 = s1.Tokenize(_T(";"), i), j++)
+ {
+ if(j == 0) ; // desc
+ else if(j == 1 && s2 != _T("0")) // state
+ {
+ CStringToBin(s2, stream.m_data);
+ }
+ else if(j == 2) fn = s2; // path
+ }
+
+ SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
+
+ CComPtr<IDvdState> pDvdState;
+ HRESULT hr = OleLoadFromStream((IStream*)&stream, IID_IDvdState, (void**)&pDvdState);
+
+ CAutoPtr<OpenDVDData> p(new OpenDVDData());
+ if(p) {p->path = fn; p->pDvdState = pDvdState;}
+ OpenMedia(p);
+ }
+}
+
+void CMainFrame::OnUpdateFavoritesDVD(CCmdUI* pCmdUI)
+{
+ UINT nID = pCmdUI->m_nID - ID_FAVORITES_DVD_START;
+}
+
+void CMainFrame::OnFavoritesDevice(UINT nID)
+{
+ nID -= ID_FAVORITES_DEVICE_START;
+}
+
+void CMainFrame::OnUpdateFavoritesDevice(CCmdUI* pCmdUI)
+{
+ UINT nID = pCmdUI->m_nID - ID_FAVORITES_DEVICE_START;
+}
+
+// help
+
+void CMainFrame::OnHelpHomepage()
+{
+ ShellExecute(m_hWnd, _T("open"), _T("http://gabest.org/"), NULL, NULL, SW_SHOWDEFAULT);
+}
+
+void CMainFrame::OnHelpDocumentation()
+{
+ ShellExecute(m_hWnd, _T("open"), _T("http://sourceforge.net/project/showfiles.php?group_id=82303&package_id=144472"), NULL, NULL, SW_SHOWDEFAULT);
+}
+
+void CMainFrame::OnHelpDonate()
+{
+ const TCHAR URL[] = _T("http://order.kagi.com/?N4A");
+ if(CString(URL).Find(CString(_T("A4N")).MakeReverse()) >= 0)
+ ShellExecute(m_hWnd, _T("open"), URL, NULL, NULL, SW_SHOWDEFAULT);
+}
+
+//////////////////////////////////
+
+static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
+{
+ CAtlArray<HMONITOR>* ml = (CAtlArray<HMONITOR>*)dwData;
+ ml->Add(hMonitor);
+ return TRUE;
+}
+
+void CMainFrame::SetDefaultWindowRect(int iMonitor)
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ {
+ CRect r1, r2;
+ GetClientRect(&r1);
+ m_wndView.GetClientRect(&r2);
+
+ CSize logosize = m_wndView.GetLogoSize();
+ int _DEFCLIENTW = max(logosize.cx, DEFCLIENTW);
+ int _DEFCLIENTH = max(logosize.cy, DEFCLIENTH);
+
+ if(GetSystemMetrics(SM_REMOTESESSION))
+ _DEFCLIENTH = 0;
+
+ DWORD style = GetStyle();
+
+ MENUBARINFO mbi;
+ memset(&mbi, 0, sizeof(mbi));
+ mbi.cbSize = sizeof(mbi);
+ ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
+
+ int w = _DEFCLIENTW + GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2
+ + r1.Width() - r2.Width();
+ int h = _DEFCLIENTH + GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2
+ + (mbi.rcBar.bottom - mbi.rcBar.top)
+ + r1.Height() - r2.Height()
+ + 1; // ???
+// + 2; // ???
+ if(style&WS_CAPTION) h += GetSystemMetrics(SM_CYCAPTION);
+
+ if(s.HasFixedWindowSize())
+ {
+ w = s.fixedWindowSize.cx;
+ h = s.fixedWindowSize.cy;
+ }
+ else if(s.fRememberWindowSize)
+ {
+ w = s.rcLastWindowPos.Width();
+ h = s.rcLastWindowPos.Height();
+ }
+
+ HMONITOR hMonitor = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
+
+ if(iMonitor > 0)
+ {
+ iMonitor--;
+ CAtlArray<HMONITOR> ml;
+ EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&ml);
+ if(iMonitor < ml.GetCount()) hMonitor = ml[iMonitor];
+ }
+
+ MONITORINFO mi;
+ mi.cbSize = sizeof(MONITORINFO);
+ GetMonitorInfo(hMonitor, &mi);
+
+ int x = (mi.rcWork.left+mi.rcWork.right-w)/2;
+ int y = (mi.rcWork.top+mi.rcWork.bottom-h)/2;
+
+ if(s.fRememberWindowPos)
+ {
+ CRect r = s.rcLastWindowPos;
+// x = r.CenterPoint().x - w/2;
+// y = r.CenterPoint().y - h/2;
+ x = r.TopLeft().x;
+ y = r.TopLeft().y;
+ }
+
+ UINT lastWindowType = s.lastWindowType;
+
+ MoveWindow(x, y, w, h);
+
+ if(s.fRememberWindowSize && s.fRememberWindowPos)
+ {
+ WINDOWPLACEMENT wp;
+ memset(&wp, 0, sizeof(wp));
+ wp.length = sizeof(WINDOWPLACEMENT);
+ if(lastWindowType == SIZE_MAXIMIZED)
+ ShowWindow(SW_MAXIMIZE);
+ else if(lastWindowType == SIZE_MINIMIZED)
+ ShowWindow(SW_MINIMIZE);
+
+ // Casimir666 : remettre le full screen si tel était de cas
+ if (!m_fFullScreen && s.fLastFullScreen) ToggleFullscreen(true, true);
+ }
+ }
+
+ if(s.fHideCaptionMenu)
+ {
+ ModifyStyle(WS_CAPTION, 0, SWP_NOZORDER);
+ ::SetMenu(m_hWnd, NULL);
+ SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
+ }
+}
+
+void CMainFrame::RestoreDefaultWindowRect()
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ WINDOWPLACEMENT wp;
+ GetWindowPlacement(&wp);
+ if(!m_fFullScreen && wp.showCmd != SW_SHOWMAXIMIZED && wp.showCmd != SW_SHOWMINIMIZED
+// && (GetExStyle()&WS_EX_APPWINDOW)
+ && !s.fRememberWindowSize)
+ {
+ CRect r1, r2;
+ GetClientRect(&r1);
+ m_wndView.GetClientRect(&r2);
+
+ CSize logosize = m_wndView.GetLogoSize();
+ int _DEFCLIENTW = max(logosize.cx, DEFCLIENTW);
+ int _DEFCLIENTH = max(logosize.cy, DEFCLIENTH);
+
+ DWORD style = GetStyle();
+
+ MENUBARINFO mbi;
+ memset(&mbi, 0, sizeof(mbi));
+ mbi.cbSize = sizeof(mbi);
+ ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
+
+ int w = _DEFCLIENTW + GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2
+ + r1.Width() - r2.Width();
+ int h = _DEFCLIENTH + GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2
+ + (mbi.rcBar.bottom - mbi.rcBar.top)
+ + r1.Height() - r2.Height()
+ + 1; // ???
+// + 2; // ???
+ if(style&WS_CAPTION) h += GetSystemMetrics(SM_CYCAPTION);
+
+ if(s.HasFixedWindowSize())
+ {
+ w = s.fixedWindowSize.cx;
+ h = s.fixedWindowSize.cy;
+ }
+
+ CRect r;
+ GetWindowRect(r);
+
+ int x = r.CenterPoint().x - w/2;
+ int y = r.CenterPoint().y - h/2;
+
+ if(s.fRememberWindowPos)
+ {
+ CRect r = s.rcLastWindowPos;
+
+ x = r.TopLeft().x;
+ y = r.TopLeft().y;
+ }
+
+ MoveWindow(x, y, w, h);
+ }
+}
+
+OAFilterState CMainFrame::GetMediaState()
+{
+ OAFilterState ret = -1;
+ if(m_iMediaLoadState == MLS_LOADED) pMC->GetState(0, &ret);
+ return(ret);
+}
+
+CSize CMainFrame::GetVideoSize()
+{
+ bool fKeepAspectRatio = AfxGetAppSettings().fKeepAspectRatio;
+ bool fCompMonDeskARDiff = AfxGetAppSettings().fCompMonDeskARDiff;
+
+ CSize ret(0,0);
+ if(m_iMediaLoadState != MLS_LOADED || m_fAudioOnly)
+ return ret;
+
+ CSize wh(0, 0), arxy(0, 0);
+
+ if(m_pCAP)
+ {
+ wh = m_pCAP->GetVideoSize(false);
+ arxy = m_pCAP->GetVideoSize(fKeepAspectRatio);
+ }
+ else
+ {
+ pBV->GetVideoSize(&wh.cx, &wh.cy);
+
+ long arx = 0, ary = 0;
+ CComQIPtr<IBasicVideo2> pBV2 = pBV;
+ if(pBV2 && SUCCEEDED(pBV2->GetPreferredAspectRatio(&arx, &ary)) && arx > 0 && ary > 0)
+ arxy.SetSize(arx, ary);
+ }
+
+ if(wh.cx <= 0 || wh.cy <= 0)
+ return ret;
+
+ // with the overlay mixer IBasicVideo2 won't tell the new AR when changed dynamically
+ DVD_VideoAttributes VATR;
+ if(m_iPlaybackMode == PM_DVD && SUCCEEDED(pDVDI->GetCurrentVideoAttributes(&VATR)))
+ arxy.SetSize(VATR.ulAspectX, VATR.ulAspectY);
+
+ CSize& ar = AfxGetAppSettings().AspectRatio;
+ if(ar.cx && ar.cy) arxy = ar;
+
+ ret = (!fKeepAspectRatio || arxy.cx <= 0 || arxy.cy <= 0)
+ ? wh
+ : CSize(MulDiv(wh.cy, arxy.cx, arxy.cy), wh.cy);
+
+ if(fCompMonDeskARDiff)
+ if(HDC hDC = ::GetDC(0))
+ {
+ int _HORZSIZE = GetDeviceCaps(hDC, HORZSIZE);
+ int _VERTSIZE = GetDeviceCaps(hDC, VERTSIZE);
+ int _HORZRES = GetDeviceCaps(hDC, HORZRES);
+ int _VERTRES = GetDeviceCaps(hDC, VERTRES);
+
+ if(_HORZSIZE > 0 && _VERTSIZE > 0 && _HORZRES > 0 && _VERTRES > 0)
+ {
+ double a = 1.0*_HORZSIZE/_VERTSIZE;
+ double b = 1.0*_HORZRES/_VERTRES;
+
+ if(b < a)
+ ret.cy = (DWORD)(1.0*ret.cy * a / b);
+ else if(a < b)
+ ret.cx = (DWORD)(1.0*ret.cx * b / a);
+ }
+
+ ::ReleaseDC(0, hDC);
+ }
+
+ return ret;
+}
+
+void CMainFrame::ToggleFullscreen(bool fToNearest, bool fSwitchScreenResWhenHasTo)
+{
+ AppSettings& s = AfxGetAppSettings();
+ CRect r;
+// const CWnd* pWndInsertAfter;
+ DWORD dwRemove = 0, dwAdd = 0;
+ DWORD dwRemoveEx = 0, dwAddEx = 0;
+ HMENU hMenu;
+
+ if(!m_fFullScreen)
+ {
+ GetWindowRect(&m_lastWindowRect);
+
+ dispmode& dm = AfxGetAppSettings().dmFullscreenRes;
+ m_dmBeforeFullscreen.fValid = false;
+ if(dm.fValid && fSwitchScreenResWhenHasTo)
+ {
+ GetCurDispMode(m_dmBeforeFullscreen);
+ SetDispMode(dm);
+ }
+
+ MONITORINFO mi;
+ mi.cbSize = sizeof(MONITORINFO);
+ GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
+
+ dwRemove = WS_CAPTION|WS_THICKFRAME;
+ if(fToNearest) r = mi.rcMonitor;
+ else GetDesktopWindow()->GetWindowRect(&r);
+ hMenu = NULL;
+ }
+ else
+ {
+ if(m_dmBeforeFullscreen.fValid)
+ SetDispMode(m_dmBeforeFullscreen);
+
+ dwAdd = (AfxGetAppSettings().fHideCaptionMenu ? 0 : WS_CAPTION) | WS_THICKFRAME;
+ r = m_lastWindowRect;
+ hMenu = AfxGetAppSettings().fHideCaptionMenu ? NULL : m_hMenuDefault;
+ }
+
+ m_lastMouseMove.x = m_lastMouseMove.y = -1;
+
+ bool fAudioOnly = m_fAudioOnly;
+ m_fAudioOnly = true;
+
+ m_fFullScreen = !m_fFullScreen;
+ s.fLastFullScreen = m_fFullScreen;
+
+ SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
+
+ ModifyStyle(dwRemove, dwAdd, SWP_NOZORDER);
+ ModifyStyleEx(dwRemoveEx, dwAddEx, SWP_NOZORDER);
+ ::SetMenu(m_hWnd, hMenu);
+ SetWindowPos(NULL, r.left, r.top, r.Width(), r.Height(), SWP_NOZORDER|SWP_NOSENDCHANGING /*SWP_FRAMECHANGED*/);
+
+ if(m_fFullScreen)
+ {
+ m_fHideCursor = true;
+ ShowControls(CS_NONE, false);
+ }
+ else
+ {
+ KillTimer(TIMER_FULLSCREENCONTROLBARHIDER);
+ KillTimer(TIMER_FULLSCREENMOUSEHIDER);
+ m_fHideCursor = false;
+ ShowControls(AfxGetAppSettings().nCS);
+ }
+
+ m_wndView.SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
+
+ m_fAudioOnly = fAudioOnly;
+
+ MoveVideoWindow();
+}
+
+void CMainFrame::MoveVideoWindow(bool fShowStats)
+{
+ if(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && IsWindowVisible())
+ {
+ CRect wr;
+ if (m_bD3DFullscreenMode)
+ m_pFullscreenWnd->GetClientRect(wr);
+ else if(!m_fFullScreen)
+ {
+ m_wndView.GetClientRect(wr);
+ if(!AfxGetAppSettings().fHideCaptionMenu)
+ wr.DeflateRect(2, 2);
+ }
+ else
+ {
+ GetWindowRect(&wr);
+
+ // HACK
+ CRect r;
+ m_wndView.GetWindowRect(&r);
+ wr -= r.TopLeft();
+ }
+
+ CRect vr = CRect(0,0,0,0);
+
+ OAFilterState fs = GetMediaState();
+ if(fs == State_Paused || fs == State_Running || fs == State_Stopped && (m_fShockwaveGraph || m_fQuicktimeGraph))
+ {
+ CSize arxy = GetVideoSize();
+
+ int iDefaultVideoSize = AfxGetAppSettings().iDefaultVideoSize;
+
+ CSize ws =
+ iDefaultVideoSize == DVS_HALF ? CSize(arxy.cx/2, arxy.cy/2) :
+ iDefaultVideoSize == DVS_NORMAL ? arxy :
+ iDefaultVideoSize == DVS_DOUBLE ? CSize(arxy.cx*2, arxy.cy*2) :
+ wr.Size();
+
+ int w = ws.cx;
+ int h = ws.cy;
+
+ if(!m_fShockwaveGraph) //&& !m_fQuicktimeGraph)
+ {
+ if(iDefaultVideoSize == DVS_FROMINSIDE || iDefaultVideoSize == DVS_FROMOUTSIDE)
+ {
+ h = ws.cy;
+ w = MulDiv(h, arxy.cx, arxy.cy);
+
+ if(iDefaultVideoSize == DVS_FROMINSIDE && w > ws.cx
+ || iDefaultVideoSize == DVS_FROMOUTSIDE && w < ws.cx)
+ {
+ w = ws.cx;
+ h = MulDiv(w, arxy.cy, arxy.cx);
+ }
+ }
+ }
+
+ CSize size(
+ (int)(m_ZoomX*w),
+ (int)(m_ZoomY*h));
+
+ CPoint pos(
+ (int)(m_PosX*(wr.Width()*3 - m_ZoomX*w) - wr.Width()),
+ (int)(m_PosY*(wr.Height()*3 - m_ZoomY*h) - wr.Height()));
+
+/* CPoint pos(
+ (int)(m_PosX*(wr.Width() - size.cx)),
+ (int)(m_PosY*(wr.Height() - size.cy)));
+
+*/
+ vr = CRect(pos, size);
+ }
+
+ wr |= CRect(0,0,0,0);
+ vr |= CRect(0,0,0,0);
+
+ if(m_pCAP)
+ {
+ m_pCAP->SetPosition(wr, vr);
+ m_pCAP->SetVideoAngle(Vector(DegToRad(m_AngleX), DegToRad(m_AngleY), DegToRad(m_AngleZ)));
+ }
+ else
+ {
+ HRESULT hr;
+ hr = pBV->SetDefaultSourcePosition();
+ hr = pBV->SetDestinationPosition(vr.left, vr.top, vr.Width(), vr.Height());
+ hr = pVW->SetWindowPosition(wr.left, wr.top, wr.Width(), wr.Height());
+ }
+
+ m_wndView.SetVideoRect(wr);
+
+ if(fShowStats && vr.Height() > 0)
+ {
+ CString info;
+ info.Format(_T("Pos %.2f %.2f, Zoom %.2f %.2f, AR %.2f"), m_PosX, m_PosY, m_ZoomX, m_ZoomY, (float)vr.Width()/vr.Height());
+ SendStatusMessage(info, 3000);
+ }
+ }
+ else
+ {
+ m_wndView.SetVideoRect();
+ }
+}
+
+void CMainFrame::ZoomVideoWindow(double scale)
+{
+ if(m_iMediaLoadState != MLS_LOADED)
+ return;
+
+ AppSettings& s = AfxGetAppSettings();
+
+ if(scale <= 0)
+ {
+ scale =
+ s.iZoomLevel == 0 ? 0.5 :
+ s.iZoomLevel == 1 ? 1.0 :
+ s.iZoomLevel == 2 ? 2.0 :
+ s.iZoomLevel == 3 ? GetZoomAutoFitScale() :
+ 1.0;
+ }
+
+ if(m_fFullScreen)
+ {
+ OnViewFullscreen();
+ }
+
+ MINMAXINFO mmi;
+ OnGetMinMaxInfo(&mmi);
+
+ CRect r;
+ int w = 0, h = 0;
+
+ if(!m_fAudioOnly)
+ {
+ CSize arxy = GetVideoSize();
+
+ long lWidth = int(arxy.cx * scale + 0.5);
+ long lHeight = int(arxy.cy * scale + 0.5);
+
+ DWORD style = GetStyle();
+
+ CRect r1, r2;
+ GetClientRect(&r1);
+ m_wndView.GetClientRect(&r2);
+
+ w = GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2
+ + r1.Width() - r2.Width()
+ + lWidth;
+
+ MENUBARINFO mbi;
+ memset(&mbi, 0, sizeof(mbi));
+ mbi.cbSize = sizeof(mbi);
+ ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
+
+ h = GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2
+ + (mbi.rcBar.bottom - mbi.rcBar.top)
+ + r1.Height() - r2.Height()
+ + lHeight;
+
+ if(style&WS_CAPTION)
+ {
+ h += GetSystemMetrics(SM_CYCAPTION);
+ w += 2; h += 2; // for the 1 pixel wide sunken frame
+ w += 2; h += 3; // for the inner black border
+ }
+
+ GetWindowRect(r);
+
+ w = max(w, mmi.ptMinTrackSize.x);
+ h = max(h, mmi.ptMinTrackSize.y);
+ }
+ else
+ {
+ GetWindowRect(r);
+
+ w = r.Width(); // mmi.ptMinTrackSize.x;
+ h = mmi.ptMinTrackSize.y;
+ }
+
+ // center window
+ if(!s.fRememberWindowPos)
+ {
+ CPoint cp = r.CenterPoint();
+ r.left = cp.x - w/2;
+ r.top = cp.y - h/2;
+ }
+
+ r.right = r.left + w;
+ r.bottom = r.top + h;
+
+ MONITORINFO mi;
+ mi.cbSize = sizeof(MONITORINFO);
+ GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
+ if(r.right > mi.rcWork.right) r.OffsetRect(mi.rcWork.right-r.right, 0);
+ if(r.left < mi.rcWork.left) r.OffsetRect(mi.rcWork.left-r.left, 0);
+ if(r.bottom > mi.rcWork.bottom) r.OffsetRect(0, mi.rcWork.bottom-r.bottom);
+ if(r.top < mi.rcWork.top) r.OffsetRect(0, mi.rcWork.top-r.top);
+
+ if((m_fFullScreen || !s.HasFixedWindowSize()) && !m_bD3DFullscreenMode)
+ {
+ MoveWindow(r);
+ }
+
+// ShowWindow(SW_SHOWNORMAL);
+
+ MoveVideoWindow();
+}
+
+double CMainFrame::GetZoomAutoFitScale()
+{
+ if(m_iMediaLoadState != MLS_LOADED || m_fAudioOnly)
+ return 1.0;
+
+ CSize arxy = GetVideoSize();
+
+ double sx = 2.0/3 * m_rcDesktop.Width() / arxy.cx;
+ double sy = 2.0/3 * m_rcDesktop.Height() / arxy.cy;
+
+ return sx < sy ? sx : sy;
+}
+
+void CMainFrame::RepaintVideo()
+{
+ if(m_pCAP) m_pCAP->Paint(false);
+}
+
+void CMainFrame::SetShaders()
+{
+ if(!m_pCAP) return;
+
+ AppSettings& s = AfxGetAppSettings();
+
+ CAtlStringMap<const AppSettings::Shader*> s2s;
+
+ POSITION pos = s.m_shaders.GetHeadPosition();
+ while(pos)
+ {
+ const AppSettings::Shader* pShader = &s.m_shaders.GetNext(pos);
+ s2s[pShader->label] = pShader;
+ }
+
+ m_pCAP->SetPixelShader(NULL, NULL);
+
+ CAtlList<CString> labels;
+
+ pos = m_shaderlabels.GetHeadPosition();
+ while(pos)
+ {
+ const AppSettings::Shader* pShader = NULL;
+ if(s2s.Lookup(m_shaderlabels.GetNext(pos), pShader))
+ {
+ CStringA target = pShader->target;
+ CStringA srcdata = pShader->srcdata;
+
+ HRESULT hr = m_pCAP->SetPixelShader(srcdata, target);
+
+ if(FAILED(hr))
+ {
+ m_pCAP->SetPixelShader(NULL, NULL);
+ SendStatusMessage(_T("Could not load shader: ") + pShader->label, 3000);
+ return;
+ }
+
+ labels.AddTail(pShader->label);
+ }
+ }
+
+ if(m_iMediaLoadState == MLS_LOADED)
+ {
+ CString str = Implode(labels, '|');
+ str.Replace(_T("|"), _T(", "));
+ SendStatusMessage(_T("Shader: ") + str, 3000);
+ }
+}
+
+void CMainFrame::UpdateShaders(CString label)
+{
+ if(!m_pCAP) return;
+
+ if(m_shaderlabels.GetCount() <= 1)
+ m_shaderlabels.RemoveAll();
+
+ if(m_shaderlabels.IsEmpty() && !label.IsEmpty())
+ m_shaderlabels.AddTail(label);
+
+ bool fUpdate = m_shaderlabels.IsEmpty();
+
+ POSITION pos = m_shaderlabels.GetHeadPosition();
+ while(pos)
+ {
+ if(label == m_shaderlabels.GetNext(pos))
+ {
+ fUpdate = true;
+ break;
+ }
+ }
+
+ if(fUpdate) SetShaders();
+
+}
+
+void CMainFrame::SetBalance(int balance)
+{
+ AfxGetAppSettings().nBalance = balance;
+
+ int sign = balance>0?-1:1;
+ balance = max(100-abs(balance), 1);
+ balance = (int)((log10(1.0*balance)-2)*5000*sign);
+ balance = max(min(balance, 10000), -10000);
+
+ if(m_iMediaLoadState == MLS_LOADED)
+ pBA->put_Balance(balance);
+}
+
+void CMainFrame::SetupIViAudReg()
+{
+ if(!AfxGetAppSettings().fAutoSpeakerConf) return;
+
+ DWORD spc = 0, defchnum = 0;
+
+ if(AfxGetAppSettings().fAutoSpeakerConf)
+ {
+ CComPtr<IDirectSound> pDS;
+ if(SUCCEEDED(DirectSoundCreate(NULL, &pDS, NULL))
+ && SUCCEEDED(pDS->SetCooperativeLevel(m_hWnd, DSSCL_NORMAL)))
+ {
+ if(SUCCEEDED(pDS->GetSpeakerConfig(&spc)))
+ {
+ switch(spc)
+ {
+ case DSSPEAKER_DIRECTOUT: defchnum = 6; break;
+ case DSSPEAKER_HEADPHONE: defchnum = 2; break;
+ case DSSPEAKER_MONO: defchnum = 1; break;
+ case DSSPEAKER_QUAD: defchnum = 4; break;
+ default:
+ case DSSPEAKER_STEREO: defchnum = 2; break;
+ case DSSPEAKER_SURROUND: defchnum = 2; break;
+ case DSSPEAKER_5POINT1: defchnum = 5; break;
+ case DSSPEAKER_7POINT1: defchnum = 5; break;
+ }
+ }
+ }
+ }
+ else
+ {
+ defchnum = 2;
+ }
+
+ CRegKey iviaud;
+ if(ERROR_SUCCESS == iviaud.Create(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\InterVideo\\Common\\AudioDec")))
+ {
+ DWORD chnum = 0;
+ if(FAILED(iviaud.QueryDWORDValue(_T("AUDIO"), chnum))) chnum = 0;
+ if(chnum <= defchnum) // check if the user has already set it..., but we won't skip if it's lower than sensible :P
+ iviaud.SetDWORDValue(_T("AUDIO"), defchnum);
+ }
+}
+
+//
+// Open/Close
+//
+
+void CMainFrame::OpenCreateGraphObject(OpenMediaData* pOMD)
+{
+ ASSERT(pGB == NULL);
+
+ m_fCustomGraph = false;
+ m_fRealMediaGraph = m_fShockwaveGraph = m_fQuicktimeGraph = false;
+
+ AppSettings& s = AfxGetAppSettings();
+
+ // CASIMIR666 todo
+ if (s.fD3DFullscreen && (s.iDSVideoRendererType == VIDRNDT_DS_VMR9RENDERLESS))
+ {
+ CreateFullScreenWindow();
+ m_pVideoWnd = m_pFullscreenWnd;
+ m_bD3DFullscreenMode = true;
+ }
+ else
+ {
+ m_pVideoWnd = &m_wndView;
+ m_bD3DFullscreenMode = false;
+ }
+
+ if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD))
+ {
+ engine_t engine = s.Formats.GetEngine(p->fns.GetHead());
+
+ CStringA ct = GetContentType(p->fns.GetHead());
+
+ if(ct == "video/x-ms-asf")
+ {
+ // TODO: put something here to make the windows media source filter load later
+ }
+ else if(ct == "audio/x-pn-realaudio"
+ || ct == "audio/x-pn-realaudio-plugin"
+ || ct == "audio/x-realaudio-secure"
+ || ct == "video/vnd.rn-realvideo-secure"
+ || ct == "application/vnd.rn-realmedia"
+ || ct.Find("vnd.rn-") >= 0
+ || ct.Find("realaudio") >= 0
+ || ct.Find("realvideo") >= 0)
+ {
+ engine = RealMedia;
+ }
+ else if(ct == "application/x-shockwave-flash")
+ {
+ engine = ShockWave;
+ }
+ else if(ct == "video/quicktime"
+ || ct == "application/x-quicktimeplayer")
+ {
+ engine = QuickTime;
+ }
+
+ HRESULT hr;
+ CComPtr<IUnknown> pUnk;
+
+ if(engine == RealMedia)
+ {
+ if(!(pUnk = (IUnknown*)(INonDelegatingUnknown*)new CRealMediaGraph(m_pVideoWnd->m_hWnd, hr)))
+ throw _T("Out of memory");
+
+ if(SUCCEEDED(hr) && !!(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
+ m_fRealMediaGraph = true;
+ }
+ else if(engine == ShockWave)
+ {
+ if(!(pUnk = (IUnknown*)(INonDelegatingUnknown*)new CShockwaveGraph(m_pVideoWnd->m_hWnd, hr)))
+ throw _T("Out of memory");
+
+ if(FAILED(hr) || !(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
+ throw _T("Can't create shockwave control");
+
+ m_fShockwaveGraph = true;
+ }
+ else if(engine == QuickTime)
+ {
+ if(!(pUnk = (IUnknown*)(INonDelegatingUnknown*)new CQuicktimeGraph(m_pVideoWnd->m_hWnd, hr)))
+ throw _T("Out of memory");
+
+ if(SUCCEEDED(hr) && !!(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
+ m_fQuicktimeGraph = true;
+ }
+
+ m_fCustomGraph = m_fRealMediaGraph || m_fShockwaveGraph || m_fQuicktimeGraph;
+
+ if(!m_fCustomGraph)
+ {
+ pGB = new CFGManagerPlayer(_T("CFGManagerPlayer"), NULL, s.SrcFilters, s.TraFilters, m_pVideoWnd->m_hWnd);
+ }
+ }
+ else if(OpenDVDData* p = dynamic_cast<OpenDVDData*>(pOMD))
+ {
+ pGB = new CFGManagerDVD(_T("CFGManagerDVD"), NULL, s.SrcFilters, s.TraFilters, m_pVideoWnd->m_hWnd);
+ }
+ else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD))
+ {
+ pGB = new CFGManagerCapture(_T("CFGManagerCapture"), NULL, s.SrcFilters, s.TraFilters, m_pVideoWnd->m_hWnd);
+ }
+
+ if(!pGB)
+ {
+ throw _T("Failed to create the filter graph object");
+ }
+
+ pGB->AddToROT();
+
+ pMC = pGB; pME = pGB; pMS = pGB; // general
+ pVW = pGB; pBV = pGB; // video
+ pBA = pGB; // audio
+ pFS = pGB;
+
+ if(!(pMC && pME && pMS)
+ || !(pVW && pBV)
+ || !(pBA))
+ {
+ throw _T("Failed to query the needed interfaces for playback");
+ }
+
+ if(FAILED(pME->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0)))
+ {
+ throw _T("Could not set target window for graph notification");
+ }
+
+ m_pProv = (IUnknown*)new CKeyProvider();
+
+ if(CComQIPtr<IObjectWithSite> pObjectWithSite = pGB)
+ pObjectWithSite->SetSite(m_pProv);
+
+ m_pCB = new CDSMChapterBag(NULL, NULL);
+}
+
+void CMainFrame::OpenFile(OpenFileData* pOFD)
+{
+ if(pOFD->fns.IsEmpty())
+ throw _T("Invalid argument");
+
+ AppSettings& s = AfxGetAppSettings();
+
+ bool fFirst = true;
+
+ POSITION pos = pOFD->fns.GetHeadPosition();
+ while(pos)
+ {
+ CString fn = pOFD->fns.GetNext(pos);
+
+ fn.Trim();
+ if(fn.IsEmpty() && !fFirst)
+ break;
+
+ HRESULT hr = pGB->RenderFile(CStringW(fn), NULL);
+
+ if (!AfxGetAppSettings().NewFile (fn) && AfxGetAppSettings().fRememberFilePos)
+ {
+ REFERENCE_TIME rtPos = AfxGetAppSettings().CurrentFilePosition()->llPosition;
+ if (pMS) pMS->SetPositions (&rtPos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
+ }
+
+ if(FAILED(hr))
+ {
+ if(fFirst)
+ {
+ if(s.fReportFailedPins)
+ {
+ CComQIPtr<IGraphBuilderDeadEnd> pGBDE = pGB;
+ if(pGBDE && pGBDE->GetCount()) CMediaTypesDlg(pGBDE, this).DoModal();
+ }
+
+ CString err;
+
+ switch(hr)
+ {
+ case E_ABORT: err = _T("Opening aborted"); break;
+ case E_FAIL: case E_POINTER: default: err = _T("Failed to render the file"); break;
+ case E_INVALIDARG: err = _T("Invalid file name"); break;
+ case E_OUTOFMEMORY: err = _T("Out of memory"); break;
+ case VFW_E_CANNOT_CONNECT: err = _T("Cannot connect the filters"); break;
+ case VFW_E_CANNOT_LOAD_SOURCE_FILTER: err = _T("Cannot load any source filter"); break;
+ case VFW_E_CANNOT_RENDER: err = _T("Cannot render the file"); break;
+ case VFW_E_INVALID_FILE_FORMAT: err = _T("Invalid file format"); break;
+ case VFW_E_NOT_FOUND: err = _T("File not found"); break;
+ case VFW_E_UNKNOWN_FILE_TYPE: err = _T("Unknown file type"); break;
+ case VFW_E_UNSUPPORTED_STREAM: err = _T("Unsupported stream"); break;
+ }
+
+ throw err;
+ }
+ }
+
+ if(s.fKeepHistory)
+ {
+ CRecentFileList* pMRU = fFirst ? &s.MRU : &s.MRUDub;
+ pMRU->ReadList();
+ pMRU->Add(fn);
+ pMRU->WriteList();
+ }
+
+ if(fFirst)
+ {
+ pOFD->title = fn;
+ }
+
+ fFirst = false;
+
+ if(m_fCustomGraph) break;
+ }
+
+ if(s.fReportFailedPins)
+ {
+ CComQIPtr<IGraphBuilderDeadEnd> pGBDE = pGB;
+ if(pGBDE && pGBDE->GetCount()) CMediaTypesDlg(pGBDE, this).DoModal();
+ }
+
+ if(!(pAMOP = pGB))
+ {
+ BeginEnumFilters(pGB, pEF, pBF)
+ if(pAMOP = pBF) break;
+ EndEnumFilters
+ }
+
+ if(FindFilter(__uuidof(CShoutcastSource), pGB))
+ m_fUpdateInfoBar = true;
+
+ SetupChapters();
+
+ CComQIPtr<IKeyFrameInfo> pKFI;
+ BeginEnumFilters(pGB, pEF, pBF)
+ if(pKFI = pBF) break;
+ EndEnumFilters
+ UINT nKFs = 0, nKFsTmp = 0;
+ if(pKFI && S_OK == pKFI->GetKeyFrameCount(nKFs) && nKFs > 0)
+ {
+ m_kfs.SetCount(nKFsTmp = nKFs);
+ if(S_OK != pKFI->GetKeyFrames(&TIME_FORMAT_MEDIA_TIME, m_kfs.GetData(), nKFsTmp) || nKFsTmp != nKFs)
+ m_kfs.RemoveAll();
+ }
+
+ m_iPlaybackMode = PM_FILE;
+}
+
+void CMainFrame::SetupChapters()
+{
+ ASSERT(m_pCB);
+
+ m_pCB->ChapRemoveAll();
+
+ CInterfaceList<IBaseFilter> pBFs;
+ BeginEnumFilters(pGB, pEF, pBF)
+ pBFs.AddTail(pBF);
+ EndEnumFilters
+
+ POSITION pos;
+
+ pos = pBFs.GetHeadPosition();
+ while(pos && !m_pCB->ChapGetCount())
+ {
+ IBaseFilter* pBF = pBFs.GetNext(pos);
+
+ CComQIPtr<IDSMChapterBag> pCB = pBF;
+ if(!pCB) continue;
+
+ for(DWORD i = 0, cnt = pCB->ChapGetCount(); i < cnt; i++)
+ {
+ REFERENCE_TIME rt;
+ CComBSTR name;
+ if(SUCCEEDED(pCB->ChapGet(i, &rt, &name)))
+ m_pCB->ChapAppend(rt, name);
+ }
+ }
+
+ pos = pBFs.GetHeadPosition();
+ while(pos && !m_pCB->ChapGetCount())
+ {
+ IBaseFilter* pBF = pBFs.GetNext(pos);
+
+ CComQIPtr<IChapterInfo> pCI = pBF;
+ if(!pCI) continue;
+
+ CHAR iso6391[3];
+ ::GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, iso6391, 3);
+ CStringA iso6392 = ISO6391To6392(iso6391);
+ if(iso6392.GetLength() < 3) iso6392 = "eng";
+
+ UINT cnt = pCI->GetChapterCount(CHAPTER_ROOT_ID);
+ for(UINT i = 1; i <= cnt; i++)
+ {
+ UINT cid = pCI->GetChapterId(CHAPTER_ROOT_ID, i);
+
+ ChapterElement ce;
+ if(pCI->GetChapterInfo(cid, &ce))
+ {
+ char pl[3] = {iso6392[0], iso6392[1], iso6392[2]};
+ char cc[] = " ";
+ CComBSTR name;
+ name.Attach(pCI->GetChapterStringInfo(cid, pl, cc));
+ m_pCB->ChapAppend(ce.rtStart, name);
+ }
+ }
+ }
+
+ pos = pBFs.GetHeadPosition();
+ while(pos && !m_pCB->ChapGetCount())
+ {
+ IBaseFilter* pBF = pBFs.GetNext(pos);
+
+ CComQIPtr<IAMExtendedSeeking, &IID_IAMExtendedSeeking> pES = pBF;
+ if(!pES) continue;
+
+ long MarkerCount = 0;
+ if(SUCCEEDED(pES->get_MarkerCount(&MarkerCount)))
+ {
+ for(long i = 1; i <= MarkerCount; i++)
+ {
+ double MarkerTime = 0;
+ if(SUCCEEDED(pES->GetMarkerTime(i, &MarkerTime)))
+ {
+ CStringW name;
+ name.Format(L"Chapter %d", i);
+
+ CComBSTR bstr;
+ if(S_OK == pES->GetMarkerName(i, &bstr))
+ name = bstr;
+
+ m_pCB->ChapAppend(REFERENCE_TIME(MarkerTime*10000000), name);
+ }
+ }
+ }
+ }
+
+ pos = pBFs.GetHeadPosition();
+ while(pos && !m_pCB->ChapGetCount())
+ {
+ IBaseFilter* pBF = pBFs.GetNext(pos);
+
+ if(GetCLSID(pBF) != CLSID_OggSplitter)
+ continue;
+
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ if(m_pCB->ChapGetCount()) break;
+
+ if(CComQIPtr<IPropertyBag> pPB = pPin)
+ {
+ for(int i = 1; ; i++)
+ {
+ CStringW str;
+ CComVariant var;
+
+ var.Clear();
+ str.Format(L"CHAPTER%02d", i);
+ if(S_OK != pPB->Read(str, &var, NULL))
+ break;
+
+ int h, m, s, ms;
+ WCHAR wc;
+ if(7 != swscanf(CStringW(var), L"%d%c%d%c%d%c%d", &h, &wc, &m, &wc, &s, &wc, &ms))
+ break;
+
+ CStringW name;
+ name.Format(L"Chapter %d", i);
+ var.Clear();
+ str += L"NAME";
+ if(S_OK == pPB->Read(str, &var, NULL))
+ name = var;
+
+ m_pCB->ChapAppend(10000i64*(((h*60 + m)*60 + s)*1000 + ms), name);
+ }
+ }
+ }
+ EndEnumPins
+ }
+
+ m_pCB->ChapSort();
+}
+
+void CMainFrame::OpenDVD(OpenDVDData* pODD)
+{
+ HRESULT hr = pGB->RenderFile(CStringW(pODD->path), NULL);
+
+ AppSettings& s = AfxGetAppSettings();
+
+ if(s.fReportFailedPins)
+ {
+ CComQIPtr<IGraphBuilderDeadEnd> pGBDE = pGB;
+ if(pGBDE && pGBDE->GetCount()) CMediaTypesDlg(pGBDE, this).DoModal();
+ }
+
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ if((pDVDC = pBF) && (pDVDI = pBF))
+ break;
+ }
+ EndEnumFilters
+
+ if(hr == E_INVALIDARG)
+ throw _T("Cannot find DVD directory");
+ else if(hr == VFW_E_CANNOT_RENDER)
+ throw _T("Failed to render all pins of the DVD Navigator filter");
+ else if(hr == VFW_S_PARTIAL_RENDER)
+ throw _T("Failed to render some of the pins of the DVD Navigator filter");
+ else if(hr == E_NOINTERFACE || !pDVDC || !pDVDI)
+ throw _T("Failed to query the needed interfaces for DVD playback");
+ else if(hr == VFW_E_CANNOT_LOAD_SOURCE_FILTER)
+ throw _T("Can't create the DVD Navigator filter");
+ else if(FAILED(hr))
+ throw _T("Failed");
+
+ WCHAR buff[MAX_PATH];
+ ULONG len = 0;
+ if(SUCCEEDED(hr = pDVDI->GetDVDDirectory(buff, countof(buff), &len)))
+ pODD->title = CString(CStringW(buff));
+
+ // TODO: resetdvd
+ pDVDC->SetOption(DVD_ResetOnStop, FALSE);
+ pDVDC->SetOption(DVD_HMSF_TimeCodeEvents, TRUE);
+
+ if(s.idMenuLang) pDVDC->SelectDefaultMenuLanguage(s.idMenuLang);
+ if(s.idAudioLang) pDVDC->SelectDefaultAudioLanguage(s.idAudioLang, DVD_AUD_EXT_NotSpecified);
+ if(s.idSubtitlesLang) pDVDC->SelectDefaultSubpictureLanguage(s.idSubtitlesLang, DVD_SP_EXT_NotSpecified);
+
+ m_iDVDDomain = DVD_DOMAIN_Stop;
+
+ m_iPlaybackMode = PM_DVD;
+}
+
+void CMainFrame::OpenCapture(OpenDeviceData* pODD)
+{
+ CStringW vidfrname, audfrname;
+ CComPtr<IBaseFilter> pVidCapTmp, pAudCapTmp;
+
+ m_VidDispName = pODD->DisplayName[0];
+
+ if(!m_VidDispName.IsEmpty())
+ {
+ if(!CreateFilter(m_VidDispName, &pVidCapTmp, vidfrname))
+ throw _T("Can't create video capture filter");
+ }
+
+ m_AudDispName = pODD->DisplayName[1];
+
+ if(!m_AudDispName.IsEmpty())
+ {
+ if(!CreateFilter(m_AudDispName, &pAudCapTmp, audfrname))
+ throw _T("Can't create video capture filter");
+ }
+
+ if(!pVidCapTmp && !pAudCapTmp)
+ {
+ throw _T("No capture filters");
+ }
+
+ pCGB = NULL;
+ pVidCap = NULL;
+ pAudCap = NULL;
+
+ if(FAILED(pCGB.CoCreateInstance(CLSID_CaptureGraphBuilder2)))
+ {
+ throw _T("Can't create capture graph builder object");
+ }
+
+ HRESULT hr;
+
+ pCGB->SetFiltergraph(pGB);
+
+ if(pVidCapTmp)
+ {
+ if(FAILED(hr = pGB->AddFilter(pVidCapTmp, vidfrname)))
+ {
+ throw _T("Can't add video capture filter to the graph");
+ }
+
+ pVidCap = pVidCapTmp;
+
+ if(!pAudCapTmp)
+ {
+ if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCCap))
+ && FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCCap)))
+ TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
+
+ if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Interleaved, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCPrev))
+ && FAILED(pCGB->FindInterface(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCPrev)))
+ TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
+
+ if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, pVidCap, IID_IAMStreamConfig, (void **)&pAMASC))
+ && FAILED(pCGB->FindInterface(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Audio, pVidCap, IID_IAMStreamConfig, (void **)&pAMASC)))
+ {
+ TRACE(_T("Warning: No IAMStreamConfig interface for vidcap"));
+ }
+ else
+ {
+ pAudCap = pVidCap;
+ }
+ }
+ else
+ {
+ if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCCap)))
+ TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
+
+ if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCPrev)))
+ TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
+ }
+
+ if(FAILED(pCGB->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pVidCap, IID_IAMCrossbar, (void**)&pAMXBar)))
+ TRACE(_T("Warning: No IAMCrossbar interface was found\n"));
+
+ if(FAILED(pCGB->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pVidCap, IID_IAMTVTuner, (void**)&pAMTuner)))
+ TRACE(_T("Warning: No IAMTVTuner interface was found\n"));
+/*
+ if(pAMVSCCap)
+ {
+//DumpStreamConfig(_T("c:\\mpclog.txt"), pAMVSCCap);
+ CComQIPtr<IAMVfwCaptureDialogs> pVfwCD = pVidCap;
+ if(!pAMXBar && pVfwCD)
+ {
+ m_wndCaptureBar.m_capdlg.SetupVideoControls(viddispname, pAMVSCCap, pVfwCD);
+ }
+ else
+ {
+ m_wndCaptureBar.m_capdlg.SetupVideoControls(viddispname, pAMVSCCap, pAMXBar, pAMTuner);
+ }
+ }
+*/
+ // TODO: init pAMXBar
+
+ if(pAMTuner) // load saved channel
+ {
+ pAMTuner->put_CountryCode(AfxGetApp()->GetProfileInt(_T("Capture"), _T("Country"), 1));
+
+ int vchannel = pODD->vchannel;
+ if(vchannel < 0) vchannel = AfxGetApp()->GetProfileInt(_T("Capture\\") + CString(m_VidDispName), _T("Channel"), -1);
+ if(vchannel >= 0)
+ {
+ OAFilterState fs = State_Stopped;
+ pMC->GetState(0, &fs);
+ if(fs == State_Running) pMC->Pause();
+ pAMTuner->put_Channel(vchannel, AMTUNER_SUBCHAN_DEFAULT, AMTUNER_SUBCHAN_DEFAULT);
+ if(fs == State_Running) pMC->Run();
+ }
+ }
+ }
+
+ if(pAudCapTmp)
+ {
+ if(FAILED(hr = pGB->AddFilter(pAudCapTmp, CStringW(audfrname))))
+ {
+ throw _T("Can't add audio capture filter to the graph");
+ }
+
+ pAudCap = pAudCapTmp;
+
+ if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, pAudCap, IID_IAMStreamConfig, (void **)&pAMASC))
+ && FAILED(pCGB->FindInterface(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Audio, pAudCap, IID_IAMStreamConfig, (void **)&pAMASC)))
+ {
+ TRACE(_T("Warning: No IAMStreamConfig interface for vidcap"));
+ }
+/*
+ CInterfaceArray<IAMAudioInputMixer> pAMAIM;
+
+ BeginEnumPins(pAudCap, pEP, pPin)
+ {
+ PIN_DIRECTION dir;
+ if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_INPUT)
+ continue;
+
+ if(CComQIPtr<IAMAudioInputMixer> pAIM = pPin)
+ pAMAIM.Add(pAIM);
+ }
+ EndEnumPins
+
+ if(pAMASC)
+ {
+ m_wndCaptureBar.m_capdlg.SetupAudioControls(auddispname, pAMASC, pAMAIM);
+ }
+*/
+ }
+
+ if(!(pVidCap || pAudCap))
+ {
+ throw _T("Couldn't open any device");
+ }
+
+ pODD->title = _T("Live");
+
+ m_iPlaybackMode = PM_CAPTURE;
+}
+
+void CMainFrame::OpenCustomizeGraph()
+{
+ if(m_iPlaybackMode == PM_CAPTURE)
+ return;
+
+ CleanGraph();
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ if(m_pCAP)
+ AddTextPassThruFilter();
+ }
+
+ if(m_iPlaybackMode == PM_DVD)
+ {
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ if(CComQIPtr<IDirectVobSub2> pDVS2 = pBF)
+ {
+// pDVS2->AdviseSubClock(m_pSubClock = new CSubClock);
+// break;
+
+ // TODO: test multiple dvobsub instances with one clock
+ if(!m_pSubClock) m_pSubClock = new CSubClock;
+ pDVS2->AdviseSubClock(m_pSubClock);
+ }
+ }
+ EndEnumFilters
+ }
+
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ if(GetCLSID(pBF) == CLSID_OggSplitter)
+ {
+ if(CComQIPtr<IAMStreamSelect> pSS = pBF)
+ {
+ LCID idAudio = AfxGetAppSettings().idAudioLang;
+ if(!idAudio) idAudio = GetUserDefaultLCID();
+ LCID idSub = AfxGetAppSettings().idSubtitlesLang;
+ if(!idSub) idSub = GetUserDefaultLCID();
+
+ DWORD cnt = 0;
+ pSS->Count(&cnt);
+ for(DWORD i = 0; i < cnt; i++)
+ {
+ AM_MEDIA_TYPE* pmt = NULL;
+ DWORD dwFlags = 0;
+ LCID lcid = 0;
+ DWORD dwGroup = 0;
+ WCHAR* pszName = NULL;
+ if(SUCCEEDED(pSS->Info((long)i, &pmt, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL)))
+ {
+ CStringW name(pszName), sound(L"Sound"), subtitle(L"Subtitle");
+
+ if(idAudio != -1 && (idAudio&0x3ff) == (lcid&0x3ff) // sublang seems to be zeroed out in ogm...
+ && name.GetLength() > sound.GetLength()
+ && !name.Left(sound.GetLength()).CompareNoCase(sound))
+ {
+ if(SUCCEEDED(pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE)))
+ idAudio = -1;
+ }
+
+ if(idSub != -1 && (idSub&0x3ff) == (lcid&0x3ff) // sublang seems to be zeroed out in ogm...
+ && name.GetLength() > subtitle.GetLength()
+ && !name.Left(subtitle.GetLength()).CompareNoCase(subtitle)
+ && name.Mid(subtitle.GetLength()).Trim().CompareNoCase(L"off"))
+ {
+ if(SUCCEEDED(pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE)))
+ idSub = -1;
+ }
+
+ if(pmt) DeleteMediaType(pmt);
+ if(pszName) CoTaskMemFree(pszName);
+ }
+ }
+ }
+ }
+ }
+ EndEnumFilters
+
+ CleanGraph();
+}
+
+void CMainFrame::OpenSetupVideo()
+{
+ m_fAudioOnly = true;
+
+ if(m_pCAP)
+ {
+ CSize vs = m_pCAP->GetVideoSize();
+ m_fAudioOnly = (vs.cx <= 0 || vs.cy <= 0);
+ }
+ else
+ {
+ {
+ long w = 0, h = 0;
+
+ if(CComQIPtr<IBasicVideo> pBV = pGB)
+ {
+ pBV->GetVideoSize(&w, &h);
+ }
+
+ if(w > 0 && h > 0)
+ {
+ m_fAudioOnly = false;
+ }
+ }
+
+ if(m_fAudioOnly)
+ {
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ long w = 0, h = 0;
+
+ if(CComQIPtr<IVideoWindow> pVW = pBF)
+ {
+ long lVisible;
+ if(FAILED(pVW->get_Visible(&lVisible)))
+ continue;
+
+ pVW->get_Width(&w);
+ pVW->get_Height(&h);
+ }
+
+ if(w > 0 && h > 0)
+ {
+ m_fAudioOnly = false;
+ break;
+ }
+ }
+ EndEnumFilters
+ }
+ }
+
+ if(m_fShockwaveGraph)
+ {
+ m_fAudioOnly = false;
+ }
+
+ if(m_pCAP)
+ {
+ SetShaders();
+ }
+ // else
+ {
+ // TESTME
+
+ pVW->put_Owner((OAHWND)m_pVideoWnd->m_hWnd);
+ pVW->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
+ pVW->put_MessageDrain((OAHWND)m_hWnd);
+
+ for(CWnd* pWnd = m_wndView.GetWindow(GW_CHILD); pWnd; pWnd = pWnd->GetNextWindow())
+ pWnd->EnableWindow(FALSE); // little trick to let WM_SETCURSOR thru
+ }
+}
+
+void CMainFrame::OpenSetupAudio()
+{
+ pBA->put_Volume(m_wndToolBar.Volume);
+
+ // FIXME
+ int balance = AfxGetAppSettings().nBalance;
+ int sign = balance>0?-1:1;
+ balance = max(100-abs(balance), 1);
+ balance = (int)((log10(1.0*balance)-2)*5000*sign);
+ balance = max(min(balance, 10000), -10000);
+ pBA->put_Balance(balance);
+}
+/*
+void CMainFrame::OpenSetupToolBar()
+{
+// m_wndToolBar.Volume = AfxGetAppSettings().nVolume;
+// SetBalance(AfxGetAppSettings().nBalance);
+}
+*/
+void CMainFrame::OpenSetupCaptureBar()
+{
+ if(m_iPlaybackMode == PM_CAPTURE)
+ {
+ if(pVidCap && pAMVSCCap)
+ {
+ CComQIPtr<IAMVfwCaptureDialogs> pVfwCD = pVidCap;
+
+ if(!pAMXBar && pVfwCD)
+ {
+ m_wndCaptureBar.m_capdlg.SetupVideoControls(m_VidDispName, pAMVSCCap, pVfwCD);
+ }
+ else
+ {
+ m_wndCaptureBar.m_capdlg.SetupVideoControls(m_VidDispName, pAMVSCCap, pAMXBar, pAMTuner);
+ }
+ }
+
+ if(pAudCap && pAMASC)
+ {
+ CInterfaceArray<IAMAudioInputMixer> pAMAIM;
+
+ BeginEnumPins(pAudCap, pEP, pPin)
+ {
+ if(CComQIPtr<IAMAudioInputMixer> pAIM = pPin)
+ pAMAIM.Add(pAIM);
+ }
+ EndEnumPins
+
+ m_wndCaptureBar.m_capdlg.SetupAudioControls(m_AudDispName, pAMASC, pAMAIM);
+ }
+ }
+
+ BuildGraphVideoAudio(
+ m_wndCaptureBar.m_capdlg.m_fVidPreview, false,
+ m_wndCaptureBar.m_capdlg.m_fAudPreview, false);
+}
+
+void CMainFrame::OpenSetupInfoBar()
+{
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ bool fEmpty = true;
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ if(CComQIPtr<IAMMediaContent, &IID_IAMMediaContent> pAMMC = pBF)
+ {
+ CComBSTR bstr;
+ if(SUCCEEDED(pAMMC->get_Title(&bstr))) {m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_TITLE), bstr.m_str); if(bstr.Length()) fEmpty = false;}
+ if(SUCCEEDED(pAMMC->get_AuthorName(&bstr))) {m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_AUTHOR), bstr.m_str); if(bstr.Length()) fEmpty = false;}
+ if(SUCCEEDED(pAMMC->get_Copyright(&bstr))) {m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_COPYRIGHT), bstr.m_str); if(bstr.Length()) fEmpty = false;}
+ if(SUCCEEDED(pAMMC->get_Rating(&bstr))) {m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_RATING), bstr.m_str); if(bstr.Length()) fEmpty = false;}
+ if(SUCCEEDED(pAMMC->get_Description(&bstr))) {m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_DESCRIPTION), bstr.m_str); if(bstr.Length()) fEmpty = false;}
+ if(!fEmpty)
+ {
+ RecalcLayout();
+ break;
+ }
+ }
+ }
+ EndEnumFilters
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ CString info('-');
+ m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_DOMAIN), info);
+ m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_LOCATION), info);
+ m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_VIDEO), info);
+ m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_AUDIO), info);
+ m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_SUBTITLES), info);
+ RecalcLayout();
+ }
+}
+
+void CMainFrame::OpenSetupStatsBar()
+{
+ CString info('-');
+
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ if(!pQP && (pQP = pBF))
+ {
+ m_wndStatsBar.SetLine(_T("Frame-rate"), info);
+ m_wndStatsBar.SetLine(_T("Sync Offset"), info);
+ m_wndStatsBar.SetLine(_T("Frames"), info);
+ m_wndStatsBar.SetLine(_T("Jitter"), info);
+ m_wndStatsBar.SetLine(_T("Buffers"), info);
+ m_wndStatsBar.SetLine(_T("Bitrate"), info);
+ RecalcLayout();
+ }
+
+ if(!pBI && (pBI = pBF))
+ {
+ m_wndStatsBar.SetLine(_T("Buffers"), info);
+ m_wndStatsBar.SetLine(_T("Bitrate"), info); // FIXME: shouldn't be here
+ RecalcLayout();
+ }
+ }
+ EndEnumFilters
+}
+
+void CMainFrame::OpenSetupStatusBar()
+{
+ m_wndStatusBar.ShowTimer(true);
+
+ //
+
+ if(!m_fCustomGraph)
+ {
+ UINT id = IDB_NOAUDIO;
+
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ CComQIPtr<IBasicAudio> pBA = pBF;
+ if(!pBA) continue;
+
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ if(S_OK == pGB->IsPinDirection(pPin, PINDIR_INPUT)
+ && S_OK == pGB->IsPinConnected(pPin))
+ {
+ AM_MEDIA_TYPE mt;
+ memset(&mt, 0, sizeof(mt));
+ pPin->ConnectionMediaType(&mt);
+
+ if(mt.majortype == MEDIATYPE_Audio && mt.formattype == FORMAT_WaveFormatEx)
+ {
+ switch(((WAVEFORMATEX*)mt.pbFormat)->nChannels)
+ {
+ case 1: id = IDB_MONO; break;
+ case 2: default: id = IDB_STEREO; break;
+ }
+ break;
+ }
+ else if(mt.majortype == MEDIATYPE_Midi)
+ {
+ id = NULL;
+ break;
+ }
+ }
+ }
+ EndEnumPins
+
+ if(id != IDB_NOAUDIO)
+ {
+ break;
+ }
+ }
+ EndEnumFilters
+
+ m_wndStatusBar.SetStatusBitmap(id);
+ }
+
+ //
+
+ HICON hIcon = NULL;
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ CString fn = m_wndPlaylistBar.GetCur();
+ CString ext = fn.Mid(fn.ReverseFind('.')+1);
+ hIcon = LoadIcon(ext, true);
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ hIcon = LoadIcon(_T(".ifo"), true);
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ // hIcon = ; // TODO
+ }
+
+ m_wndStatusBar.SetStatusTypeIcon(hIcon);
+}
+
+void CMainFrame::OpenSetupWindowTitle(CString fn)
+{
+ CString title(MAKEINTRESOURCE(IDR_MAINFRAME));
+
+ AppSettings& s = AfxGetAppSettings();
+
+ int i = s.iTitleBarTextStyle;
+
+ if(!fn.IsEmpty() && (i == 0 || i == 1))
+ {
+ if(i == 1)
+ {
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ fn.Replace('\\', '/');
+ CString fn2 = fn.Mid(fn.ReverseFind('/')+1);
+ if(!fn2.IsEmpty()) fn = fn2;
+ if(s.fTitleBarTextTitle)
+ {
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ if(CComQIPtr<IAMMediaContent, &IID_IAMMediaContent> pAMMC = pBF)
+ {
+ CComBSTR bstr;
+ if(SUCCEEDED(pAMMC->get_Title(&bstr)) && bstr.Length())
+ {
+ fn = CString(bstr.m_str);
+ break;
+ }
+ }
+ }
+ EndEnumFilters
+ }
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ fn = _T("DVD");
+ }
+ else if(m_iPlaybackMode == PM_CAPTURE)
+ {
+ fn = _T("Live");
+ }
+ }
+
+ title = fn + _T(" - ") + title;
+ }
+
+ SetWindowText(title);
+}
+
+bool CMainFrame::OpenMediaPrivate(CAutoPtr<OpenMediaData> pOMD)
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ if(m_iMediaLoadState != MLS_CLOSED)
+ {
+ ASSERT(0);
+ return(false);
+ }
+
+ if(!dynamic_cast<OpenFileData*>(pOMD.m_p)
+ && !dynamic_cast<OpenDVDData*>(pOMD.m_p)
+ && !dynamic_cast<OpenDeviceData*>(pOMD.m_p))
+ {
+ ASSERT(0);
+ return(false);
+ }
+
+ if(OpenFileData* pOFD = dynamic_cast<OpenFileData*>(pOMD.m_p))
+ {
+ if(pOFD->fns.IsEmpty())
+ return(false);
+
+ CString fn = pOFD->fns.GetHead();
+
+ int i = fn.Find(_T(":\\"));
+ if(i > 0)
+ {
+ CString drive = fn.Left(i+2);
+ UINT type = GetDriveType(drive);
+ CAtlList<CString> sl;
+ if(type == DRIVE_REMOVABLE || type == DRIVE_CDROM && GetCDROMType(drive[0], sl) != CDROM_Audio)
+ {
+ int ret = IDRETRY;
+ while(ret == IDRETRY)
+ {
+ WIN32_FIND_DATA findFileData;
+ HANDLE h = FindFirstFile(fn, &findFileData);
+ if(h != INVALID_HANDLE_VALUE)
+ {
+ FindClose(h);
+ ret = IDOK;
+ }
+ else
+ {
+ CString msg;
+ msg.Format(_T("%s was not found, please insert media containing this file."), fn);
+ ret = AfxMessageBox(msg, MB_RETRYCANCEL);
+ }
+ }
+
+ if(ret != IDOK)
+ return(false);
+ }
+ }
+ }
+
+ m_iMediaLoadState = MLS_LOADING;
+
+ // FIXME: Don't show "Closed" initially
+ PostMessage(WM_KICKIDLE);
+
+ CString err, aborted(_T("Aborted"));
+
+ m_fUpdateInfoBar = false;
+
+ try
+ {
+ CComQIPtr<IVMRMixerBitmap9> pVMB;
+ if(m_fOpeningAborted) throw aborted;
+
+ OpenCreateGraphObject(pOMD);
+
+ if(m_fOpeningAborted) throw aborted;
+
+ SetupIViAudReg();
+
+ if(m_fOpeningAborted) throw aborted;
+
+ if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p)) OpenFile(p);
+ else if(OpenDVDData* p = dynamic_cast<OpenDVDData*>(pOMD.m_p)) OpenDVD(p);
+ else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p)) OpenCapture(p);
+ else throw _T("Can't open, invalid input parameters");
+
+ pGB->FindInterface(__uuidof(ISubPicAllocatorPresenter), (void**)&m_pCAP, TRUE);
+ pGB->FindInterface(__uuidof(IVMRMixerControl9), (void**)&m_pMC, TRUE);
+ pGB->FindInterface(__uuidof(IVMRMixerBitmap9), (void**)&pVMB, TRUE);
+ if (pVMB) m_OSD.Start (m_pVideoWnd, pVMB);
+ if (m_pMC)
+ {
+ m_pMC->GetProcAmpControlRange (0, (VMR9ProcAmpControlRange*)AfxGetMyApp()->GetColorControl (Brightness));
+ m_pMC->GetProcAmpControlRange (0, (VMR9ProcAmpControlRange*)AfxGetMyApp()->GetColorControl (Contrast));
+ m_pMC->GetProcAmpControlRange (0, (VMR9ProcAmpControlRange*)AfxGetMyApp()->GetColorControl (Hue));
+ m_pMC->GetProcAmpControlRange (0, (VMR9ProcAmpControlRange*)AfxGetMyApp()->GetColorControl (Saturation));
+ SetVMR9ColorControl(s.dBrightness, s.dContrast, s.dHue, s.dSaturation);
+ }
+
+ if(m_fOpeningAborted) throw aborted;
+
+ OpenCustomizeGraph();
+
+ if(m_fOpeningAborted) throw aborted;
+
+ OpenSetupVideo();
+
+ if(m_fOpeningAborted) throw aborted;
+
+ OpenSetupAudio();
+
+ if(m_fOpeningAborted) throw aborted;
+
+ if(m_pCAP && (!m_fAudioOnly || m_fRealMediaGraph))
+ {
+ POSITION pos = pOMD->subs.GetHeadPosition();
+ while(pos) LoadSubtitle(pOMD->subs.GetNext(pos));
+
+ if(AfxGetAppSettings().fEnableSubtitles && m_pSubStreams.GetCount() > 0)
+ SetSubtitle(m_pSubStreams.GetHead());
+ }
+
+ if(m_fOpeningAborted) throw aborted;
+
+ OpenSetupWindowTitle(pOMD->title);
+
+ if(::GetCurrentThreadId() == AfxGetApp()->m_nThreadID)
+ {
+ OnFilePostOpenmedia();
+ }
+ else
+ {
+ PostMessage(WM_COMMAND, ID_FILE_POST_OPENMEDIA);
+ }
+
+ while(m_iMediaLoadState != MLS_LOADED
+ && m_iMediaLoadState != MLS_CLOSING // FIXME
+ )
+ {
+ Sleep(50);
+ }
+
+ // PostMessage instead of SendMessage because the user might call CloseMedia and then we would deadlock
+
+ PostMessage(WM_COMMAND, ID_PLAY_PAUSE);
+
+ if(!(AfxGetAppSettings().nCLSwitches&CLSW_OPEN))
+ PostMessage(WM_COMMAND, ID_PLAY_PLAY);
+
+ AfxGetAppSettings().nCLSwitches &= ~CLSW_OPEN;
+
+ if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p))
+ {
+ if(p->rtStart > 0)
+ PostMessage(WM_RESUMEFROMSTATE, (WPARAM)PM_FILE, (LPARAM)(p->rtStart/10000)); // REFERENCE_TIME doesn't fit in LPARAM under a 32bit env.
+ }
+ else if(OpenDVDData* p = dynamic_cast<OpenDVDData*>(pOMD.m_p))
+ {
+ if(p->pDvdState)
+ PostMessage(WM_RESUMEFROMSTATE, (WPARAM)PM_DVD, (LPARAM)(CComPtr<IDvdState>(p->pDvdState).Detach())); // must be released by the called message handler
+ }
+ else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
+ {
+ m_wndCaptureBar.m_capdlg.SetVideoInput(p->vinput);
+ m_wndCaptureBar.m_capdlg.SetVideoChannel(p->vchannel);
+ m_wndCaptureBar.m_capdlg.SetAudioInput(p->ainput);
+ }
+ }
+ catch(LPCTSTR msg)
+ {
+ err = msg;
+ }
+ catch(CString msg)
+ {
+ err = msg;
+ }
+
+ if(!err.IsEmpty())
+ {
+ CloseMediaPrivate();
+ m_closingmsg = err;
+
+ OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p);
+ if(p && err != aborted)
+ {
+ m_wndPlaylistBar.SetCurValid(false);
+ if(m_wndPlaylistBar.GetCount() > 1)
+ {
+ CPlaylistItem pli[2];
+ m_wndPlaylistBar.GetCur(pli[0]);
+ m_wndPlaylistBar.SetNext();
+ m_wndPlaylistBar.GetCur(pli[1]);
+ if(pli[0].m_id != pli[1].m_id)
+ {
+ CAutoPtr<OpenMediaData> p(m_wndPlaylistBar.GetCurOMD());
+ if(p) OpenMediaPrivate(p);
+ }
+ }
+ }
+ }
+ else
+ {
+ m_wndPlaylistBar.SetCurValid(true);
+ }
+
+ PostMessage(WM_KICKIDLE); // calls main thread to update things
+
+ return(err.IsEmpty());
+}
+
+void CMainFrame::CloseMediaPrivate()
+{
+ m_iMediaLoadState = MLS_CLOSING;
+
+ OnPlayStop(); // SendMessage(WM_COMMAND, ID_PLAY_STOP);
+
+ m_iPlaybackMode = PM_NONE;
+ m_iSpeedLevel = 0;
+
+ m_fLiveWM = false;
+
+ m_fEndOfStream = false;
+
+ m_rtDurationOverride = -1;
+
+ m_kfs.RemoveAll();
+
+ m_pCB = NULL;
+
+// if(pVW) pVW->put_Visible(OAFALSE);
+// if(pVW) pVW->put_MessageDrain((OAHWND)NULL), pVW->put_Owner((OAHWND)NULL);
+
+ m_pCAP = NULL; // IMPORTANT: IVMRSurfaceAllocatorNotify/IVMRSurfaceAllocatorNotify9 has to be released before the VMR/VMR9, otherwise it will crash in Release()
+ m_pMC = NULL;
+ m_OSD.Stop();
+
+ pAMXBar.Release(); pAMTuner.Release(); pAMDF.Release();
+ pAMVCCap.Release(); pAMVCPrev.Release(); pAMVSCCap.Release(); pAMVSCPrev.Release(); pAMASC.Release();
+ pVidCap.Release(); pAudCap.Release();
+ pCGB.Release();
+ pDVDC.Release(); pDVDI.Release();
+ pQP.Release(); pBI.Release(); pAMOP.Release(); pFS.Release();
+ pMC.Release(); pME.Release(); pMS.Release();
+ pVW.Release(); pBV.Release();
+ pBA.Release();
+
+ if(pGB) pGB->RemoveFromROT();
+ pGB.Release();
+
+ m_fRealMediaGraph = m_fShockwaveGraph = m_fQuicktimeGraph = false;
+
+ m_pSubClock = NULL;
+
+ m_pProv.Release();
+
+ {
+ CAutoLock cAutoLock(&m_csSubLock);
+ m_pSubStreams.RemoveAll();
+ }
+
+ m_VidDispName.Empty();
+ m_AudDispName.Empty();
+
+ m_closingmsg = ResStr(IDS_CONTROLS_CLOSED);
+
+ AfxGetAppSettings().nCLSwitches &= CLSW_OPEN|CLSW_PLAY|CLSW_AFTERPLAYBACK_MASK|CLSW_NOFOCUS;
+
+ m_iMediaLoadState = MLS_CLOSED;
+}
+
+// msn
+
+void CMainFrame::SendNowPlayingToMSN()
+{
+ if(!AfxGetAppSettings().fNotifyMSN)
+ return;
+
+ CString title, author;
+
+ if(m_iMediaLoadState == MLS_LOADED)
+ {
+ m_wndInfoBar.GetLine(ResStr(IDS_INFOBAR_TITLE), title);
+ m_wndInfoBar.GetLine(ResStr(IDS_INFOBAR_AUTHOR), author);
+
+ if(title.IsEmpty())
+ {
+ CPlaylistItem pli;
+ m_wndPlaylistBar.GetCur(pli);
+
+ if(!pli.m_fns.IsEmpty())
+ {
+ CString label = !pli.m_label.IsEmpty() ? pli.m_label : pli.m_fns.GetHead();
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ CString fn = label;
+ if(fn.Find(_T("://")) >= 0) {int i = fn.Find('?'); if(i >= 0) fn = fn.Left(i);}
+ CPath path(fn);
+ path.StripPath();
+ path.MakePretty();
+ path.RemoveExtension();
+ title = (LPCTSTR)path;
+ author.Empty();
+ }
+ else if(m_iPlaybackMode == PM_CAPTURE)
+ {
+ title = label != pli.m_fns.GetHead() ? label : _T("Live");
+ author.Empty();
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ title = _T("DVD");
+ author.Empty();
+ }
+ }
+ }
+ }
+
+ CStringW buff;
+ buff += L"\\0Music\\0";
+ buff += title.IsEmpty() ? L"0" : L"1";
+ buff += L"\\0";
+ buff += author.IsEmpty() ? L"{0}" : L"{0} - {1}";
+ buff += L"\\0";
+ if(!author.IsEmpty()) {buff += CStringW(author) + L"\\0";}
+ buff += CStringW(title) + L"\\0";
+ buff += L"\\0\\0";
+
+ COPYDATASTRUCT data;
+ data.dwData = 0x0547;
+ data.lpData = (PVOID)(LPCWSTR)buff;
+ data.cbData = buff.GetLength() * 2 + 2;
+
+ HWND hWnd = NULL;
+ while(hWnd = ::FindWindowEx(NULL, hWnd, _T("MsnMsgrUIManager"), NULL))
+ ::SendMessage(hWnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&data);
+}
+
+// mIRC
+
+void CMainFrame::SendNowPlayingTomIRC()
+{
+ if(!AfxGetAppSettings().fNotifyGTSdll)
+ return;
+
+ for(int i = 0; i < 20; i++)
+ {
+ HANDLE hFMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 1024, _T("mIRC"));
+ if(!hFMap) return;
+
+ if(GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ CloseHandle(hFMap);
+ Sleep(50);
+ continue;
+ }
+
+ if(LPVOID lpMappingAddress = MapViewOfFile(hFMap, FILE_MAP_WRITE, 0, 0, 0))
+ {
+ LPCSTR cmd = m_fAudioOnly ? "/.timerAUDGTS 1 5 mpcaud" : "/.timerVIDGTS 1 5 mpcvid";
+ strcpy((char*)lpMappingAddress, cmd);
+
+ if(HWND hWnd = ::FindWindow(_T("mIRC"), NULL))
+ ::SendMessage(hWnd, (WM_USER + 200), (WPARAM)1, (LPARAM)0);
+
+ UnmapViewOfFile(lpMappingAddress);
+ }
+
+ CloseHandle(hFMap);
+
+ break;
+ }
+}
+
+// dynamic menus
+
+void CMainFrame::SetupOpenCDSubMenu()
+{
+ CMenu* pSub = &m_opencds;
+
+ if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
+ else while(pSub->RemoveMenu(0, MF_BYPOSITION));
+
+ if(m_iMediaLoadState == MLS_LOADING) return;
+
+ if(AfxGetAppSettings().fHideCDROMsSubMenu) return;
+
+ UINT id = ID_FILE_OPEN_CD_START;
+
+ for(TCHAR drive = 'C'; drive <= 'Z'; drive++)
+ {
+ CString label = GetDriveLabel(drive), str;
+
+ CAtlList<CString> files;
+ switch(GetCDROMType(drive, files))
+ {
+ case CDROM_Audio:
+ if(label.IsEmpty()) label = _T("Audio CD");
+ str.Format(_T("%s (%c:)"), label, drive);
+ break;
+ case CDROM_VideoCD:
+ if(label.IsEmpty()) label = _T("(S)VCD");
+ str.Format(_T("%s (%c:)"), label, drive);
+ break;
+ case CDROM_DVDVideo:
+ if(label.IsEmpty()) label = _T("DVD Video");
+ str.Format(_T("%s (%c:)"), label, drive);
+ break;
+ default:
+ break;
+ }
+
+ if(!str.IsEmpty())
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, str);
+ }
+}
+
+void CMainFrame::SetupFiltersSubMenu()
+{
+ CMenu* pSub = &m_filters;
+
+ if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
+ else while(pSub->RemoveMenu(0, MF_BYPOSITION));
+
+ m_filterpopups.RemoveAll();
+
+ m_pparray.RemoveAll();
+ m_ssarray.RemoveAll();
+
+ if(m_iMediaLoadState == MLS_LOADED)
+ {
+ UINT idf = 0;
+ UINT ids = ID_FILTERS_SUBITEM_START;
+ UINT idl = ID_FILTERSTREAMS_SUBITEM_START;
+
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ CString name(GetFilterName(pBF));
+ if(name.GetLength() >= 43) name = name.Left(40) + _T("...");
+
+ CLSID clsid = GetCLSID(pBF);
+ if(clsid == CLSID_AVIDec)
+ {
+ CComPtr<IPin> pPin = GetFirstPin(pBF);
+ AM_MEDIA_TYPE mt;
+ if(pPin && SUCCEEDED(pPin->ConnectionMediaType(&mt)))
+ {
+ DWORD c = ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression;
+ switch(c)
+ {
+ case BI_RGB: name += _T(" (RGB)"); break;
+ case BI_RLE4: name += _T(" (RLE4)"); break;
+ case BI_RLE8: name += _T(" (RLE8)"); break;
+ case BI_BITFIELDS: name += _T(" (BITF)"); break;
+ default: name.Format(_T("%s (%c%c%c%c)"),
+ CString(name), (TCHAR)((c>>0)&0xff), (TCHAR)((c>>8)&0xff), (TCHAR)((c>>16)&0xff), (TCHAR)((c>>24)&0xff)); break;
+ }
+ }
+ }
+ else if(clsid == CLSID_ACMWrapper)
+ {
+ CComPtr<IPin> pPin = GetFirstPin(pBF);
+ AM_MEDIA_TYPE mt;
+ if(pPin && SUCCEEDED(pPin->ConnectionMediaType(&mt)))
+ {
+ WORD c = ((WAVEFORMATEX*)mt.pbFormat)->wFormatTag;
+ name.Format(_T("%s (0x%04x)"), CString(name), (int)c);
+ }
+ }
+ else if(clsid == __uuidof(CTextPassThruFilter) || clsid == __uuidof(CNullTextRenderer)
+ || clsid == GUIDFromCString(_T("{48025243-2D39-11CE-875D-00608CB78066}"))) // ISCR
+ {
+ // hide these
+ continue;
+ }
+
+ CAutoPtr<CMenu> pSubSub(new CMenu);
+ pSubSub->CreatePopupMenu();
+
+ int nPPages = 0;
+
+ CComQIPtr<ISpecifyPropertyPages> pSPP = pBF;
+
+/* if(pSPP)
+ {
+ CAUUID caGUID;
+ caGUID.pElems = NULL;
+ if(SUCCEEDED(pSPP->GetPages(&caGUID)) && caGUID.cElems > 0)
+ {
+*/ m_pparray.Add(pBF);
+ pSubSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ids, _T("&Properties..."));
+/*
+ if(caGUID.pElems) CoTaskMemFree(caGUID.pElems);
+*/
+ nPPages++;
+/* }
+ }
+*/
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ CString name = GetPinName(pPin);
+ name.Replace(_T("&"), _T("&&"));
+
+ if(pSPP = pPin)
+ {
+ CAUUID caGUID;
+ caGUID.pElems = NULL;
+ if(SUCCEEDED(pSPP->GetPages(&caGUID)) && caGUID.cElems > 0)
+ {
+ m_pparray.Add(pPin);
+ pSubSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ids+nPPages, name + _T(" (pin) properties..."));
+
+ if(caGUID.pElems) CoTaskMemFree(caGUID.pElems);
+
+ nPPages++;
+ }
+ }
+ }
+ EndEnumPins
+
+ CComQIPtr<IAMStreamSelect> pSS = pBF;
+ if(pSS)
+ {
+ DWORD nStreams = 0, flags, group, prevgroup = -1;
+ LCID lcid;
+ WCHAR* wname = NULL;
+ CComPtr<IUnknown> pObj, pUnk;
+
+ pSS->Count(&nStreams);
+
+ if(nStreams > 0 && nPPages > 0) pSubSub->AppendMenu(MF_SEPARATOR|MF_ENABLED);
+
+ UINT idlstart = idl;
+
+ for(DWORD i = 0; i < nStreams; i++, pObj = NULL, pUnk = NULL)
+ {
+ m_ssarray.Add(pSS);
+
+ flags = group = 0;
+ wname = NULL;
+ pSS->Info(i, NULL, &flags, &lcid, &group, &wname, &pObj, &pUnk);
+
+ if(group != prevgroup && idl > idlstart)
+ pSubSub->AppendMenu(MF_SEPARATOR|MF_ENABLED);
+ prevgroup = group;
+
+ if(flags & AMSTREAMSELECTINFO_EXCLUSIVE)
+ {
+ }
+ else if(flags & AMSTREAMSELECTINFO_ENABLED)
+ {
+ }
+
+ if(!wname)
+ {
+ CStringW stream(L"Unknown Stream");
+ wname = (WCHAR*)CoTaskMemAlloc((stream.GetLength()+3+1)*sizeof(WCHAR));
+ swprintf(wname, L"%s %d", stream, min(i+1,999));
+ }
+
+ CString name(wname);
+ name.Replace(_T("&"), _T("&&"));
+
+ pSubSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, idl++, name);
+
+ CoTaskMemFree(wname);
+ }
+
+ if(nStreams == 0) pSS.Release();
+ }
+
+ if(nPPages == 1 && !pSS)
+ {
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ids, name);
+ }
+ else
+ {
+ pSub->AppendMenu(MF_BYPOSITION|MF_STRING|MF_DISABLED|MF_GRAYED, idf, name);
+
+ if(nPPages > 0 || pSS)
+ {
+ MENUITEMINFO mii;
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STATE|MIIM_SUBMENU;
+ mii.fType = MF_POPUP;
+ mii.hSubMenu = pSubSub->m_hMenu;
+ mii.fState = (pSPP || pSS) ? MF_ENABLED : (MF_DISABLED|MF_GRAYED);
+ pSub->SetMenuItemInfo(idf, &mii, TRUE);
+
+ m_filterpopups.Add(pSubSub);
+ }
+ }
+
+ ids += nPPages;
+ idf++;
+ }
+ EndEnumFilters
+ }
+}
+
+void CMainFrame::SetupAudioSwitcherSubMenu()
+{
+ CMenu* pSub = &m_audios;
+
+ if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
+ else while(pSub->RemoveMenu(0, MF_BYPOSITION));
+
+ if(m_iMediaLoadState == MLS_LOADED)
+ {
+ UINT id = ID_AUDIO_SUBITEM_START;
+
+ CComQIPtr<IAMStreamSelect> pSS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB);
+ if(!pSS) pSS = FindFilter(L"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB);
+
+ if(pSS)
+ {
+ DWORD cStreams = 0;
+ if(SUCCEEDED(pSS->Count(&cStreams)) && cStreams > 0)
+ {
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, ResStr(IDS_SUBTITLES_OPTIONS));
+ pSub->AppendMenu(MF_SEPARATOR|MF_ENABLED);
+
+ for(int i = 0; i < (int)cStreams; i++)
+ {
+ WCHAR* pName = NULL;
+ if(FAILED(pSS->Info(i, NULL, NULL, NULL, NULL, &pName, NULL, NULL)))
+ break;
+
+ CString name(pName);
+ name.Replace(_T("&"), _T("&&"));
+
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, name);
+
+ CoTaskMemFree(pName);
+ }
+ }
+ }
+ }
+}
+
+void CMainFrame::SetupSubtitlesSubMenu()
+{
+ CMenu* pSub = &m_subtitles;
+
+ if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
+ else while(pSub->RemoveMenu(0, MF_BYPOSITION));
+
+ if(m_iMediaLoadState != MLS_LOADED || m_fAudioOnly || !m_pCAP)
+ return;
+
+ UINT id = ID_SUBTITLES_SUBITEM_START;
+
+ POSITION pos = m_pSubStreams.GetHeadPosition();
+
+ if(pos)
+ {
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, ResStr(IDS_SUBTITLES_OPTIONS));
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, ResStr(IDS_SUBTITLES_STYLES));
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, ResStr(IDS_SUBTITLES_RELOAD));
+ pSub->AppendMenu(MF_SEPARATOR);
+
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, ResStr(IDS_SUBTITLES_ENABLE));
+ pSub->AppendMenu(MF_SEPARATOR);
+ }
+
+ while(pos)
+ {
+ CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
+ if(!pSubStream) continue;
+
+ for(int i = 0, j = pSubStream->GetStreamCount(); i < j; i++)
+ {
+ WCHAR* pName = NULL;
+ if(SUCCEEDED(pSubStream->GetStreamInfo(i, &pName, NULL)))
+ {
+ CString name(pName);
+ name.Replace(_T("&"), _T("&&"));
+
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, name);
+ CoTaskMemFree(pName);
+ }
+ else
+ {
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, _T("<Unknown>"));
+ }
+ }
+
+ // TODO: find a better way to group these entries
+ if(pos && m_pSubStreams.GetAt(pos))
+ {
+ CLSID cur, next;
+ pSubStream->GetClassID(&cur);
+ m_pSubStreams.GetAt(pos)->GetClassID(&next);
+
+ if(cur != next)
+ pSub->AppendMenu(MF_SEPARATOR);
+ }
+ }
+}
+
+void CMainFrame::SetupNavAudioSubMenu()
+{
+ CMenu* pSub = &m_navaudio;
+
+ if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
+ else while(pSub->RemoveMenu(0, MF_BYPOSITION));
+
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ UINT id = ID_NAVIGATE_AUDIO_SUBITEM_START;
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ SetupNavStreamSelectSubMenu(pSub, id, 1);
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ ULONG ulStreamsAvailable, ulCurrentStream;
+ if(FAILED(pDVDI->GetCurrentAudio(&ulStreamsAvailable, &ulCurrentStream)))
+ return;
+
+ LCID DefLanguage;
+ DVD_AUDIO_LANG_EXT ext;
+ if(FAILED(pDVDI->GetDefaultAudioLanguage(&DefLanguage, &ext)))
+ return;
+
+ for(ULONG i = 0; i < ulStreamsAvailable; i++)
+ {
+ LCID Language;
+ if(FAILED(pDVDI->GetAudioLanguage(i, &Language)))
+ continue;
+
+ UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
+ if(Language == DefLanguage) flags |= MF_DEFAULT;
+ if(i == ulCurrentStream) flags |= MF_CHECKED;
+
+ CString str(_T("Unknown"));
+ if(Language)
+ {
+ int len = GetLocaleInfo(Language, LOCALE_SENGLANGUAGE, str.GetBuffer(256), 256);
+ str.ReleaseBufferSetLength(max(len-1, 0));
+ }
+
+ DVD_AudioAttributes ATR;
+ if(SUCCEEDED(pDVDI->GetAudioAttributes(i, &ATR)))
+ {
+ switch(ATR.LanguageExtension)
+ {
+ case DVD_AUD_EXT_NotSpecified:
+ default: break;
+ case DVD_AUD_EXT_Captions: str += _T(" (Captions)"); break;
+ case DVD_AUD_EXT_VisuallyImpaired: str += _T(" (Visually Impaired)"); break;
+ case DVD_AUD_EXT_DirectorComments1: str += _T(" (Director Comments 1)"); break;
+ case DVD_AUD_EXT_DirectorComments2: str += _T(" (Director Comments 2)"); break;
+ }
+
+ CString format = GetDVDAudioFormatName(ATR);
+
+ if(!format.IsEmpty())
+ {
+ str.Format(_T("%s, %s %dHz %dbits %d channel(s)"),
+ CString(str),
+ format,
+ ATR.dwFrequency,
+ ATR.bQuantization,
+ ATR.bNumberOfChannels);
+ }
+ }
+
+ str.Replace(_T("&"), _T("&&"));
+
+ pSub->AppendMenu(flags, id++, str);
+ }
+ }
+}
+
+void CMainFrame::SetupNavSubtitleSubMenu()
+{
+ CMenu* pSub = &m_navsubtitle;
+
+ if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
+ else while(pSub->RemoveMenu(0, MF_BYPOSITION));
+
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ UINT id = ID_NAVIGATE_SUBP_SUBITEM_START;
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ SetupNavStreamSelectSubMenu(pSub, id, 2);
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ ULONG ulStreamsAvailable, ulCurrentStream;
+ BOOL bIsDisabled;
+ if(FAILED(pDVDI->GetCurrentSubpicture(&ulStreamsAvailable, &ulCurrentStream, &bIsDisabled))
+ || ulStreamsAvailable == 0)
+ return;
+
+ LCID DefLanguage;
+ DVD_SUBPICTURE_LANG_EXT ext;
+ if(FAILED(pDVDI->GetDefaultSubpictureLanguage(&DefLanguage, &ext)))
+ return;
+
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|(bIsDisabled?0:MF_CHECKED), id++, _T("Enabled"));
+ pSub->AppendMenu(MF_BYCOMMAND|MF_SEPARATOR|MF_ENABLED);
+
+ for(ULONG i = 0; i < ulStreamsAvailable; i++)
+ {
+ LCID Language;
+ if(FAILED(pDVDI->GetSubpictureLanguage(i, &Language)))
+ continue;
+
+ UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
+ if(Language == DefLanguage) flags |= MF_DEFAULT;
+ if(i == ulCurrentStream) flags |= MF_CHECKED;
+
+ CString str(_T("Unknown"));
+ if(Language)
+ {
+ int len = GetLocaleInfo(Language, LOCALE_SENGLANGUAGE, str.GetBuffer(256), 256);
+ str.ReleaseBufferSetLength(max(len-1, 0));
+ }
+
+ DVD_SubpictureAttributes ATR;
+ if(SUCCEEDED(pDVDI->GetSubpictureAttributes(i, &ATR)))
+ {
+ switch(ATR.LanguageExtension)
+ {
+ case DVD_SP_EXT_NotSpecified:
+ default: break;
+ case DVD_SP_EXT_Caption_Normal: str += _T(""); break;
+ case DVD_SP_EXT_Caption_Big: str += _T(" (Big)"); break;
+ case DVD_SP_EXT_Caption_Children: str += _T(" (Children)"); break;
+ case DVD_SP_EXT_CC_Normal: str += _T(" (CC)"); break;
+ case DVD_SP_EXT_CC_Big: str += _T(" (CC Big)"); break;
+ case DVD_SP_EXT_CC_Children: str += _T(" (CC Children)"); break;
+ case DVD_SP_EXT_Forced: str += _T(" (Forced)"); break;
+ case DVD_SP_EXT_DirectorComments_Normal: str += _T(" (Director Comments)"); break;
+ case DVD_SP_EXT_DirectorComments_Big: str += _T(" (Director Comments, Big)"); break;
+ case DVD_SP_EXT_DirectorComments_Children: str += _T(" (Director Comments, Children)"); break;
+ }
+ }
+
+ str.Replace(_T("&"), _T("&&"));
+
+ pSub->AppendMenu(flags, id++, str);
+ }
+ }
+}
+
+void CMainFrame::SetupNavAngleSubMenu()
+{
+ CMenu* pSub = &m_navangle;
+
+ if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
+ else while(pSub->RemoveMenu(0, MF_BYPOSITION));
+
+ if(m_iMediaLoadState != MLS_LOADED) return;
+
+ UINT id = ID_NAVIGATE_ANGLE_SUBITEM_START;
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ SetupNavStreamSelectSubMenu(pSub, id, 0);
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ ULONG ulStreamsAvailable, ulCurrentStream;
+ if(FAILED(pDVDI->GetCurrentAngle(&ulStreamsAvailable, &ulCurrentStream)))
+ return;
+
+ if(ulStreamsAvailable < 2) return; // one choice is not a choice...
+
+ for(ULONG i = 1; i <= ulStreamsAvailable; i++)
+ {
+ UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
+ if(i == ulCurrentStream) flags |= MF_CHECKED;
+
+ CString str;
+ str.Format(_T("Angle %d"), i);
+
+ pSub->AppendMenu(flags, id++, str);
+ }
+ }
+}
+
+void CMainFrame::SetupNavChaptersSubMenu()
+{
+ CMenu* pSub = &m_navchapters;
+
+ if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
+ else while(pSub->RemoveMenu(0, MF_BYPOSITION));
+
+ if(m_iMediaLoadState != MLS_LOADED)
+ return;
+
+ UINT id = ID_NAVIGATE_CHAP_SUBITEM_START;
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ SetupChapters();
+
+ REFERENCE_TIME rt = GetPos();
+ DWORD j = m_pCB->ChapLookup(&rt, NULL);
+
+ for(DWORD i = 0; i < m_pCB->ChapGetCount(); i++, id++)
+ {
+ rt = 0;
+ CComBSTR bstr;
+ if(FAILED(m_pCB->ChapGet(i, &rt, &bstr)))
+ continue;
+
+ int s = (int)((rt/10000000)%60);
+ int m = (int)((rt/10000000/60)%60);
+ int h = (int)((rt/10000000/60/60));
+
+ CString time;
+ time.Format(_T("[%02d:%02d:%02d] "), h, m, s);
+
+ CString name = CString(bstr);
+ name.Replace(_T("&"), _T("&&"));
+ name.Replace(_T("\t"), _T(" "));
+
+ UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
+ if(i == j) flags |= MF_CHECKED;
+ if(id != ID_NAVIGATE_CHAP_SUBITEM_START && i == 0) pSub->AppendMenu(MF_SEPARATOR);
+ pSub->AppendMenu(flags, id, name + '\t' + time);
+ }
+
+ if(m_wndPlaylistBar.GetCount() > 1)
+ {
+ POSITION pos = m_wndPlaylistBar.m_pl.GetHeadPosition();
+ while(pos)
+ {
+ UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
+ if(pos == m_wndPlaylistBar.m_pl.GetPos()) flags |= MF_CHECKED;
+ if(id != ID_NAVIGATE_CHAP_SUBITEM_START && pos == m_wndPlaylistBar.m_pl.GetHeadPosition())
+ pSub->AppendMenu(MF_SEPARATOR);
+ CPlaylistItem& pli = m_wndPlaylistBar.m_pl.GetNext(pos);
+ CString name = pli.GetLabel();
+ name.Replace(_T("&"), _T("&&"));
+ pSub->AppendMenu(flags, id++, name);
+ }
+ }
+ }
+ else if(m_iPlaybackMode == PM_DVD)
+ {
+ ULONG ulNumOfVolumes, ulVolume;
+ DVD_DISC_SIDE Side;
+ ULONG ulNumOfTitles = 0;
+ pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles);
+
+ DVD_PLAYBACK_LOCATION2 Location;
+ pDVDI->GetCurrentLocation(&Location);
+
+ ULONG ulNumOfChapters = 0;
+ pDVDI->GetNumberOfChapters(Location.TitleNum, &ulNumOfChapters);
+
+ ULONG ulUOPs = 0;
+ pDVDI->GetCurrentUOPS(&ulUOPs);
+
+ for(ULONG i = 1; i <= ulNumOfTitles; i++)
+ {
+ UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
+ if(i == Location.TitleNum) flags |= MF_CHECKED;
+ if(ulUOPs&UOP_FLAG_Play_Title) flags |= MF_DISABLED|MF_GRAYED;
+
+ CString str;
+ str.Format(_T("Title %d"), i);
+
+ pSub->AppendMenu(flags, id++, str);
+ }
+
+ for(ULONG i = 1; i <= ulNumOfChapters; i++)
+ {
+ UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
+ if(i == Location.ChapterNum) flags |= MF_CHECKED;
+ if(ulUOPs&UOP_FLAG_Play_Chapter) flags |= MF_DISABLED|MF_GRAYED;
+ if(i == 1) flags |= MF_MENUBARBREAK;
+
+ CString str;
+ str.Format(_T("Chapter %d"), i);
+
+ pSub->AppendMenu(flags, id++, str);
+ }
+ }
+}
+
+void CMainFrame::SetupNavStreamSelectSubMenu(CMenu* pSub, UINT id, DWORD dwSelGroup)
+{
+ UINT baseid = id;
+
+ CComQIPtr<IAMStreamSelect> pSS = FindFilter(CLSID_OggSplitter, pGB);
+ if(!pSS) pSS = FindFilter(L"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB);
+ if(!pSS) return;
+
+ DWORD cStreams;
+ if(FAILED(pSS->Count(&cStreams)))
+ return;
+
+ DWORD dwPrevGroup = -1;
+
+ for(int i = 0, j = cStreams; i < j; i++)
+ {
+ DWORD dwFlags, dwGroup;
+ LCID lcid;
+ WCHAR* pszName = NULL;
+
+ if(FAILED(pSS->Info(i, NULL, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL))
+ || !pszName)
+ continue;
+
+ CString name(pszName);
+ CString lcname = CString(name).MakeLower();
+
+ if(pszName) CoTaskMemFree(pszName);
+
+ if(dwGroup != dwSelGroup)
+ continue;
+
+ if(dwPrevGroup != -1 && dwPrevGroup != dwGroup)
+ pSub->AppendMenu(MF_SEPARATOR);
+ dwPrevGroup = dwGroup;
+
+ CString str;
+
+ if(lcname.Find(_T(" off")) >= 0)
+ {
+ str = _T("Disabled");
+ }
+ else
+ {
+ if(lcid == 0)
+ {
+ str.Format(_T("Unknown %d"), id - baseid);
+ }
+ else
+ {
+ int len = GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, str.GetBuffer(64), 64);
+ str.ReleaseBufferSetLength(max(len-1, 0));
+ }
+
+ CString lcstr = CString(str).MakeLower();
+
+ if(str.IsEmpty() || lcname.Find(lcstr) >= 0) str = name;
+ else if(!name.IsEmpty()) str = CString(name) + _T(" (") + str + _T(")");
+ }
+
+ UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
+ if(dwFlags) flags |= MF_CHECKED;
+
+ str.Replace(_T("&"), _T("&&"));
+ pSub->AppendMenu(flags, id++, str);
+ }
+}
+
+void CMainFrame::OnNavStreamSelectSubMenu(UINT id, DWORD dwSelGroup)
+{
+ CComQIPtr<IAMStreamSelect> pSS = FindFilter(CLSID_OggSplitter, pGB);
+ if(!pSS) pSS = FindFilter(L"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB);
+ if(!pSS) return;
+
+ DWORD cStreams;
+ if(FAILED(pSS->Count(&cStreams)))
+ return;
+
+ for(int i = 0, j = cStreams; i < j; i++)
+ {
+ DWORD dwFlags, dwGroup;
+ LCID lcid;
+ WCHAR* pszName = NULL;
+
+ if(FAILED(pSS->Info(i, NULL, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL))
+ || !pszName)
+ continue;
+
+ if(pszName) CoTaskMemFree(pszName);
+
+ if(dwGroup != dwSelGroup)
+ continue;
+
+ if(id == 0)
+ {
+ pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE);
+ break;
+ }
+
+ id--;
+ }
+}
+
+void CMainFrame::SetupFavoritesSubMenu()
+{
+ CMenu* pSub = &m_favorites;
+
+ if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
+ else while(pSub->RemoveMenu(0, MF_BYPOSITION));
+
+ AppSettings& s = AfxGetAppSettings();
+
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ID_FAVORITES_ADD, ResStr(IDS_FAVORITES_ADD));
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ID_FAVORITES_ORGANIZE, ResStr(IDS_FAVORITES_ORGANIZE));
+
+ int nLastGroupStart = pSub->GetMenuItemCount();
+
+ UINT id = ID_FAVORITES_FILE_START;
+
+ CAtlList<CString> sl;
+ AfxGetAppSettings().GetFav(FAV_FILE, sl);
+
+ POSITION pos = sl.GetHeadPosition();
+ while(pos)
+ {
+ UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
+
+ CString str = sl.GetNext(pos);
+ str.Replace(_T("&"), _T("&&"));
+ str.Replace(_T("\t"), _T(" "));
+
+ CAtlList<CString> sl;
+ Explode(str, sl, ';', 2);
+
+ str = sl.RemoveHead();
+
+ if(!sl.IsEmpty())
+ {
+ REFERENCE_TIME rt = 0;
+ if(1 == _stscanf(sl.GetHead(), _T("%I64d"), &rt) && rt > 0)
+ {
+ DVD_HMSF_TIMECODE hmsf = RT2HMSF(rt, 0);
+ str.Format(_T("%s\t[%02d:%02d:%02d]"), CString(str), hmsf.bHours, hmsf.bMinutes, hmsf.bSeconds);
+ }
+ }
+
+ if(!str.IsEmpty())
+ pSub->AppendMenu(flags, id, str);
+
+ id++;
+ }
+
+ if(id > ID_FAVORITES_FILE_START)
+ pSub->InsertMenu(nLastGroupStart, MF_SEPARATOR|MF_ENABLED|MF_BYPOSITION);
+
+ nLastGroupStart = pSub->GetMenuItemCount();
+
+ id = ID_FAVORITES_DVD_START;
+
+ AfxGetAppSettings().GetFav(FAV_DVD, sl);
+
+ pos = sl.GetHeadPosition();
+ while(pos)
+ {
+ UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
+
+ CString str = sl.GetNext(pos);
+ str.Replace(_T("&"), _T("&&"));
+
+ CAtlList<CString> sl;
+ Explode(str, sl, ';', 2);
+
+ str = sl.RemoveHead();
+
+ if(!sl.IsEmpty())
+ {
+ // TODO
+ }
+
+ if(!str.IsEmpty())
+ pSub->AppendMenu(flags, id, str);
+
+ id++;
+ }
+
+ if(id > ID_FAVORITES_DVD_START)
+ pSub->InsertMenu(nLastGroupStart, MF_SEPARATOR|MF_ENABLED|MF_BYPOSITION);
+
+ nLastGroupStart = pSub->GetMenuItemCount();
+
+ id = ID_FAVORITES_DEVICE_START;
+
+ AfxGetAppSettings().GetFav(FAV_DEVICE, sl);
+
+ pos = sl.GetHeadPosition();
+ while(pos)
+ {
+ UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
+
+ CString str = sl.GetNext(pos);
+ str.Replace(_T("&"), _T("&&"));
+
+ CAtlList<CString> sl;
+ Explode(str, sl, ';', 2);
+
+ str = sl.RemoveHead();
+
+ if(!str.IsEmpty())
+ pSub->AppendMenu(flags, id, str);
+
+ id++;
+ }
+}
+
+void CMainFrame::SetupShadersSubMenu()
+{
+ CMenu* pSub = &m_shaders;
+
+ if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
+ else while(pSub->RemoveMenu(0, MF_BYPOSITION));
+
+ CWinApp* pApp = AfxGetApp();
+
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ID_SHADERS_START, ResStr(IDS_SHADER_OFF));
+
+ UINT id = ID_SHADERS_START+1;
+
+ if(POSITION pos = AfxGetAppSettings().m_shaders.GetHeadPosition())
+ {
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, ResStr(IDS_SHADER_COMBINE));
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, ResStr(IDS_SHADER_EDIT));
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ID_SHADER_TOGGLE, ResStr(IDS_SHADER_TOGGLE));
+ pSub->AppendMenu(MF_SEPARATOR);
+
+ MENUITEMINFO mii;
+ memset(&mii, 0, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask |= MIIM_DATA;
+
+ while(pos)
+ {
+ const AppSettings::Shader& s = AfxGetAppSettings().m_shaders.GetNext(pos);
+ CString label = s.label;
+ label.Replace(_T("&"), _T("&&"));
+ pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id, label);
+ mii.dwItemData = (ULONG_PTR)&s;
+ pSub->SetMenuItemInfo(id, &mii);
+ id++;
+ }
+ }
+}
+
+/////////////
+
+void CMainFrame::ShowControls(int nCS, bool fSave)
+{
+ int nCSprev = AfxGetAppSettings().nCS;
+ int hbefore = 0, hafter = 0;
+
+ m_pLastBar = NULL;
+
+ POSITION pos = m_bars.GetHeadPosition();
+ for(int i = 1; pos; i <<= 1)
+ {
+ CControlBar* pNext = m_bars.GetNext(pos);
+ ShowControlBar(pNext, !!(nCS&i), TRUE);
+ if(nCS&i) m_pLastBar = pNext;
+
+ CSize s = pNext->CalcFixedLayout(FALSE, TRUE);
+ if(nCSprev&i) hbefore += s.cy;
+ if(nCS&i) hafter += s.cy;
+ }
+
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(wp);
+ GetWindowPlacement(&wp);
+
+ if(wp.showCmd != SW_SHOWMAXIMIZED && !m_fFullScreen)
+ {
+ CRect r;
+ GetWindowRect(r);
+ MoveWindow(r.left, r.top, r.Width(), r.Height()+(hafter-hbefore));
+ }
+
+ if(fSave)
+ AfxGetAppSettings().nCS = nCS;
+
+ RecalcLayout();
+}
+
+void CMainFrame::SetAlwaysOnTop(int i)
+{
+ AfxGetAppSettings().iOnTop = i;
+
+ if(!m_fFullScreen)
+ {
+ const CWnd* pInsertAfter = NULL;
+
+ if(i == 0)
+ pInsertAfter = &wndNoTopMost;
+ else if(i == 1)
+ pInsertAfter = &wndTopMost;
+ else // if(i == 2)
+ pInsertAfter = GetMediaState() == State_Running ? &wndTopMost : &wndNoTopMost;
+
+ SetWindowPos(pInsertAfter, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
+ }
+ else if(!(GetWindowLong(m_hWnd, GWL_EXSTYLE)&WS_EX_TOPMOST))
+ {
+ if (!AfxGetAppSettings().fD3DFullscreen)
+ SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
+ }
+}
+
+void CMainFrame::AddTextPassThruFilter()
+{
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ if(!IsSplitter(pBF)) continue;
+
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ CComPtr<IPin> pPinTo;
+ AM_MEDIA_TYPE mt;
+ if(FAILED(pPin->ConnectedTo(&pPinTo)) || !pPinTo
+ || FAILED(pPin->ConnectionMediaType(&mt))
+ || mt.majortype != MEDIATYPE_Text && mt.majortype != MEDIATYPE_Subtitle)
+ continue;
+
+ CComQIPtr<IBaseFilter> pTPTF = new CTextPassThruFilter(this);
+ CStringW name;
+ name.Format(L"TextPassThru%08x", pTPTF);
+ if(FAILED(pGB->AddFilter(pTPTF, name)))
+ continue;
+
+ HRESULT hr;
+
+ hr = pPinTo->Disconnect();
+ hr = pPin->Disconnect();
+
+ if(FAILED(hr = pGB->ConnectDirect(pPin, GetFirstPin(pTPTF, PINDIR_INPUT), NULL))
+ || FAILED(hr = pGB->ConnectDirect(GetFirstPin(pTPTF, PINDIR_OUTPUT), pPinTo, NULL)))
+ hr = pGB->ConnectDirect(pPin, pPinTo, NULL);
+ else
+ m_pSubStreams.AddTail(CComQIPtr<ISubStream>(pTPTF));
+ }
+ EndEnumPins
+ }
+ EndEnumFilters
+}
+
+bool CMainFrame::LoadSubtitle(CString fn)
+{
+ CComPtr<ISubStream> pSubStream;
+
+ // TMP: maybe this will catch something for those who get a runtime error dialog when opening subtitles from cds
+ try
+ {
+ if(!pSubStream)
+ {
+ CAutoPtr<CVobSubFile> pVSF(new CVobSubFile(&m_csSubLock));
+ if(CString(CPath(fn).GetExtension()).MakeLower() == _T(".idx") && pVSF && pVSF->Open(fn) && pVSF->GetStreamCount() > 0)
+ pSubStream = pVSF.Detach();
+ }
+
+ if(!pSubStream)
+ {
+ CAutoPtr<CRenderedTextSubtitle> pRTS(new CRenderedTextSubtitle(&m_csSubLock));
+ if(pRTS && pRTS->Open(fn, DEFAULT_CHARSET) && pRTS->GetStreamCount() > 0)
+ pSubStream = pRTS.Detach();
+ }
+ }
+ catch(CException* e)
+ {
+ e->Delete();
+ }
+
+ if(pSubStream)
+ {
+ m_pSubStreams.AddTail(pSubStream);
+ }
+
+ return(!!pSubStream);
+}
+
+void CMainFrame::UpdateSubtitle(bool fApplyDefStyle)
+{
+ if(!m_pCAP) return;
+
+ int i = m_iSubtitleSel;
+
+ POSITION pos = m_pSubStreams.GetHeadPosition();
+ while(pos && i >= 0)
+ {
+ CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
+
+ if(i < pSubStream->GetStreamCount())
+ {
+ CAutoLock cAutoLock(&m_csSubLock);
+ pSubStream->SetStream(i);
+ SetSubtitle(pSubStream, fApplyDefStyle);
+ return;
+ }
+
+ i -= pSubStream->GetStreamCount();
+ }
+
+ m_pCAP->SetSubPicProvider(NULL);
+}
+
+void CMainFrame::SetSubtitle(ISubStream* pSubStream, bool fApplyDefStyle)
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ if(pSubStream)
+ {
+ CLSID clsid;
+ pSubStream->GetClassID(&clsid);
+
+ if(clsid == __uuidof(CVobSubFile))
+ {
+ CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)pSubStream;
+
+ if(fApplyDefStyle)
+ {
+ pVSF->SetAlignment(s.fOverridePlacement, s.nHorPos, s.nVerPos, 1, 1);
+ }
+ }
+ else if(clsid == __uuidof(CVobSubStream))
+ {
+ CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)pSubStream;
+
+ if(fApplyDefStyle)
+ {
+ pVSS->SetAlignment(s.fOverridePlacement, s.nHorPos, s.nVerPos, 1, 1);
+ }
+ }
+ else if(clsid == __uuidof(CRenderedTextSubtitle))
+ {
+ CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)pSubStream;
+
+ STSStyle style;
+
+ if(fApplyDefStyle || pRTS->m_fUsingAutoGeneratedDefaultStyle)
+ {
+ style = s.subdefstyle;
+
+ if(s.fOverridePlacement)
+ {
+ style.scrAlignment = 2;
+ int w = pRTS->m_dstScreenSize.cx;
+ int h = pRTS->m_dstScreenSize.cy;
+ int mw = w - style.marginRect.left - style.marginRect.right;
+ style.marginRect.bottom = h - MulDiv(h, s.nVerPos, 100);
+ style.marginRect.left = MulDiv(w, s.nHorPos, 100) - mw/2;
+ style.marginRect.right = w - (style.marginRect.left + mw);
+ }
+
+ pRTS->SetDefaultStyle(style);
+ }
+
+ if(pRTS->GetDefaultStyle(style) && style.relativeTo == 2)
+ {
+ style.relativeTo = s.subdefstyle.relativeTo;
+ pRTS->SetDefaultStyle(style);
+ }
+
+ pRTS->Deinit();
+ }
+ }
+
+ if(!fApplyDefStyle)
+ {
+ m_iSubtitleSel = -1;
+
+ if(pSubStream)
+ {
+
+ int i = 0;
+
+ POSITION pos = m_pSubStreams.GetHeadPosition();
+ while(pos)
+ {
+ CComPtr<ISubStream> pSubStream2 = m_pSubStreams.GetNext(pos);
+
+ if(pSubStream == pSubStream2)
+ {
+ m_iSubtitleSel = i + pSubStream2->GetStream();
+ break;
+ }
+
+ i += pSubStream2->GetStreamCount();
+ }
+
+ }
+ }
+
+ m_nSubtitleId = (DWORD_PTR)pSubStream;
+
+ if(m_pCAP)
+ {
+ m_pCAP->SetSubPicProvider(CComQIPtr<ISubPicProvider>(pSubStream));
+ m_wndSubresyncBar.SetSubtitle(pSubStream, m_pCAP->GetFPS());
+ }
+}
+
+void CMainFrame::ReplaceSubtitle(ISubStream* pSubStreamOld, ISubStream* pSubStreamNew)
+{
+ POSITION pos = m_pSubStreams.GetHeadPosition();
+ while(pos)
+ {
+ POSITION cur = pos;
+ if(pSubStreamOld == m_pSubStreams.GetNext(pos))
+ {
+ m_pSubStreams.SetAt(cur, pSubStreamNew);
+ UpdateSubtitle();
+ break;
+ }
+ }
+}
+
+void CMainFrame::InvalidateSubtitle(DWORD_PTR nSubtitleId, REFERENCE_TIME rtInvalidate)
+{
+ if(m_pCAP)
+ {
+ if(nSubtitleId == -1 || nSubtitleId == m_nSubtitleId)
+ m_pCAP->Invalidate(rtInvalidate);
+ }
+}
+
+void CMainFrame::ReloadSubtitle()
+{
+ POSITION pos = m_pSubStreams.GetHeadPosition();
+ while(pos) m_pSubStreams.GetNext(pos)->Reload();
+ UpdateSubtitle();
+}
+
+REFERENCE_TIME CMainFrame::GetPos()
+{
+ return(m_iMediaLoadState == MLS_LOADED ? m_wndSeekBar.GetPos() : 0);
+}
+
+REFERENCE_TIME CMainFrame::GetDur()
+{
+ __int64 start, stop;
+ m_wndSeekBar.GetRange(start, stop);
+ return(m_iMediaLoadState == MLS_LOADED ? stop : 0);
+}
+
+void CMainFrame::SeekTo(REFERENCE_TIME rtPos, bool fSeekToKeyFrame)
+{
+ OAFilterState fs = GetMediaState();
+
+ if(rtPos < 0) rtPos = 0;
+
+ if(m_iPlaybackMode == PM_FILE)
+ {
+ if(fs == State_Stopped)
+ SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
+
+ HRESULT hr;
+
+ if(fSeekToKeyFrame)
+ {
+ if(!m_kfs.IsEmpty())
+ {
+ int i = rangebsearch(rtPos, m_kfs);
+ if(i >= 0 && i < m_kfs.GetCount())
+ rtPos = m_kfs[i];
+ }
+ }
+
+ hr = pMS->SetPositions(&rtPos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
+ }
+ else if(m_iPlaybackMode == PM_DVD && m_iDVDDomain == DVD_DOMAIN_Title)
+ {
+ if(fs != State_Running)
+ SendMessage(WM_COMMAND, ID_PLAY_PLAY);
+
+ DVD_HMSF_TIMECODE tc = RT2HMSF(rtPos);
+ pDVDC->PlayAtTime(&tc, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
+
+// if(fs != State_Running)
+// SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
+ }
+ else if(m_iPlaybackMode == PM_CAPTURE)
+ {
+ TRACE(_T("Warning (CMainFrame::SeekTo): Trying to seek in capture mode"));
+ }
+ m_fEndOfStream = false;
+}
+
+void CMainFrame::CleanGraph()
+{
+ if(!pGB) return;
+
+ BeginEnumFilters(pGB, pEF, pBF)
+ {
+ CComQIPtr<IAMFilterMiscFlags> pAMMF(pBF);
+ if(pAMMF && (pAMMF->GetMiscFlags()&AM_FILTER_MISC_FLAGS_IS_SOURCE))
+ continue;
+
+ // some capture filters forget to set AM_FILTER_MISC_FLAGS_IS_SOURCE
+ // or to implement the IAMFilterMiscFlags interface
+ if(pBF == pVidCap || pBF == pAudCap)
+ continue;
+
+ if(CComQIPtr<IFileSourceFilter>(pBF))
+ continue;
+
+ int nIn, nOut, nInC, nOutC;
+ if(CountPins(pBF, nIn, nOut, nInC, nOutC) > 0 && (nInC+nOutC) == 0)
+ {
+ TRACE(CStringW(L"Removing: ") + GetFilterName(pBF) + '\n');
+
+ pGB->RemoveFilter(pBF);
+ pEF->Reset();
+ }
+ }
+ EndEnumFilters
+}
+
+#define AUDIOBUFFERLEN 500
+
+static void SetLatency(IBaseFilter* pBF, int cbBuffer)
+{
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ if(CComQIPtr<IAMBufferNegotiation> pAMBN = pPin)
+ {
+ ALLOCATOR_PROPERTIES ap;
+ ap.cbAlign = -1; // -1 means no preference.
+ ap.cbBuffer = cbBuffer;
+ ap.cbPrefix = -1;
+ ap.cBuffers = -1;
+ pAMBN->SuggestAllocatorProperties(&ap);
+ }
+ }
+ EndEnumPins
+}
+
+HRESULT CMainFrame::BuildCapture(IPin* pPin, IBaseFilter* pBF[3], const GUID& majortype, AM_MEDIA_TYPE* pmt)
+{
+ IBaseFilter* pBuff = pBF[0];
+ IBaseFilter* pEnc = pBF[1];
+ IBaseFilter* pMux = pBF[2];
+
+ if(!pPin || !pMux) return E_FAIL;
+
+ CString err;
+
+ HRESULT hr = S_OK;
+
+ CFilterInfo fi;
+ if(FAILED(pMux->QueryFilterInfo(&fi)) || !fi.pGraph)
+ pGB->AddFilter(pMux, L"Multiplexer");
+
+ CStringW prefix, prefixl;
+ if(majortype == MEDIATYPE_Video) prefix = L"Video ";
+ else if(majortype == MEDIATYPE_Audio) prefix = L"Audio ";
+ prefixl = prefix;
+ prefixl.MakeLower();
+
+ if(pBuff)
+ {
+ hr = pGB->AddFilter(pBuff, prefix + L"Buffer");
+ if(FAILED(hr))
+ {
+ err = _T("Can't add ") + CString(prefixl) + _T("buffer filter");
+ AfxMessageBox(err);
+ return hr;
+ }
+
+ hr = pGB->ConnectFilter(pPin, pBuff);
+ if(FAILED(hr))
+ {
+ err = _T("Error connecting the ") + CString(prefixl) + _T("buffer filter");
+ AfxMessageBox(err);
+ return(hr);
+ }
+
+ pPin = GetFirstPin(pBuff, PINDIR_OUTPUT);
+ }
+
+ if(pEnc)
+ {
+ hr = pGB->AddFilter(pEnc, prefix + L"Encoder");
+ if(FAILED(hr))
+ {
+ err = _T("Can't add ") + CString(prefixl) + _T("encoder filter");
+ AfxMessageBox(err);
+ return hr;
+ }
+
+ hr = pGB->ConnectFilter(pPin, pEnc);
+ if(FAILED(hr))
+ {
+ err = _T("Error connecting the ") + CString(prefixl) + _T("encoder filter");
+ AfxMessageBox(err);
+ return(hr);
+ }
+
+ pPin = GetFirstPin(pEnc, PINDIR_OUTPUT);
+
+ if(CComQIPtr<IAMStreamConfig> pAMSC = pPin)
+ {
+ if(pmt->majortype == majortype)
+ {
+ hr = pAMSC->SetFormat(pmt);
+ if(FAILED(hr))
+ {
+ err = _T("Can't set compression format on the ") + CString(prefixl) + _T("encoder filter");
+ AfxMessageBox(err);
+ return(hr);
+ }
+ }
+ }
+
+ }
+
+// if(pMux)
+ {
+ hr = pGB->ConnectFilter(pPin, pMux);
+ if(FAILED(hr))
+ {
+ err = _T("Error connecting ") + CString(prefixl) + _T(" to the muliplexer filter");
+ AfxMessageBox(err);
+ return(hr);
+ }
+ }
+
+ CleanGraph();
+
+ return S_OK;
+}
+
+bool CMainFrame::BuildToCapturePreviewPin(
+ IBaseFilter* pVidCap, IPin** ppVidCapPin, IPin** ppVidPrevPin,
+ IBaseFilter* pAudCap, IPin** ppAudCapPin, IPin** ppAudPrevPin)
+{
+ HRESULT hr;
+
+ *ppVidCapPin = *ppVidPrevPin = NULL;
+ *ppAudCapPin = *ppAudPrevPin = NULL;
+
+ CComPtr<IPin> pDVAudPin;
+
+ if(pVidCap)
+ {
+ CComPtr<IPin> pPin;
+ if(!pAudCap // only look for interleaved stream when we don't use any other audio capture source
+ && SUCCEEDED(pCGB->FindPin(pVidCap, PINDIR_OUTPUT, &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, TRUE, 0, &pPin)))
+ {
+ CComPtr<IBaseFilter> pDVSplitter;
+ hr = pDVSplitter.CoCreateInstance(CLSID_DVSplitter);
+ hr = pGB->AddFilter(pDVSplitter, L"DV Splitter");
+
+ hr = pCGB->RenderStream(NULL, &MEDIATYPE_Interleaved, pPin, NULL, pDVSplitter);
+
+ pPin = NULL;
+ hr = pCGB->FindPin(pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pPin);
+ hr = pCGB->FindPin(pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Audio, TRUE, 0, &pDVAudPin);
+
+ CComPtr<IBaseFilter> pDVDec;
+ hr = pDVDec.CoCreateInstance(CLSID_DVVideoCodec);
+ hr = pGB->AddFilter(pDVDec, L"DV Video Decoder");
+
+ hr = pGB->ConnectFilter(pPin, pDVDec);
+
+ pPin = NULL;
+ hr = pCGB->FindPin(pDVDec, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pPin);
+ }
+ else if(SUCCEEDED(pCGB->FindPin(pVidCap, PINDIR_OUTPUT, &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, TRUE, 0, &pPin)))
+ {
+ }
+ else
+ {
+ AfxMessageBox(_T("No video capture pin was found"));
+ return(false);
+ }
+
+ CComPtr<IBaseFilter> pSmartTee;
+ hr = pSmartTee.CoCreateInstance(CLSID_SmartTee);
+ hr = pGB->AddFilter(pSmartTee, L"Smart Tee (video)");
+
+ hr = pGB->ConnectFilter(pPin, pSmartTee);
+
+ hr = pSmartTee->FindPin(L"Preview", ppVidPrevPin);
+ hr = pSmartTee->FindPin(L"Capture", ppVidCapPin);
+ }
+
+ if(pAudCap || pDVAudPin)
+ {
+ CComPtr<IPin> pPin;
+ if(pDVAudPin)
+ {
+ pPin = pDVAudPin;
+ }
+ else if(SUCCEEDED(pCGB->FindPin(pAudCap, PINDIR_OUTPUT, &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, TRUE, 0, &pPin)))
+ {
+ }
+ else
+ {
+ AfxMessageBox(_T("No audio capture pin was found"));
+ return(false);
+ }
+
+ CComPtr<IBaseFilter> pSmartTee;
+ hr = pSmartTee.CoCreateInstance(CLSID_SmartTee);
+ hr = pGB->AddFilter(pSmartTee, L"Smart Tee (audio)");
+
+ hr = pGB->ConnectFilter(pPin, pSmartTee);
+
+ hr = pSmartTee->FindPin(L"Preview", ppAudPrevPin);
+ hr = pSmartTee->FindPin(L"Capture", ppAudCapPin);
+ }
+
+ return(true);
+}
+
+bool CMainFrame::BuildGraphVideoAudio(int fVPreview, bool fVCapture, int fAPreview, bool fACapture)
+{
+ if(!pCGB) return(false);
+
+ SaveMediaState;
+
+ HRESULT hr;
+
+ pGB->NukeDownstream(pVidCap);
+ pGB->NukeDownstream(pAudCap);
+
+ CleanGraph();
+
+ if(pAMVSCCap) hr = pAMVSCCap->SetFormat(&m_wndCaptureBar.m_capdlg.m_mtv);
+ if(pAMVSCPrev) hr = pAMVSCPrev->SetFormat(&m_wndCaptureBar.m_capdlg.m_mtv);
+ if(pAMASC) hr = pAMASC->SetFormat(&m_wndCaptureBar.m_capdlg.m_mta);
+
+ CComPtr<IBaseFilter> pVidBuffer = m_wndCaptureBar.m_capdlg.m_pVidBuffer;
+ CComPtr<IBaseFilter> pAudBuffer = m_wndCaptureBar.m_capdlg.m_pAudBuffer;
+ CComPtr<IBaseFilter> pVidEnc = m_wndCaptureBar.m_capdlg.m_pVidEnc;
+ CComPtr<IBaseFilter> pAudEnc = m_wndCaptureBar.m_capdlg.m_pAudEnc;
+ CComPtr<IBaseFilter> pMux = m_wndCaptureBar.m_capdlg.m_pMux;
+ CComPtr<IBaseFilter> pDst = m_wndCaptureBar.m_capdlg.m_pDst;
+ CComPtr<IBaseFilter> pAudMux = m_wndCaptureBar.m_capdlg.m_pAudMux;
+ CComPtr<IBaseFilter> pAudDst = m_wndCaptureBar.m_capdlg.m_pAudDst;
+
+ bool fFileOutput = (pMux && pDst) || (pAudMux && pAudDst);
+ bool fCapture = (fVCapture || fACapture);
+
+ if(pAudCap)
+ {
+ AM_MEDIA_TYPE* pmt = &m_wndCaptureBar.m_capdlg.m_mta;
+ int ms = (fACapture && fFileOutput && m_wndCaptureBar.m_capdlg.m_fAudOutput) ? AUDIOBUFFERLEN : 60;
+ if(pMux != pAudMux && fACapture) SetLatency(pAudCap, -1);
+ else if(pmt->pbFormat) SetLatency(pAudCap, ((WAVEFORMATEX*)pmt->pbFormat)->nAvgBytesPerSec * ms / 1000);
+ }
+
+ CComPtr<IPin> pVidCapPin, pVidPrevPin, pAudCapPin, pAudPrevPin;
+ BuildToCapturePreviewPin(pVidCap, &pVidCapPin, &pVidPrevPin, pAudCap, &pAudCapPin, &pAudPrevPin);
+
+// if(pVidCap)
+ {
+ bool fVidPrev = pVidPrevPin && fVPreview;
+ bool fVidCap = pVidCapPin && fVCapture && fFileOutput && m_wndCaptureBar.m_capdlg.m_fVidOutput;
+
+ if(fVPreview == 2 && !fVidCap && pVidCapPin)
+ {
+ pVidPrevPin = pVidCapPin;
+ pVidCapPin = NULL;
+ }
+
+ if(fVidPrev)
+ {
+ m_pCAP = NULL;
+ pGB->Render(pVidPrevPin);
+ pGB->FindInterface(__uuidof(ISubPicAllocatorPresenter), (void**)&m_pCAP, TRUE);
+ }
+
+ if(fVidCap)
+ {
+ IBaseFilter* pBF[3] = {pVidBuffer, pVidEnc, pMux};
+ HRESULT hr = BuildCapture(pVidCapPin, pBF, MEDIATYPE_Video, &m_wndCaptureBar.m_capdlg.m_mtcv);
+ }
+
+ pAMDF = NULL;
+ pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVidCap, IID_IAMDroppedFrames, (void**)&pAMDF);
+ }
+
+// if(pAudCap)
+ {
+ bool fAudPrev = pAudPrevPin && fAPreview;
+ bool fAudCap = pAudCapPin && fACapture && fFileOutput && m_wndCaptureBar.m_capdlg.m_fAudOutput;
+
+ if(fAPreview == 2 && !fAudCap && pAudCapPin)
+ {
+ pAudPrevPin = pAudCapPin;
+ pAudCapPin = NULL;
+ }
+
+ if(fAudPrev)
+ {
+ pGB->Render(pAudPrevPin);
+ }
+
+ if(fAudCap)
+ {
+ IBaseFilter* pBF[3] = {pAudBuffer, pAudEnc, pAudMux ? pAudMux : pMux};
+ HRESULT hr = BuildCapture(pAudCapPin, pBF, MEDIATYPE_Audio, &m_wndCaptureBar.m_capdlg.m_mtca);
+ }
+ }
+
+ if((pVidCap || pAudCap) && fCapture && fFileOutput)
+ {
+ if(pMux != pDst)
+ {
+ hr = pGB->AddFilter(pDst, L"File Writer V/A");
+ hr = pGB->ConnectFilter(GetFirstPin(pMux, PINDIR_OUTPUT), pDst);
+ }
+
+ if(CComQIPtr<IConfigAviMux> pCAM = pMux)
+ {
+ int nIn, nOut, nInC, nOutC;
+ CountPins(pMux, nIn, nOut, nInC, nOutC);
+ pCAM->SetMasterStream(nInC-1);
+// pCAM->SetMasterStream(-1);
+ pCAM->SetOutputCompatibilityIndex(FALSE);
+ }
+
+ if(CComQIPtr<IConfigInterleaving> pCI = pMux)
+ {
+// if(FAILED(pCI->put_Mode(INTERLEAVE_CAPTURE)))
+ if(FAILED(pCI->put_Mode(INTERLEAVE_NONE_BUFFERED)))
+ pCI->put_Mode(INTERLEAVE_NONE);
+
+ REFERENCE_TIME rtInterleave = 10000i64*AUDIOBUFFERLEN, rtPreroll = 0;//10000i64*500
+ pCI->put_Interleaving(&rtInterleave, &rtPreroll);
+ }
+
+ if(pMux != pAudMux && pAudMux != pAudDst)
+ {
+ hr = pGB->AddFilter(pAudDst, L"File Writer A");
+ hr = pGB->ConnectFilter(GetFirstPin(pAudMux, PINDIR_OUTPUT), pAudDst);
+ }
+ }
+
+ REFERENCE_TIME stop = MAX_TIME;
+ hr = pCGB->ControlStream(&PIN_CATEGORY_CAPTURE, NULL, NULL, NULL, &stop, 0, 0); // stop in the infinite
+
+ CleanGraph();
+
+ OpenSetupVideo();
+ OpenSetupAudio();
+ OpenSetupStatsBar();
+ OpenSetupStatusBar();
+
+ RestoreMediaState;
+
+ return(true);
+}
+
+bool CMainFrame::StartCapture()
+{
+ if(!pCGB || m_fCapturing) return(false);
+
+ if(!m_wndCaptureBar.m_capdlg.m_pMux && !m_wndCaptureBar.m_capdlg.m_pDst) return(false);
+
+ HRESULT hr;
+
+ ::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS);
+
+ // rare to see two capture filters to support IAMPushSource at the same time...
+// hr = CComQIPtr<IAMGraphStreams>(pGB)->SyncUsingStreamOffset(TRUE); // TODO:
+
+ BuildGraphVideoAudio(
+ m_wndCaptureBar.m_capdlg.m_fVidPreview, true,
+ m_wndCaptureBar.m_capdlg.m_fAudPreview, true);
+
+ hr = pME->CancelDefaultHandling(EC_REPAINT);
+
+ SendMessage(WM_COMMAND, ID_PLAY_PLAY);
+
+ m_fCapturing = true;
+
+ return(true);
+}
+
+bool CMainFrame::StopCapture()
+{
+ if(!pCGB || !m_fCapturing) return(false);
+
+ if(!m_wndCaptureBar.m_capdlg.m_pMux && !m_wndCaptureBar.m_capdlg.m_pDst) return(false);
+
+ HRESULT hr;
+
+ m_wndStatusBar.SetStatusMessage(ResStr(IDS_CONTROLS_COMPLETING));
+
+ m_fCapturing = false;
+
+ BuildGraphVideoAudio(
+ m_wndCaptureBar.m_capdlg.m_fVidPreview, false,
+ m_wndCaptureBar.m_capdlg.m_fAudPreview, false);
+
+ hr = pME->RestoreDefaultHandling(EC_REPAINT);
+
+ ::SetPriorityClass(::GetCurrentProcess(), AfxGetAppSettings().priority);
+
+ m_rtDurationOverride = -1;
+
+ return(true);
+}
+
+//
+
+void CMainFrame::ShowOptions(int idPage)
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ CPPageSheet options(ResStr(IDS_OPTIONS_CAPTION), pGB, this, idPage);
+
+ if(options.DoModal() == IDOK)
+ {
+ if(!m_fFullScreen)
+ SetAlwaysOnTop(s.iOnTop);
+
+ m_wndView.LoadLogo();
+
+ s.UpdateData(true);
+ }
+}
+
+void CMainFrame::StartWebServer(int nPort)
+{
+ if(!m_pWebServer)
+ m_pWebServer.Attach(new CWebServer(this, nPort));
+}
+
+void CMainFrame::StopWebServer()
+{
+ if(m_pWebServer)
+ m_pWebServer.Free();
+}
+
+CString CMainFrame::GetStatusMessage()
+{
+ CString str;
+ m_wndStatusBar.m_status.GetWindowText(str);
+ return str;
+}
+
+void CMainFrame::SendStatusMessage(CString msg, int nTimeOut)
+{
+ KillTimer(TIMER_STATUSERASER);
+
+ m_playingmsg.Empty();
+ if(nTimeOut <= 0) return;
+
+ m_playingmsg = msg;
+ SetTimer(TIMER_STATUSERASER, nTimeOut, NULL);
+}
+
+void CMainFrame::OpenCurPlaylistItem(REFERENCE_TIME rtStart)
+{
+ if(m_wndPlaylistBar.GetCount() == 0)
+ return;
+
+ CPlaylistItem pli;
+ if(!m_wndPlaylistBar.GetCur(pli)) m_wndPlaylistBar.SetFirst();
+ if(!m_wndPlaylistBar.GetCur(pli)) return;
+
+ CAutoPtr<OpenMediaData> p(m_wndPlaylistBar.GetCurOMD(rtStart));
+ if(p) OpenMedia(p);
+}
+
+void CMainFrame::AddCurDevToPlaylist()
+{
+ if(m_iPlaybackMode == PM_CAPTURE)
+ {
+ m_wndPlaylistBar.Append(
+ m_VidDispName,
+ m_AudDispName,
+ m_wndCaptureBar.m_capdlg.GetVideoInput(),
+ m_wndCaptureBar.m_capdlg.GetVideoChannel(),
+ m_wndCaptureBar.m_capdlg.GetAudioInput()
+ );
+ }
+}
+
+static int s_fOpenedThruThread = false;
+
+void CMainFrame::OpenMedia(CAutoPtr<OpenMediaData> pOMD)
+{
+ // shortcut
+ if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
+ {
+ if(m_iMediaLoadState == MLS_LOADED && pAMTuner
+ && m_VidDispName == p->DisplayName[0] && m_AudDispName == p->DisplayName[1])
+ {
+ m_wndCaptureBar.m_capdlg.SetVideoInput(p->vinput);
+ m_wndCaptureBar.m_capdlg.SetVideoChannel(p->vchannel);
+ m_wndCaptureBar.m_capdlg.SetAudioInput(p->ainput);
+ SendNowPlayingToMSN();
+ SendNowPlayingTomIRC();
+ return;
+ }
+ }
+
+ if(m_iMediaLoadState != MLS_CLOSED)
+ CloseMedia();
+
+// m_iMediaLoadState = MLS_LOADING; // HACK: hides the logo
+
+ AppSettings& s = AfxGetAppSettings();
+
+ bool fUseThread = true;
+
+ if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p))
+ {
+ if(p->fns.GetCount() > 0)
+ {
+ engine_t e = s.Formats.GetEngine(p->fns.GetHead());
+ fUseThread = e == DirectShow /*|| e == RealMedia || e == QuickTime*/;
+ }
+ }
+ else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
+ {
+ fUseThread = false;
+ }
+
+ if(m_pGraphThread && fUseThread
+ && AfxGetAppSettings().fEnableWorkerThreadForOpening)
+ {
+ m_pGraphThread->PostThreadMessage(CGraphThread::TM_OPEN, 0, (LPARAM)pOMD.Detach());
+ s_fOpenedThruThread = true;
+ }
+ else
+ {
+ OpenMediaPrivate(pOMD);
+ s_fOpenedThruThread = false;
+ }
+}
+
+void CMainFrame::CloseMedia()
+{
+ if(m_iMediaLoadState == MLS_CLOSING)
+ {
+ TRACE(_T("WARNING: CMainFrame::CloseMedia() called twice or more\n"));
+ return;
+ }
+
+ int nTimeWaited = 0;
+
+ while(m_iMediaLoadState == MLS_LOADING)
+ {
+ m_fOpeningAborted = true;
+
+ if(pGB) pGB->Abort(); // TODO: lock on graph objects somehow, this is not thread safe
+
+ if(nTimeWaited > 5*1000 && m_pGraphThread)
+ {
+ MessageBeep(MB_ICONEXCLAMATION);
+ TRACE(_T("CRITICAL ERROR: !!! Must kill opener thread !!!"));
+ TerminateThread(m_pGraphThread->m_hThread, -1);
+ m_pGraphThread = (CGraphThread*)AfxBeginThread(RUNTIME_CLASS(CGraphThread));
+ s_fOpenedThruThread = false;
+ break;
+ }
+
+ Sleep(50);
+
+ nTimeWaited += 50;
+ }
+
+ m_fOpeningAborted = false;
+
+ m_closingmsg.Empty();
+
+ m_iMediaLoadState = MLS_CLOSING;
+
+ OnFilePostClosemedia();
+
+ if(m_pGraphThread && s_fOpenedThruThread)
+ {
+ CAMEvent e;
+ m_pGraphThread->PostThreadMessage(CGraphThread::TM_CLOSE, 0, (LPARAM)&e);
+ e.Wait(); // either opening or closing has to be blocked to prevent reentering them, closing is the better choice
+ }
+ else
+ {
+ CloseMediaPrivate();
+ }
+
+ UnloadExternalObjects();
+ if (m_bD3DFullscreenMode)
+ {
+ if (m_pFullscreenWnd->m_hWnd) m_pFullscreenWnd->ShowWindow (SW_HIDE);
+ m_bD3DFullscreenMode = false;
+ }
+}
+
+//
+// CGraphThread
+//
+
+IMPLEMENT_DYNCREATE(CGraphThread, CWinThread)
+
+BOOL CGraphThread::InitInstance()
+{
+ AfxSocketInit();
+ return SUCCEEDED(CoInitialize(0)) ? TRUE : FALSE;
+}
+
+int CGraphThread::ExitInstance()
+{
+ CoUninitialize();
+ return __super::ExitInstance();
+}
+
+BEGIN_MESSAGE_MAP(CGraphThread, CWinThread)
+ ON_THREAD_MESSAGE(TM_EXIT, OnExit)
+ ON_THREAD_MESSAGE(TM_OPEN, OnOpen)
+ ON_THREAD_MESSAGE(TM_CLOSE, OnClose)
+END_MESSAGE_MAP()
+
+void CGraphThread::OnExit(WPARAM wParam, LPARAM lParam)
+{
+ PostQuitMessage(0);
+ if(CAMEvent* e = (CAMEvent*)lParam) e->Set();
+}
+
+void CGraphThread::OnOpen(WPARAM wParam, LPARAM lParam)
+{
+ if(m_pMainFrame)
+ {
+ CAutoPtr<OpenMediaData> pOMD((OpenMediaData*)lParam);
+ m_pMainFrame->OpenMediaPrivate(pOMD);
+ }
+}
+
+void CGraphThread::OnClose(WPARAM wParam, LPARAM lParam)
+{
+ if(m_pMainFrame) m_pMainFrame->CloseMediaPrivate();
+ if(CAMEvent* e = (CAMEvent*)lParam) e->Set();
+}
+
+
+
+
+// ==== Added by CASIMIR666
+bool CMainFrame::CreateFullScreenWindow()
+{
+ HMONITOR hMonitor;
+ MONITORINFOEX MonitorInfo;
+ CRect MonitorRect;
+
+ if (m_pFullscreenWnd->m_hWnd) m_pFullscreenWnd->DestroyWindow();
+
+ ZeroMemory (&MonitorInfo, sizeof(MonitorInfo));
+ MonitorInfo.cbSize = sizeof(MonitorInfo);
+ hMonitor = MonitorFromWindow (m_hWnd, 0);
+ if (GetMonitorInfo (hMonitor, &MonitorInfo))
+ {
+ MonitorRect = CRect (MonitorInfo.rcMonitor);
+ // Creation de la fenetre
+ DWORD dwStyle = WS_POPUP | WS_VISIBLE ;
+ m_fullWndSize.cx = MonitorRect.Width();
+ m_fullWndSize.cy = MonitorRect.Height();
+
+ m_pFullscreenWnd->CreateEx (WS_EX_TOPMOST | WS_EX_TOOLWINDOW, _T(""), _T("MPC D3D FullScreen"), dwStyle, MonitorRect.left, MonitorRect.top, MonitorRect.Width(), MonitorRect.Height(), NULL, NULL, NULL);
+ }
+
+ return (m_pFullscreenWnd->m_hWnd)? true : false;
+}
+
+
+bool CMainFrame::IsD3DFullScreenMode()
+{
+ return (m_bD3DFullscreenMode);
+// return (AfxGetAppSettings().fD3DFullscreen && ((m_iMediaLoadState == MLS_LOADED) || (m_iMediaLoadState == MLS_LOADING)));
+};
+
+
+
+void CMainFrame::SetVMR9ColorControl(float dBrightness, float dContrast, float dHue, float dSaturation)
+{
+ VMR9ProcAmpControl ClrControl;
+
+ if(m_pMC)
+ {
+ ClrControl.dwSize = sizeof(ClrControl);
+ ClrControl.dwFlags = ProcAmpControl9_Mask;
+ ClrControl.Brightness = dBrightness;
+ ClrControl.Contrast = dContrast;
+ ClrControl.Hue = dHue;
+ ClrControl.Saturation = dSaturation;
+
+ m_pMC->SetProcAmpControl (0, &ClrControl);
+ }
+}
+
+LPCTSTR CMainFrame::GetDVDAudioFormatName (DVD_AudioAttributes& ATR)
+{
+ switch(ATR.AudioFormat)
+ {
+ case DVD_AudioFormat_AC3:
+ return _T("AC3");
+ case DVD_AudioFormat_MPEG1:
+ case DVD_AudioFormat_MPEG1_DRC:
+ return _T("MPEG1");
+ case DVD_AudioFormat_MPEG2:
+ case DVD_AudioFormat_MPEG2_DRC:
+ return _T("MPEG2");
+ case DVD_AudioFormat_LPCM:
+ return _T("LPCM");
+ case DVD_AudioFormat_DTS:
+ return _T("DTS");
+ case DVD_AudioFormat_SDDS:
+ return _T("SDDS");
+ case DVD_AudioFormat_Other:
+ default:
+ return _T("Unknown format");
+ }
+}
diff --git a/src/apps/mplayerc/MainFrm.h b/src/apps/mplayerc/MainFrm.h
new file mode 100644
index 000000000..aeabf3c46
--- /dev/null
+++ b/src/apps/mplayerc/MainFrm.h
@@ -0,0 +1,693 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <atlbase.h>
+
+#include "ChildView.h"
+#include "PlayerSeekBar.h"
+#include "PlayerToolBar.h"
+#include "PlayerInfoBar.h"
+#include "PlayerStatusBar.h"
+#include "PlayerSubresyncBar.h"
+#include "PlayerPlaylistBar.h"
+#include "PlayerCaptureBar.h"
+#include "PlayerShaderEditorBar.h"
+#include "PPageSheet.h"
+#include "PPageFileInfoSheet.h"
+#include "OpenCapDeviceDlg.h"
+
+#include "FileDropTarget.h"
+
+#include "KeyProvider.h"
+
+#include "..\..\subpic\ISubPic.h"
+
+#include "IGraphBuilder2.h"
+
+#include "RealMediaGraph.h"
+#include "QuicktimeGraph.h"
+#include "ShockwaveGraph.h"
+
+#include "..\..\..\include\IChapterInfo.h"
+#include "..\..\..\include\IKeyFrameInfo.h"
+#include "..\..\..\include\IBufferInfo.h"
+
+#include "WebServer.h"
+#include <D3d9.h>
+#include <Vmr9.h>
+#include "VMROSD.h"
+
+class CFullscreenWnd;
+
+enum {PM_NONE, PM_FILE, PM_DVD, PM_CAPTURE};
+
+class OpenMediaData
+{
+public:
+// OpenMediaData() {}
+ virtual ~OpenMediaData() {} // one virtual funct is needed to enable rtti
+ CString title;
+ CAtlList<CString> subs;
+};
+
+class OpenFileData : public OpenMediaData
+{
+public:
+ OpenFileData() : rtStart(0) {}
+ CAtlList<CString> fns;
+ REFERENCE_TIME rtStart;
+};
+
+class OpenDVDData : public OpenMediaData
+{
+public:
+// OpenDVDData() {}
+ CString path;
+ CComPtr<IDvdState> pDvdState;
+};
+
+class OpenDeviceData : public OpenMediaData
+{
+public:
+ OpenDeviceData() {vinput = vchannel = ainput = -1;}
+ CStringW DisplayName[2];
+ int vinput, vchannel, ainput;
+};
+
+class CMainFrame;
+
+class CGraphThread : public CWinThread
+{
+ CMainFrame* m_pMainFrame;
+
+ DECLARE_DYNCREATE(CGraphThread);
+
+public:
+ CGraphThread() : m_pMainFrame(NULL) {}
+
+ void SetMainFrame(CMainFrame* pMainFrame) {m_pMainFrame = pMainFrame;}
+
+ BOOL InitInstance();
+ int ExitInstance();
+
+ enum {TM_EXIT=WM_APP, TM_OPEN, TM_CLOSE};
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnExit(WPARAM wParam, LPARAM lParam);
+ afx_msg void OnOpen(WPARAM wParam, LPARAM lParam);
+ afx_msg void OnClose(WPARAM wParam, LPARAM lParam);
+};
+/*
+class CKeyFrameFinderThread : public CWinThread, public CCritSec
+{
+ DECLARE_DYNCREATE(CKeyFrameFinderThread);
+
+public:
+ CKeyFrameFinderThread() {}
+
+ CUIntArray m_kfs; // protected by (CCritSec*)this
+
+ BOOL InitInstance();
+ int ExitInstance();
+
+ enum {TM_EXIT=WM_APP, TM_INDEX, TM_BREAK};
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnExit(WPARAM wParam, LPARAM lParam);
+ afx_msg void OnIndex(WPARAM wParam, LPARAM lParam);
+ afx_msg void OnBreak(WPARAM wParam, LPARAM lParam);
+};
+*/
+interface ISubClock;
+
+class CMainFrame : public CFrameWnd, public CDropTarget
+{
+ enum
+ {
+ TIMER_STREAMPOSPOLLER = 1,
+ TIMER_STREAMPOSPOLLER2,
+ TIMER_FULLSCREENCONTROLBARHIDER,
+ TIMER_FULLSCREENMOUSEHIDER,
+ TIMER_STATS,
+ TIMER_LEFTCLICK,
+ TIMER_STATUSERASER
+ };
+
+ friend class CPPageFileInfoSheet;
+ friend class CPPageLogo;
+
+ // TODO: wrap these graph objects into a class to make it look cleaner
+
+ DWORD m_dwRegister;
+
+ CComPtr<IGraphBuilder2> pGB;
+ CComQIPtr<IMediaControl> pMC;
+ CComQIPtr<IMediaEventEx> pME;
+ CComQIPtr<IVideoWindow> pVW;
+ CComQIPtr<IBasicVideo> pBV;
+ CComQIPtr<IBasicAudio> pBA;
+ CComQIPtr<IMediaSeeking> pMS;
+ CComQIPtr<IVideoFrameStep> pFS;
+ CComQIPtr<IQualProp, &IID_IQualProp> pQP;
+ CComQIPtr<IBufferInfo> pBI;
+ CComQIPtr<IAMOpenProgress> pAMOP;
+
+ CComQIPtr<IDvdControl2> pDVDC;
+ CComQIPtr<IDvdInfo2> pDVDI;
+
+ CComPtr<ICaptureGraphBuilder2> pCGB;
+ CStringW m_VidDispName, m_AudDispName;
+ CComPtr<IBaseFilter> pVidCap, pAudCap;
+ CComPtr<IAMVideoCompression> pAMVCCap, pAMVCPrev;
+ CComPtr<IAMStreamConfig> pAMVSCCap, pAMVSCPrev, pAMASC;
+ CComPtr<IAMCrossbar> pAMXBar;
+ CComPtr<IAMTVTuner> pAMTuner;
+ CComPtr<IAMDroppedFrames> pAMDF;
+
+ CComPtr<ISubPicAllocatorPresenter> m_pCAP;
+
+ void SetBalance(int balance);
+
+ // subtitles
+
+ CCritSec m_csSubLock;
+ CInterfaceList<ISubStream> m_pSubStreams;
+ int m_iSubtitleSel; // if(m_iSubtitleSel&(1<<31)): disabled
+ DWORD_PTR m_nSubtitleId;
+
+ friend class CTextPassThruFilter;
+
+ // windowing
+
+ CRect m_lastWindowRect;
+ CPoint m_lastMouseMove;
+
+ CRect m_rcDesktop;
+
+ void ShowControls(int nCS, bool fSave = true);
+
+ void SetDefaultWindowRect(int iMonitor = 0);
+ void RestoreDefaultWindowRect();
+ void ZoomVideoWindow(double scale = -1);
+ double GetZoomAutoFitScale();
+
+ void SetAlwaysOnTop(int i);
+
+ // dynamic menus
+
+ void SetupOpenCDSubMenu();
+ void SetupFiltersSubMenu();
+ void SetupAudioSwitcherSubMenu();
+ void SetupSubtitlesSubMenu();
+ void SetupNavAudioSubMenu();
+ void SetupNavSubtitleSubMenu();
+ void SetupNavAngleSubMenu();
+ void SetupNavChaptersSubMenu();
+ void SetupFavoritesSubMenu();
+ void SetupShadersSubMenu();
+
+ void SetupNavStreamSelectSubMenu(CMenu* pSub, UINT id, DWORD dwSelGroup);
+ void OnNavStreamSelectSubMenu(UINT id, DWORD dwSelGroup);
+
+ CMenu m_popupmain, m_popup;
+ CMenu m_opencds;
+ CMenu m_filters, m_subtitles, m_audios;
+ CAutoPtrArray<CMenu> m_filterpopups;
+ CMenu m_navaudio, m_navsubtitle, m_navangle;
+ CMenu m_navchapters, m_navtitles;
+ CMenu m_favorites;
+ CMenu m_shaders;
+
+ CInterfaceArray<IUnknown, &IID_IUnknown> m_pparray;
+ CInterfaceArray<IAMStreamSelect> m_ssarray;
+
+ // chapters (file mode)
+ CComPtr<IDSMChapterBag> m_pCB;
+ void SetupChapters();
+
+ //
+
+ void SetupIViAudReg();
+
+ void AddTextPassThruFilter();
+
+ int m_nLoops;
+
+ bool m_fCustomGraph;
+ bool m_fRealMediaGraph, m_fShockwaveGraph, m_fQuicktimeGraph;
+
+ CComPtr<ISubClock> m_pSubClock;
+
+ int m_fFrameSteppingActive;
+ int m_VolumeBeforeFrameStepping;
+
+ bool m_fEndOfStream;
+
+ bool m_fBuffering;
+
+ bool m_fLiveWM;
+
+ bool m_fUpdateInfoBar;
+
+ void SendStatusMessage(CString msg, int nTimeOut);
+ CString m_playingmsg, m_closingmsg;
+
+ REFERENCE_TIME m_rtDurationOverride;
+
+ CComPtr<IUnknown> m_pProv;
+
+ void CleanGraph();
+
+ CComPtr<IBaseFilter> pAudioDubSrc;
+
+ void ShowOptions(int idPage = 0);
+
+ bool GetDIB(BYTE** ppData, long& size, bool fSilent = false);
+ void SaveDIB(LPCTSTR fn, BYTE* pData, long size);
+ void SaveImage(LPCTSTR fn);
+ void SaveThumbnails(LPCTSTR fn);
+
+ //
+
+ friend class CWebClientSocket;
+ friend class CWebServer;
+ CAutoPtr<CWebServer> m_pWebServer;
+
+public:
+ void StartWebServer(int nPort);
+ void StopWebServer();
+
+ CString GetStatusMessage();
+ bool IsMuted() {return m_wndToolBar.GetVolume() == -10000;}
+ int GetVolume() {return m_wndToolBar.m_volctrl.GetPos();}
+
+public:
+ CMainFrame();
+
+ DECLARE_DYNAMIC(CMainFrame)
+
+// Attributes
+public:
+ int m_iPlaybackMode;
+
+ bool m_fFullScreen;
+ bool m_fHideCursor;
+
+ bool IsFrameLessWindow() {return(m_fFullScreen || AfxGetAppSettings().fHideCaptionMenu);}
+ bool IsCaptionMenuHidden() {return(!m_fFullScreen && AfxGetAppSettings().fHideCaptionMenu);}
+ bool IsSomethingLoaded() {return((m_iMediaLoadState == MLS_LOADING || m_iMediaLoadState == MLS_LOADED) && !IsD3DFullScreenMode());}
+ bool IsPlaylistEmpty() {return(m_wndPlaylistBar.GetCount() == 0);}
+ bool IsInteractiveVideo() {return(AfxGetAppSettings().fIntRealMedia && m_fRealMediaGraph || m_fShockwaveGraph);}
+ bool IsD3DFullScreenMode();
+
+ CControlBar* m_pLastBar;
+
+protected:
+ enum {MLS_CLOSED, MLS_LOADING, MLS_LOADED, MLS_CLOSING};
+ int m_iMediaLoadState;
+
+ bool m_fAudioOnly;
+ dispmode m_dmBeforeFullscreen;
+
+ DVD_DOMAIN m_iDVDDomain;
+ DWORD m_iDVDTitle;
+ int m_iSpeedLevel;
+
+ double m_ZoomX, m_ZoomY, m_PosX, m_PosY;
+ int m_AngleX, m_AngleY, m_AngleZ;
+
+// Operations
+ bool OpenMediaPrivate(CAutoPtr<OpenMediaData> pOMD);
+ void CloseMediaPrivate();
+
+ void SendNowPlayingToMSN();
+ void SendNowPlayingTomIRC();
+
+ void OpenCreateGraphObject(OpenMediaData* pOMD);
+ void OpenFile(OpenFileData* pOFD);
+ void OpenDVD(OpenDVDData* pODD);
+ void OpenCapture(OpenDeviceData* pODD);
+ void OpenCustomizeGraph();
+ void OpenSetupVideo();
+ void OpenSetupAudio();
+ void OpenSetupInfoBar();
+ void OpenSetupStatsBar();
+ void OpenSetupStatusBar();
+ // void OpenSetupToolBar();
+ void OpenSetupCaptureBar();
+ void OpenSetupWindowTitle(CString fn = _T(""));
+
+ friend class CGraphThread;
+ CGraphThread* m_pGraphThread;
+
+ CAtlArray<REFERENCE_TIME> m_kfs;
+
+ bool m_fOpeningAborted;
+
+public:
+ void OpenCurPlaylistItem(REFERENCE_TIME rtStart = 0);
+ void OpenMedia(CAutoPtr<OpenMediaData> pOMD);
+ void CloseMedia();
+
+ void AddCurDevToPlaylist();
+
+ bool m_fTrayIcon;
+ void ShowTrayIcon(bool fShow);
+ void SetTrayTip(CString str);
+
+ CSize GetVideoSize();
+ void ToggleFullscreen(bool fToNearest, bool fSwitchScreenResWhenHasTo);
+ void MoveVideoWindow(bool fShowStats = false);
+ void RepaintVideo();
+
+ OAFilterState GetMediaState();
+ REFERENCE_TIME GetPos(), GetDur();
+ void SeekTo(REFERENCE_TIME rt, bool fSeekToKeyFrame = false);
+
+ bool LoadSubtitle(CString fn);
+ void UpdateSubtitle(bool fApplyDefStyle = false);
+ void SetSubtitle(ISubStream* pSubStream, bool fApplyDefStyle = false);
+ void ReplaceSubtitle(ISubStream* pSubStreamOld, ISubStream* pSubStreamNew);
+ void InvalidateSubtitle(DWORD_PTR nSubtitleId = -1, REFERENCE_TIME rtInvalidate = -1);
+ void ReloadSubtitle();
+
+ // shaders
+ CAtlList<CString> m_shaderlabels;
+ void SetShaders();
+ void UpdateShaders(CString label);
+
+ // capturing
+ bool m_fCapturing;
+ HRESULT BuildCapture(IPin* pPin, IBaseFilter* pBF[3], const GUID& majortype, AM_MEDIA_TYPE* pmt); // pBF: 0 buff, 1 enc, 2 mux, pmt is for 1 enc
+ bool BuildToCapturePreviewPin(
+ IBaseFilter* pVidCap, IPin** pVidCapPin, IPin** pVidPrevPin,
+ IBaseFilter* pAudCap, IPin** pAudCapPin, IPin** pAudPrevPin);
+ bool BuildGraphVideoAudio(int fVPreview, bool fVCapture, int fAPreview, bool fACapture);
+ bool DoCapture(), StartCapture(), StopCapture();
+
+ bool DoAfterPlaybackEvent();
+
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
+ virtual void RecalcLayout(BOOL bNotify = TRUE);
+
+// Implementation
+public:
+ virtual ~CMainFrame();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected: // control bar embedded members
+
+ CChildView m_wndView;
+
+ CPlayerSeekBar m_wndSeekBar;
+ CPlayerToolBar m_wndToolBar;
+ CPlayerInfoBar m_wndInfoBar;
+ CPlayerInfoBar m_wndStatsBar;
+ CPlayerStatusBar m_wndStatusBar;
+ CList<CControlBar*> m_bars;
+
+ CPlayerSubresyncBar m_wndSubresyncBar;
+ CPlayerPlaylistBar m_wndPlaylistBar;
+ CPlayerCaptureBar m_wndCaptureBar;
+ CPlayerShaderEditorBar m_wndShaderEditorBar;
+ CList<CSizingControlBar*> m_dockingbars;
+
+ CFileDropTarget m_fileDropTarget;
+ // TODO
+ DROPEFFECT OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
+ DROPEFFECT OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
+ BOOL OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point);
+ DROPEFFECT OnDropEx(COleDataObject* pDataObject, DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point);
+ void OnDragLeave();
+ DROPEFFECT OnDragScroll(DWORD dwKeyState, CPoint point);
+
+ friend class CPPagePlayback; // TODO
+ friend class CMPlayerCApp; // TODO
+
+ void LoadControlBar(CControlBar* pBar, UINT defDockBarID);
+ void RestoreFloatingControlBars();
+ void SaveControlBars();
+
+// Generated message map functions
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnDestroy();
+
+ afx_msg LRESULT OnTaskBarRestart(WPARAM, LPARAM);
+ afx_msg LRESULT OnNotifyIcon(WPARAM, LPARAM);
+
+ afx_msg void OnSetFocus(CWnd* pOldWnd);
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
+ afx_msg void OnMove(int x, int y);
+ afx_msg void OnMoving(UINT fwSide, LPRECT pRect);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnSizing(UINT fwSide, LPRECT pRect);
+ afx_msg void OnDisplayChange();
+
+ afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+ afx_msg void OnActivateApp(BOOL bActive, DWORD dwThreadID);
+ afx_msg LRESULT OnAppCommand(WPARAM wParam, LPARAM lParam);
+
+ afx_msg void OnTimer(UINT nIDEvent);
+
+ afx_msg LRESULT OnGraphNotify(WPARAM wParam, LPARAM lParam);
+ afx_msg LRESULT OnRepaintRenderLess(WPARAM wParam, LPARAM lParam);
+ afx_msg LRESULT OnResumeFromState(WPARAM wParam, LPARAM lParam);
+
+ BOOL OnButton(UINT id, UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
+ afx_msg void OnMButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnMButtonUp(UINT nFlags, CPoint point);
+ afx_msg void OnMButtonDblClk(UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDblClk(UINT nFlags, CPoint point);
+ afx_msg LRESULT OnXButtonDown(WPARAM wParam, LPARAM lParam);
+ afx_msg LRESULT OnXButtonUp(WPARAM wParam, LPARAM lParam);
+ afx_msg LRESULT OnXButtonDblClk(WPARAM wParam, LPARAM lParam);
+ afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
+ afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+
+ afx_msg UINT OnNcHitTest(CPoint point);
+
+ afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+
+ afx_msg void OnInitMenu(CMenu* pMenu);
+ afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu);
+
+ BOOL OnMenu(CMenu* pMenu);
+ afx_msg void OnMenuPlayerShort();
+ afx_msg void OnMenuPlayerLong();
+ afx_msg void OnMenuFilters();
+
+ afx_msg void OnUpdatePlayerStatus(CCmdUI* pCmdUI);
+
+ afx_msg void OnFilePostOpenmedia();
+ afx_msg void OnUpdateFilePostOpenmedia(CCmdUI* pCmdUI);
+ afx_msg void OnFilePostClosemedia();
+ afx_msg void OnUpdateFilePostClosemedia(CCmdUI* pCmdUI);
+
+ afx_msg void OnBossKey();
+
+ afx_msg void OnStreamAudio(UINT nID);
+ afx_msg void OnStreamSub(UINT nID);
+ afx_msg void OnStreamSubOnOff();
+ afx_msg void OnOgmAudio(UINT nID);
+ afx_msg void OnOgmSub(UINT nID);
+ afx_msg void OnDvdAngle(UINT nID);
+ afx_msg void OnDvdAudio(UINT nID);
+ afx_msg void OnDvdSub(UINT nID);
+ afx_msg void OnDvdSubOnOff();
+
+
+ // menu item handlers
+
+ afx_msg void OnFileOpenQuick();
+ afx_msg void OnFileOpenmedia();
+ afx_msg void OnUpdateFileOpen(CCmdUI* pCmdUI);
+ afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct);
+ afx_msg void OnFileOpendvd();
+ afx_msg void OnFileOpendevice();
+ afx_msg void OnFileOpenCD(UINT nID);
+ afx_msg void OnDropFiles(HDROP hDropInfo); // no menu item
+ afx_msg void OnFileSaveAs();
+ afx_msg void OnUpdateFileSaveAs(CCmdUI* pCmdUI);
+ afx_msg void OnFileSaveImage();
+ afx_msg void OnFileSaveImageAuto();
+ afx_msg void OnUpdateFileSaveImage(CCmdUI* pCmdUI);
+ afx_msg void OnFileSaveThumbnails();
+ afx_msg void OnUpdateFileSaveThumbnails(CCmdUI* pCmdUI);
+ afx_msg void OnFileConvert();
+ afx_msg void OnUpdateFileConvert(CCmdUI* pCmdUI);
+ afx_msg void OnFileLoadsubtitle();
+ afx_msg void OnUpdateFileLoadsubtitle(CCmdUI* pCmdUI);
+ afx_msg void OnFileSavesubtitle();
+ afx_msg void OnUpdateFileSavesubtitle(CCmdUI* pCmdUI);
+ afx_msg void OnFileISDBSearch();
+ afx_msg void OnUpdateFileISDBSearch(CCmdUI* pCmdUI);
+ afx_msg void OnFileISDBUpload();
+ afx_msg void OnUpdateFileISDBUpload(CCmdUI* pCmdUI);
+ afx_msg void OnFileISDBDownload();
+ afx_msg void OnUpdateFileISDBDownload(CCmdUI* pCmdUI);
+ afx_msg void OnFileProperties();
+ afx_msg void OnUpdateFileProperties(CCmdUI* pCmdUI);
+ afx_msg void OnFileClosePlaylist();
+ afx_msg void OnFileCloseMedia(); // no menu item
+ afx_msg void OnUpdateFileClose(CCmdUI* pCmdUI);
+
+ afx_msg void OnViewCaptionmenu();
+ afx_msg void OnUpdateViewCaptionmenu(CCmdUI* pCmdUI);
+ afx_msg void OnViewControlBar(UINT nID);
+ afx_msg void OnUpdateViewControlBar(CCmdUI* pCmdUI);
+ afx_msg void OnViewSubresync();
+ afx_msg void OnUpdateViewSubresync(CCmdUI* pCmdUI);
+ afx_msg void OnViewPlaylist();
+ afx_msg void OnUpdateViewPlaylist(CCmdUI* pCmdUI);
+ afx_msg void OnViewCapture();
+ afx_msg void OnUpdateViewCapture(CCmdUI* pCmdUI);
+ afx_msg void OnViewShaderEditor();
+ afx_msg void OnUpdateViewShaderEditor(CCmdUI* pCmdUI);
+ afx_msg void OnViewMinimal();
+ afx_msg void OnUpdateViewMinimal(CCmdUI* pCmdUI);
+ afx_msg void OnViewCompact();
+ afx_msg void OnUpdateViewCompact(CCmdUI* pCmdUI);
+ afx_msg void OnViewNormal();
+ afx_msg void OnUpdateViewNormal(CCmdUI* pCmdUI);
+ afx_msg void OnViewFullscreen();
+ afx_msg void OnViewFullscreenSecondary();
+ afx_msg void OnUpdateViewFullscreen(CCmdUI* pCmdUI);
+ afx_msg void OnViewZoom(UINT nID);
+ afx_msg void OnUpdateViewZoom(CCmdUI* pCmdUI);
+ afx_msg void OnViewZoomAutoFit();
+ afx_msg void OnViewDefaultVideoFrame(UINT nID);
+ afx_msg void OnUpdateViewDefaultVideoFrame(CCmdUI* pCmdUI);
+ afx_msg void OnViewKeepaspectratio();
+ afx_msg void OnUpdateViewKeepaspectratio(CCmdUI* pCmdUI);
+ afx_msg void OnViewCompMonDeskARDiff();
+ afx_msg void OnUpdateViewCompMonDeskARDiff(CCmdUI* pCmdUI);
+ afx_msg void OnViewPanNScan(UINT nID);
+ afx_msg void OnUpdateViewPanNScan(CCmdUI* pCmdUI);
+ afx_msg void OnViewPanNScanPresets(UINT nID);
+ afx_msg void OnUpdateViewPanNScanPresets(CCmdUI* pCmdUI);
+ afx_msg void OnViewRotate(UINT nID);
+ afx_msg void OnUpdateViewRotate(CCmdUI* pCmdUI);
+ afx_msg void OnViewAspectRatio(UINT nID);
+ afx_msg void OnUpdateViewAspectRatio(CCmdUI* pCmdUI);
+ afx_msg void OnViewAspectRatioNext();
+ afx_msg void OnViewOntop(UINT nID);
+ afx_msg void OnUpdateViewOntop(CCmdUI* pCmdUI);
+ afx_msg void OnViewOptions();
+ afx_msg void OnUpdateViewTearingTest(CCmdUI* pCmdUI);
+ afx_msg void OnViewTearingTest();
+ afx_msg void OnUpdateShaderToggle(CCmdUI* pCmdUI);
+ afx_msg void OnShaderToggle();
+ afx_msg void OnUpdateViewRemainingTime(CCmdUI* pCmdUI);
+ afx_msg void OnViewRemainingTime();
+
+
+ afx_msg void OnPlayPlay();
+ afx_msg void OnPlayPause();
+ afx_msg void OnPlayPlaypause();
+ afx_msg void OnPlayStop();
+ afx_msg void OnUpdatePlayPauseStop(CCmdUI* pCmdUI);
+ afx_msg void OnPlayFramestep(UINT nID);
+ afx_msg void OnUpdatePlayFramestep(CCmdUI* pCmdUI);
+ afx_msg void OnPlaySeek(UINT nID);
+ afx_msg void OnPlaySeekKey(UINT nID); // no menu item
+ afx_msg void OnUpdatePlaySeek(CCmdUI* pCmdUI);
+ afx_msg void OnPlayGoto();
+ afx_msg void OnUpdateGoto(CCmdUI* pCmdUI);
+ afx_msg void OnPlayChangeRate(UINT nID);
+ afx_msg void OnUpdatePlayChangeRate(CCmdUI* pCmdUI);
+ afx_msg void OnPlayResetRate();
+ afx_msg void OnUpdatePlayResetRate(CCmdUI* pCmdUI);
+ afx_msg void OnPlayChangeAudDelay(UINT nID);
+ afx_msg void OnUpdatePlayChangeAudDelay(CCmdUI* pCmdUI);
+ afx_msg void OnPlayFilters(UINT nID);
+ afx_msg void OnUpdatePlayFilters(CCmdUI* pCmdUI);
+ afx_msg void OnPlayShaders(UINT nID);
+ afx_msg void OnUpdatePlayShaders(CCmdUI* pCmdUI);
+ afx_msg void OnPlayAudio(UINT nID);
+ afx_msg void OnUpdatePlayAudio(CCmdUI* pCmdUI);
+ afx_msg void OnPlaySubtitles(UINT nID);
+ afx_msg void OnUpdatePlaySubtitles(CCmdUI* pCmdUI);
+ afx_msg void OnPlayLanguage(UINT nID);
+ afx_msg void OnUpdatePlayLanguage(CCmdUI* pCmdUI);
+ afx_msg void OnPlayVolume(UINT nID);
+ afx_msg void OnPlayVolumeBoost(UINT nID);
+ afx_msg void OnUpdatePlayVolumeBoost(CCmdUI* pCmdUI);
+ afx_msg void OnAfterplayback(UINT nID);
+ afx_msg void OnUpdateAfterplayback(CCmdUI* pCmdUI);
+
+ afx_msg void OnNavigateSkip(UINT nID);
+ afx_msg void OnUpdateNavigateSkip(CCmdUI* pCmdUI);
+ afx_msg void OnNavigateSkipPlaylistItem(UINT nID);
+ afx_msg void OnUpdateNavigateSkipPlaylistItem(CCmdUI* pCmdUI);
+ afx_msg void OnNavigateMenu(UINT nID);
+ afx_msg void OnUpdateNavigateMenu(CCmdUI* pCmdUI);
+ afx_msg void OnNavigateAudio(UINT nID);
+ afx_msg void OnNavigateSubpic(UINT nID);
+ afx_msg void OnNavigateAngle(UINT nID);
+ afx_msg void OnNavigateChapters(UINT nID);
+ afx_msg void OnNavigateMenuItem(UINT nID);
+ afx_msg void OnUpdateNavigateMenuItem(CCmdUI* pCmdUI);
+
+ afx_msg void OnFavoritesAdd();
+ afx_msg void OnUpdateFavoritesAdd(CCmdUI* pCmdUI);
+ afx_msg void OnFavoritesOrganize();
+ afx_msg void OnUpdateFavoritesOrganize(CCmdUI* pCmdUI);
+ afx_msg void OnFavoritesFile(UINT nID);
+ afx_msg void OnUpdateFavoritesFile(CCmdUI* pCmdUI);
+ afx_msg void OnFavoritesDVD(UINT nID);
+ afx_msg void OnUpdateFavoritesDVD(CCmdUI* pCmdUI);
+ afx_msg void OnFavoritesDevice(UINT nID);
+ afx_msg void OnUpdateFavoritesDevice(CCmdUI* pCmdUI);
+
+ afx_msg void OnHelpHomepage();
+ afx_msg void OnHelpDocumentation();
+ afx_msg void OnHelpDonate();
+
+ afx_msg void OnClose();
+
+
+ // ==== Added by CASIMIR666
+ CWnd* m_pVideoWnd; // Vidéo courante (écran principal ou 2ieme écran)
+ SIZE m_fullWndSize;
+ CFullscreenWnd* m_pFullscreenWnd;
+ CComPtr<IVMRMixerControl9> m_pMC;
+ CVMROSD m_OSD;
+ bool m_bD3DFullscreenMode;
+ bool m_bRemainingTime;
+
+ bool CreateFullScreenWindow();
+ void SetVMR9ColorControl(float Brightness, float Contrast, float Hue, float Saturation);
+ LPCTSTR GetDVDAudioFormatName (DVD_AudioAttributes& ATR);
+};
diff --git a/src/apps/mplayerc/MediaFormats.cpp b/src/apps/mplayerc/MediaFormats.cpp
new file mode 100644
index 000000000..644e95511
--- /dev/null
+++ b/src/apps/mplayerc/MediaFormats.cpp
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include <atlbase.h>
+#include "MediaFormats.h"
+
+//
+// CMediaFormatCategory
+//
+
+CMediaFormatCategory::CMediaFormatCategory()
+ : m_fAudioOnly(false)
+{
+}
+
+CMediaFormatCategory::CMediaFormatCategory(
+ CString label, CAtlList<CString>& exts, bool fAudioOnly,
+ CString specreqnote, engine_t engine)
+{
+ m_label = label;
+ m_exts.AddTailList(&exts);
+ m_backupexts.AddTailList(&m_exts);
+ m_specreqnote = specreqnote;
+ m_fAudioOnly = fAudioOnly;
+ m_engine = engine;
+}
+
+CMediaFormatCategory::CMediaFormatCategory(
+ CString label, CString exts, bool fAudioOnly,
+ CString specreqnote, engine_t engine)
+{
+ m_label = label;
+ ExplodeMin(exts, m_exts, ' ');
+ POSITION pos = m_exts.GetHeadPosition();
+ while(pos) m_exts.GetNext(pos).TrimLeft('.');
+
+ m_backupexts.AddTailList(&m_exts);
+ m_specreqnote = specreqnote;
+ m_fAudioOnly = fAudioOnly;
+ m_engine = engine;
+}
+
+CMediaFormatCategory::~CMediaFormatCategory()
+{
+}
+
+void CMediaFormatCategory::UpdateData(bool fSave)
+{
+ if(fSave)
+ {
+ AfxGetApp()->WriteProfileString(_T("FileFormats"), m_label, GetExts(true));
+ }
+ else
+ {
+ SetExts(AfxGetApp()->GetProfileString(_T("FileFormats"), m_label, GetExts(true)));
+ }
+}
+
+CMediaFormatCategory::CMediaFormatCategory(CMediaFormatCategory& mfc)
+{
+ *this = mfc;
+}
+
+CMediaFormatCategory& CMediaFormatCategory::operator = (const CMediaFormatCategory& mfc)
+{
+ m_label = mfc.m_label;
+ m_specreqnote = mfc.m_specreqnote;
+ m_exts.RemoveAll();
+ m_exts.AddTailList(&mfc.m_exts);
+ m_backupexts.RemoveAll();
+ m_backupexts.AddTailList(&mfc.m_backupexts);
+ m_fAudioOnly = mfc.m_fAudioOnly;
+ m_engine = mfc.m_engine;
+
+ return(*this);
+}
+
+void CMediaFormatCategory::RestoreDefaultExts()
+{
+ m_exts.RemoveAll();
+ m_exts.AddTailList(&m_backupexts);
+}
+
+void CMediaFormatCategory::SetExts(CAtlList<CString>& exts)
+{
+ m_exts.RemoveAll();
+ m_exts.AddTailList(&exts);
+}
+
+void CMediaFormatCategory::SetExts(CString exts)
+{
+ m_exts.RemoveAll();
+ ExplodeMin(exts, m_exts, ' ');
+ POSITION pos = m_exts.GetHeadPosition();
+ while(pos)
+ {
+ POSITION cur = pos;
+ CString& ext = m_exts.GetNext(pos);
+ if(ext[0] == '\\') {m_engine = (engine_t)_tcstol(ext.TrimLeft('\\'), NULL, 10); m_exts.RemoveAt(cur);}
+ else ext.TrimLeft('.');
+ }
+}
+
+CString CMediaFormatCategory::GetFilter()
+{
+ CString filter;
+ POSITION pos = m_exts.GetHeadPosition();
+ while(pos) filter += _T("*.") + m_exts.GetNext(pos) + _T(";");
+ filter.TrimRight(_T(";")); // cheap...
+ return(filter);
+}
+
+CString CMediaFormatCategory::GetExts(bool fAppendEngine)
+{
+ CString exts = Implode(m_exts, ' ');
+ if(fAppendEngine) exts += CString(_T(" \\")) + (TCHAR)(0x30 + (int)m_engine);
+ return(exts);
+}
+
+CString CMediaFormatCategory::GetExtsWithPeriod(bool fAppendEngine)
+{
+ CString exts;
+ POSITION pos = m_exts.GetHeadPosition();
+ while(pos) exts += _T(".") + m_exts.GetNext(pos) + _T(" ");
+ exts.TrimRight(_T(" ")); // cheap...
+ if(fAppendEngine) exts += CString(_T(" \\")) + (TCHAR)(0x30 + (int)m_engine);
+ return(exts);
+}
+
+CString CMediaFormatCategory::GetBackupExtsWithPeriod(bool fAppendEngine)
+{
+ CString exts;
+ POSITION pos = m_backupexts.GetHeadPosition();
+ while(pos) exts += _T(".") + m_backupexts.GetNext(pos) + _T(" ");
+ exts.TrimRight(_T(" ")); // cheap...
+ if(fAppendEngine) exts += CString(_T(" \\")) + (TCHAR)(0x30 + (int)m_engine);
+ return(exts);
+}
+
+//
+// CMediaFormats
+//
+
+CMediaFormats::CMediaFormats()
+{
+}
+
+CMediaFormats::~CMediaFormats()
+{
+}
+
+void CMediaFormats::UpdateData(bool fSave)
+{
+ if(fSave)
+ {
+ AfxGetApp()->WriteProfileString(_T("FileFormats"), NULL, NULL);
+
+ AfxGetApp()->WriteProfileInt(_T("FileFormats"), _T("RtspHandler"), m_iRtspHandler);
+ AfxGetApp()->WriteProfileInt(_T("FileFormats"), _T("RtspFileExtFirst"), m_fRtspFileExtFirst);
+ }
+ else
+ {
+ RemoveAll();
+#define ADDFMT(f) Add(CMediaFormatCategory##f)
+ ADDFMT((_T("Windows Media file"), _T("wmv wmp wm asf")));
+ ADDFMT((_T("Windows Media Audio file"), _T("wma"), true));
+ ADDFMT((_T("Video file"), _T("avi")));
+ ADDFMT((_T("Audio file"), _T("wav"), true));
+ ADDFMT((_T("MPEG Media file "), _T("mpg mpeg mpe m1v m2v mpv2 mp2v dat ts tp tpr pva pss")));
+ ADDFMT((_T("MPEG Audio file"), _T("mpa mp2 m1a m2a"), true));
+ ADDFMT((_T("DVD file"), _T("vob ifo")));
+ ADDFMT((_T("DVD Audio file"), _T("ac3 dts"), true));
+ ADDFMT((_T("MP3 Format Sound"), _T("mp3"), true));
+ ADDFMT((_T("MIDI file"), _T("mid midi rmi"), true));
+ ADDFMT((_T("Indeo Video file"), _T("ivf")));
+ ADDFMT((_T("AIFF Format Sound"), _T("aif aifc aiff"), true));
+ ADDFMT((_T("AU Format Sound"), _T("au snd"), true));
+ ADDFMT((_T("Ogg Media file"), _T("ogm")));
+ ADDFMT((_T("Ogg Vorbis Audio file"), _T("ogg"), true));
+ ADDFMT((_T("CD Audio Track"), _T("cda"), true, _T("Windows 2000/XP or better")));
+ ADDFMT((_T("FLIC file"), _T("fli flc flic")));
+ ADDFMT((_T("DVD2AVI Project file"), _T("d2v")));
+ ADDFMT((_T("MPEG4 file "), _T("mp4 m4v m4p m4b 3gp 3gpp 3g2 3gp2")));
+ ADDFMT((_T("MPEG4 Audio file "), _T("m4a aac"), true));
+ ADDFMT((_T("Matroska Media file"), _T("mkv")));
+ ADDFMT((_T("Matroska Audio file"), _T("mka"), true));
+ ADDFMT((_T("Smacker/Bink Media file"), _T("smk bik"), false, _T("smackw32/binkw32.dll in dll path")));
+ ADDFMT((_T("ratdvd file"), _T("ratdvd"), false, _T("ratdvd media file")));
+ ADDFMT((_T("RoQ Media file"), _T("roq"), false));
+ ADDFMT((_T("Real Media file "), _T("rm ram rmvb rpm"), false, _T("RealOne or codec pack")));
+ ADDFMT((_T("Real Audio file "), _T("ra"), true, _T("RealOne or codec pack")));
+ ADDFMT((_T("Real Script file"), _T("rt rp smi smil"), false, _T("RealOne or codec pack"), RealMedia));
+ ADDFMT((_T("Dirac Video file"), _T("drc"), false));
+ ADDFMT((_T("DirectShow Media file"), _T("dsm dsv dsa dss")));
+ ADDFMT((_T("Shockwave Flash file"), _T("swf"), false, _T("ShockWave ActiveX control"), ShockWave));
+ ADDFMT((_T("Quicktime file "), _T("mov qt amr"), false, _T("QuickTime Player or codec pack"), QuickTime));
+ ADDFMT((_T("Image file"), _T("jpeg jpg bmp gif pic png dib tiff tif")));
+ ADDFMT((_T("Playlist file"), _T("asx m3u pls wvx wax wmx mpcpl")));
+ ADDFMT((_T("Other "), _T("divx vp6")));
+#undef ADDFMT
+
+ m_iRtspHandler = (engine_t)AfxGetApp()->GetProfileInt(_T("FileFormats"), _T("RtspHandler"), (int)RealMedia);
+ m_fRtspFileExtFirst = !!AfxGetApp()->GetProfileInt(_T("FileFormats"), _T("RtspFileExtFirst"), 1);
+ }
+
+ for(int i = 0; i < GetCount(); i++)
+ GetAt(i).UpdateData(fSave);
+}
+
+engine_t CMediaFormats::GetRtspHandler(bool& fRtspFileExtFirst)
+{
+ fRtspFileExtFirst = m_fRtspFileExtFirst;
+ return m_iRtspHandler;
+}
+
+void CMediaFormats::SetRtspHandler(engine_t e, bool fRtspFileExtFirst)
+{
+ m_iRtspHandler = e;
+ m_fRtspFileExtFirst = fRtspFileExtFirst;
+}
+
+bool CMediaFormats::IsUsingEngine(CString path, engine_t e)
+{
+ return(GetEngine(path) == e);
+}
+
+engine_t CMediaFormats::GetEngine(CString path)
+{
+ path.Trim().MakeLower();
+
+ if(!m_fRtspFileExtFirst && path.Find(_T("rtsp://")) == 0)
+ return m_iRtspHandler;
+
+ CString ext = CPath(path).GetExtension();
+ ext.MakeLower();
+ if(!ext.IsEmpty())
+ {
+ if(path.Find(_T("rtsp://")) == 0)
+ {
+ if(ext == _T(".ram") || ext == _T(".rm") || ext == _T(".ra"))
+ return RealMedia;
+ if(ext == _T(".qt") || ext == _T(".mov"))
+ return QuickTime;
+ }
+
+ for(int i = 0; i < GetCount(); i++)
+ {
+ CMediaFormatCategory& mfc = GetAt(i);
+ if(mfc.FindExt(ext))
+ return mfc.GetEngineType();
+ }
+ }
+
+ if(m_fRtspFileExtFirst && path.Find(_T("rtsp://")) == 0)
+ return m_iRtspHandler;
+
+ return DirectShow;
+}
+
+bool CMediaFormats::FindExt(CString ext, bool fAudioOnly)
+{
+ ext.TrimLeft(_T("."));
+
+ if(!ext.IsEmpty())
+ {
+ for(int i = 0; i < GetCount(); i++)
+ {
+ CMediaFormatCategory& mfc = GetAt(i);
+ if((!fAudioOnly || mfc.IsAudioOnly()) && mfc.FindExt(ext))
+ return(true);
+ }
+ }
+
+ return(false);
+}
+
+void CMediaFormats::GetFilter(CString& filter, CAtlArray<CString>& mask)
+{
+ filter += _T("Media files (all types)|__dummy|");
+ mask.Add(_T(""));
+
+ for(int i = 0; i < GetCount(); i++)
+ mask[0] += GetAt(i).GetFilter() + _T(";");
+ mask[0].TrimRight(_T(";"));
+
+ for(int i = 0; i < GetCount(); i++)
+ {
+ CMediaFormatCategory& mfc = GetAt(i);
+ filter += mfc.GetLabel() + _T("|__dummy|");
+ mask.Add(mfc.GetFilter());
+ }
+
+ filter += _T("All files (*.*)|__dummy|");
+ mask.Add(_T("*.*"));
+
+ filter += _T("|");
+}
+
+void CMediaFormats::GetAudioFilter(CString& filter, CAtlArray<CString>& mask)
+{
+ filter += _T("Audio files (all types)|__dummy|");
+ mask.Add(_T(""));
+
+ for(int i = 0; i < GetCount(); i++)
+ {
+ CMediaFormatCategory& mfc = GetAt(i);
+ if(!mfc.IsAudioOnly() || mfc.GetEngineType() != DirectShow) continue;
+ mask[0] += GetAt(i).GetFilter() + _T(";");
+ }
+
+ mask[0].TrimRight(_T(";"));
+
+ for(int i = 0; i < GetCount(); i++)
+ {
+ CMediaFormatCategory& mfc = GetAt(i);
+ if(!mfc.IsAudioOnly() || mfc.GetEngineType() != DirectShow) continue;
+ filter += mfc.GetLabel() + _T("|__dummy|");
+ mask.Add(mfc.GetFilter());
+ }
+
+ filter += _T("All files (*.*)|__dummy|");
+ mask.Add(_T("*.*"));
+
+ filter += _T("|");
+} \ No newline at end of file
diff --git a/src/apps/mplayerc/MediaFormats.h b/src/apps/mplayerc/MediaFormats.h
new file mode 100644
index 000000000..ae54f9717
--- /dev/null
+++ b/src/apps/mplayerc/MediaFormats.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <atlcoll.h>
+#include "BaseGraph.h"
+
+class CMediaFormatCategory
+{
+public:
+protected:
+ CString m_label, m_specreqnote;
+ CAtlList<CString> m_exts, m_backupexts;
+ bool m_fAudioOnly;
+ engine_t m_engine;
+
+public:
+ CMediaFormatCategory();
+ CMediaFormatCategory(
+ CString label, CAtlList<CString>& exts, bool fAudioOnly = false,
+ CString specreqnote = _T(""), engine_t e = DirectShow);
+ CMediaFormatCategory(
+ CString label, CString exts, bool fAudioOnly = false,
+ CString specreqnote = _T(""), engine_t e = DirectShow);
+ virtual ~CMediaFormatCategory();
+
+ void UpdateData(bool fSave);
+
+ CMediaFormatCategory(CMediaFormatCategory& mfc);
+ CMediaFormatCategory& operator = (const CMediaFormatCategory& mfc);
+
+ void RestoreDefaultExts();
+ void SetExts(CAtlList<CString>& exts);
+ void SetExts(CString exts);
+
+ bool FindExt(CString ext) {return m_exts.Find(ext.TrimLeft(_T(".")).MakeLower()) != NULL;}
+
+ CString GetLabel() {return m_label;}
+ CString GetFilter();
+ CString GetExts(bool fAppendEngine = false);
+ CString GetExtsWithPeriod(bool fAppendEngine = false);
+ CString GetBackupExtsWithPeriod(bool fAppendEngine = false);
+ CString GetSpecReqNote() {return m_specreqnote;}
+ bool IsAudioOnly() {return m_fAudioOnly;}
+ engine_t GetEngineType() {return m_engine;}
+ void SetEngineType(engine_t e) {m_engine = e;}
+};
+
+class CMediaFormats : public CArray<CMediaFormatCategory>
+{
+protected:
+ engine_t m_iRtspHandler;
+ bool m_fRtspFileExtFirst;
+
+public:
+ CMediaFormats();
+ virtual ~CMediaFormats();
+
+ void UpdateData(bool fSave);
+
+ engine_t GetRtspHandler(bool& fRtspFileExtFirst);
+ void SetRtspHandler(engine_t e, bool fRtspFileExtFirst);
+
+ bool IsUsingEngine(CString path, engine_t e);
+ engine_t GetEngine(CString path);
+
+ bool FindExt(CString ext, bool fAudioOnly = false);
+
+ void GetFilter(CString& filter, CAtlArray<CString>& mask);
+ void GetAudioFilter(CString& filter, CAtlArray<CString>& mask);
+};
diff --git a/src/apps/mplayerc/MediaTypesDlg.cpp b/src/apps/mplayerc/MediaTypesDlg.cpp
new file mode 100644
index 000000000..aaa4dd969
--- /dev/null
+++ b/src/apps/mplayerc/MediaTypesDlg.cpp
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// MediaTypesDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "MediaTypesDlg.h"
+#include "..\..\DSUtil\DSUtil.h"
+#include "..\..\..\include\moreuuids.h"
+
+#pragma pack(push, 1)
+typedef struct
+{
+ WAVEFORMATEX Format;
+ BYTE bBigEndian;
+ BYTE bsid;
+ BYTE lfeon;
+ BYTE copyrightb;
+ BYTE nAuxBitsCode; // Aux bits per frame
+} DOLBYAC3WAVEFORMAT;
+#pragma pack(pop)
+
+// CMediaTypesDlg dialog
+
+//IMPLEMENT_DYNAMIC(CMediaTypesDlg, CResizableDialog)
+CMediaTypesDlg::CMediaTypesDlg(IGraphBuilderDeadEnd* pGBDE, CWnd* pParent /*=NULL*/)
+ : CResizableDialog(CMediaTypesDlg::IDD, pParent)
+ , m_pGBDE(pGBDE)
+{
+ m_subtype = GUID_NULL;
+ m_type = UNKNOWN;
+}
+
+CMediaTypesDlg::~CMediaTypesDlg()
+{
+}
+
+void CMediaTypesDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CResizableDialog::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_COMBO1, m_pins);
+ DDX_Control(pDX, IDC_EDIT1, m_report);
+}
+
+void CMediaTypesDlg::AddLine(CString str)
+{
+ str.Replace(_T("\n"), _T("\r\n"));
+ int len = m_report.GetWindowTextLength();
+ m_report.SetSel(len, len, TRUE);
+ m_report.ReplaceSel(str);
+}
+
+void CMediaTypesDlg::AddMediaType(AM_MEDIA_TYPE* pmt)
+{
+ CString major = CStringFromGUID(pmt->majortype);
+ CString sub = CStringFromGUID(pmt->subtype);
+ CString format = CStringFromGUID(pmt->formattype);
+
+ m_subtype = pmt->subtype;
+ if(pmt->majortype == MEDIATYPE_Video) m_type = VIDEO;
+ else if(pmt->majortype == MEDIATYPE_Audio) m_type = AUDIO;
+ else m_type = UNKNOWN;
+
+ CString str;
+
+ AddLine(_T("AM_MEDIA_TYPE: (") + CMediaTypeEx(*pmt).ToString() + _T(")\n"));
+ str.Format(_T("majortype: %s %s\n"), CString(GuidNames[pmt->majortype]), major);
+ AddLine(str);
+ str.Format(_T("subtype: %s %s\n"), CString(GuidNames[pmt->subtype]), sub);
+ AddLine(str);
+ str.Format(_T("formattype: %s %s\n"), CString(GuidNames[pmt->formattype]), format);
+ AddLine(str);
+ str.Format(_T("bFixedSizeSamples: %d\n"), pmt->bFixedSizeSamples);
+ AddLine(str);
+ str.Format(_T("bTemporalCompression: %d\n"), pmt->bTemporalCompression);
+ AddLine(str);
+ str.Format(_T("lSampleSize: %d\n"), pmt->lSampleSize);
+ AddLine(str);
+ str.Format(_T("cbFormat: %d\n"), pmt->cbFormat);
+ AddLine(str);
+
+ AddLine();
+
+ if(pmt->formattype == FORMAT_VideoInfo || pmt->formattype == FORMAT_VideoInfo2)
+ {
+ VIDEOINFOHEADER& vih = *((VIDEOINFOHEADER*)pmt->pbFormat);
+ BITMAPINFOHEADER* bih = &vih.bmiHeader;
+
+ AddLine(_T("VIDEOINFOHEADER:\n"));
+ str.Format(_T("rcSource: (%d,%d)-(%d,%d)\n"), vih.rcSource);
+ AddLine(str);
+ str.Format(_T("rcTarget: (%d,%d)-(%d,%d)\n"), vih.rcTarget);
+ AddLine(str);
+ str.Format(_T("dwBitRate: %d\n"), vih.dwBitRate);
+ AddLine(str);
+ str.Format(_T("dwBitErrorRate: %d\n"), vih.dwBitErrorRate);
+ AddLine(str);
+ str.Format(_T("AvgTimePerFrame: %I64d\n"), vih.AvgTimePerFrame);
+ AddLine(str);
+
+ if(pmt->formattype == FORMAT_VideoInfo2)
+ {
+ VIDEOINFOHEADER2& vih = *((VIDEOINFOHEADER2*)pmt->pbFormat);
+ bih = &vih.bmiHeader;
+
+ AddLine(_T("VIDEOINFOHEADER2:\n"));
+ str.Format(_T("dwInterlaceFlags: 0x%08x\n"), vih.dwInterlaceFlags);
+ AddLine(str);
+ str.Format(_T("dwCopyProtectFlags: 0x%08x\n"), vih.dwCopyProtectFlags);
+ AddLine(str);
+ str.Format(_T("dwPictAspectRatioX: %d\n"), vih.dwPictAspectRatioX);
+ AddLine(str);
+ str.Format(_T("dwPictAspectRatioY: %d\n"), vih.dwPictAspectRatioY);
+ AddLine(str);
+ str.Format(_T("dwControlFlags: 0x%08x\n"), vih.dwControlFlags);
+ AddLine(str);
+ str.Format(_T("dwReserved2: 0x%08x\n"), vih.dwReserved2);
+ AddLine(str);
+ }
+
+ AddLine();
+
+ AddLine(_T("BITMAPINFOHEADER:\n"));
+ str.Format(_T("biSize: %d\n"), bih->biSize);
+ AddLine(str);
+ str.Format(_T("biWidth: %d\n"), bih->biWidth);
+ AddLine(str);
+ str.Format(_T("biHeight: %d\n"), bih->biHeight);
+ AddLine(str);
+ str.Format(_T("biPlanes: %d\n"), bih->biPlanes);
+ AddLine(str);
+ str.Format(_T("biBitCount: %d\n"), bih->biBitCount);
+ AddLine(str);
+ if(bih->biCompression < 256) str.Format(_T("biCompression: %d\n"), bih->biCompression);
+ else str.Format(_T("biCompression: %4.4hs\n"), &bih->biCompression);
+ AddLine(str);
+ str.Format(_T("biSizeImage: %d\n"), bih->biSizeImage);
+ AddLine(str);
+ str.Format(_T("biXPelsPerMeter: %d\n"), bih->biXPelsPerMeter);
+ AddLine(str);
+ str.Format(_T("biYPelsPerMeter: %d\n"), bih->biYPelsPerMeter);
+ AddLine(str);
+ str.Format(_T("biYPelsPerMeter: %d\n"), bih->biYPelsPerMeter);
+ AddLine(str);
+ str.Format(_T("biClrUsed: %d\n"), bih->biClrUsed);
+ AddLine(str);
+ str.Format(_T("biClrImportant: %d\n"), bih->biClrImportant);
+ AddLine(str);
+
+ AddLine();
+ }
+ else if(pmt->formattype == FORMAT_WaveFormatEx)
+ {
+ WAVEFORMATEX& wfe = *((WAVEFORMATEX*)pmt->pbFormat);
+
+ AddLine(_T("WAVEFORMATEX:\n"));
+ str.Format(_T("wFormatTag: 0x%04x\n"), wfe.wFormatTag);
+ AddLine(str);
+ str.Format(_T("nChannels: %d\n"), wfe.nChannels);
+ AddLine(str);
+ str.Format(_T("nSamplesPerSec: %d\n"), wfe.nSamplesPerSec);
+ AddLine(str);
+ str.Format(_T("nAvgBytesPerSec: %d\n"), wfe.nAvgBytesPerSec);
+ AddLine(str);
+ str.Format(_T("nBlockAlign: %d\n"), wfe.nBlockAlign);
+ AddLine(str);
+ str.Format(_T("wBitsPerSample: %d\n"), wfe.wBitsPerSample);
+ AddLine(str);
+
+ if(wfe.wFormatTag != WAVE_FORMAT_PCM && wfe.cbSize > 0)
+ {
+ str.Format(_T("cbSize: %d (extra bytes)\n"), wfe.cbSize);
+ AddLine(str);
+
+ if(wfe.wFormatTag == WAVE_FORMAT_EXTENSIBLE && wfe.cbSize == sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX))
+ {
+ WAVEFORMATEXTENSIBLE& wfe = *((WAVEFORMATEXTENSIBLE*)pmt->pbFormat);
+
+ AddLine(_T("WAVEFORMATEXTENSIBLE:\n"));
+ if(wfe.Format.wBitsPerSample != 0) str.Format(_T("wValidBitsPerSample: %d\n"), wfe.Samples.wValidBitsPerSample);
+ else str.Format(_T("wSamplesPerBlock: %d\n"), wfe.Samples.wSamplesPerBlock);
+ AddLine(str);
+ str.Format(_T("dwChannelMask: 0x%08x\n"), wfe.dwChannelMask);
+ AddLine(str);
+ str.Format(_T("SubFormat: %s\n"), CStringFromGUID(wfe.SubFormat));
+ AddLine(str);
+ }
+ else if(wfe.wFormatTag == WAVE_FORMAT_DOLBY_AC3 && wfe.cbSize == sizeof(DOLBYAC3WAVEFORMAT)-sizeof(WAVEFORMATEX))
+ {
+ DOLBYAC3WAVEFORMAT& wfe = *((DOLBYAC3WAVEFORMAT*)pmt->pbFormat);
+
+ AddLine(_T("DOLBYAC3WAVEFORMAT:\n"));
+ str.Format(_T("bBigEndian: %d\n"), wfe.bBigEndian);
+ AddLine(str);
+ str.Format(_T("bsid: %d\n"), wfe.bsid);
+ AddLine(str);
+ str.Format(_T("lfeon: %d\n"), wfe.lfeon);
+ AddLine(str);
+ str.Format(_T("copyrightb: %d\n"), wfe.copyrightb);
+ AddLine(str);
+ str.Format(_T("nAuxBitsCode: %d\n"), wfe.nAuxBitsCode);
+ AddLine(str);
+ }
+ }
+
+ AddLine();
+ }
+
+ if(pmt->cbFormat > 0)
+ {
+ AddLine(_T("pbFormat:\n"));
+
+ for(int i = 0, j = (pmt->cbFormat + 15) & ~15; i < j; i += 16)
+ {
+ str.Format(_T("%08x:"), i);
+ for(int k = i, l = min(i+16, pmt->cbFormat); k < l; k++)
+ {
+ CString byte;
+ byte.Format(_T(" %02x"), pmt->pbFormat[k]);
+ str += byte;
+ }
+ str += '\n';
+ AddLine(str);
+ }
+
+ AddLine();
+ }
+}
+
+BEGIN_MESSAGE_MAP(CMediaTypesDlg, CResizableDialog)
+ ON_CBN_SELCHANGE(IDC_COMBO1, OnCbnSelchangeCombo1)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateButton1)
+END_MESSAGE_MAP()
+
+
+// CMediaTypesDlg message handlers
+
+BOOL CMediaTypesDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ CAtlList<CStringW> path;
+ CAtlList<CMediaType> mts;
+
+ for(int i = 0; S_OK == m_pGBDE->GetDeadEnd(i, path, mts); i++)
+ {
+ if(!path.GetCount()) continue;
+ m_pins.SetItemData(m_pins.AddString(CString(path.GetTail())), (DWORD_PTR)i);
+ }
+
+ m_pins.SetCurSel(0);
+ OnCbnSelchangeCombo1();
+
+ AddAnchor(IDC_STATIC1, TOP_LEFT, TOP_RIGHT);
+ AddAnchor(IDC_STATIC2, TOP_LEFT, TOP_RIGHT);
+ AddAnchor(IDC_COMBO1, TOP_LEFT, TOP_RIGHT);
+ AddAnchor(IDC_EDIT1, TOP_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_BUTTON1, BOTTOM_LEFT);
+ AddAnchor(IDOK, BOTTOM_RIGHT);
+
+ SetMinTrackSize(CSize(300, 200));
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CMediaTypesDlg::OnCbnSelchangeCombo1()
+{
+ m_report.SetWindowText(_T(""));
+
+ int i = m_pins.GetCurSel();
+ if(i < 0) return;
+
+ CAtlList<CStringW> path;
+ CAtlList<CMediaType> mts;
+
+ if(FAILED(m_pGBDE->GetDeadEnd(i, path, mts)) || !path.GetCount())
+ return;
+
+ POSITION pos = path.GetHeadPosition();
+ while(pos)
+ {
+ AddLine(CString(path.GetNext(pos)) + _T("\n"));
+ if(!pos) AddLine(_T("\n"));
+ }
+
+ pos = mts.GetHeadPosition();
+ for(int j = 0; pos; j++)
+ {
+ CString str;
+ str.Format(_T("Media Type %d:\n"), j);
+ AddLine(str);
+ AddLine(_T("--------------------------\n"));
+ AddMediaType(&mts.GetNext(pos));
+ AddLine();
+ }
+
+ m_report.SetSel(0, 0);
+}
+
+void CMediaTypesDlg::OnBnClickedButton1()
+{
+ if(m_subtype.Data2 == 0x0000 && m_subtype.Data3 == 0x0010
+ && *(unsigned __int64*)m_subtype.Data4 == 0x719b3800aa000080i64)
+ {
+ BYTE* p = (BYTE*)&m_subtype.Data1;
+ for(int i = 0; i < 4; i++, p++)
+ if(*p >= 'a' && *p <= 'z') *p -= 0x20;
+ }
+
+ CString str;
+ str.Format(_T("http://gabest.org/codec.php?type=%d&guid=%s"), m_type, CStringFromGUID(m_subtype));
+ ShellExecute(NULL, _T("open"), str, NULL, NULL, SW_SHOW);
+}
+
+void CMediaTypesDlg::OnUpdateButton1(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_subtype != GUID_NULL);
+}
diff --git a/src/apps/mplayerc/MediaTypesDlg.h b/src/apps/mplayerc/MediaTypesDlg.h
new file mode 100644
index 000000000..6d9755c86
--- /dev/null
+++ b/src/apps/mplayerc/MediaTypesDlg.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <afxwin.h>
+#include <atlcoll.h>
+#include "IGraphBuilder2.h"
+
+// CMediaTypesDlg dialog
+
+class CMediaTypesDlg : public CResizableDialog
+{
+// DECLARE_DYNAMIC(CMediaTypesDlg)
+
+private:
+ CComPtr<IGraphBuilderDeadEnd> m_pGBDE;
+ enum {UNKNOWN, VIDEO, AUDIO} m_type;
+ GUID m_subtype;
+ void AddLine(CString str = _T("\n"));
+ void AddMediaType(AM_MEDIA_TYPE* pmt);
+
+public:
+ CMediaTypesDlg(IGraphBuilderDeadEnd* pGBDE, CWnd* pParent = NULL); // standard constructor
+ virtual ~CMediaTypesDlg();
+
+// Dialog Data
+ enum { IDD = IDD_MEDIATYPES_DLG };
+ CComboBox m_pins;
+ CEdit m_report;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+
+ DECLARE_MESSAGE_MAP()
+public:
+ afx_msg void OnCbnSelchangeCombo1();
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnUpdateButton1(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/OpenCapDeviceDlg.cpp b/src/apps/mplayerc/OpenCapDeviceDlg.cpp
new file mode 100644
index 000000000..e4a3b0b60
--- /dev/null
+++ b/src/apps/mplayerc/OpenCapDeviceDlg.cpp
@@ -0,0 +1,448 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// OpenCapDeviceDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "OpenCapDeviceDlg.h"
+#include "..\..\DSUtil\DSUtil.h"
+
+static struct cc_t {long code; AnalogVideoStandard standard; const TCHAR* str;} s_countrycodes[] =
+{
+ {1, AnalogVideo_NTSC_M, _T("USA")},
+/* {1, AnalogVideo_NTSC_M, _T("Anguilla")},
+ {1, AnalogVideo_NTSC_M, _T("Antigua")},
+ {1, AnalogVideo_NTSC_M, _T("Bahamas")},
+ {1, AnalogVideo_NTSC_M, _T("Barbados")},
+ {1, AnalogVideo_NTSC_M, _T("Bermuda")},
+ {1, AnalogVideo_NTSC_M, _T("British Virgin Islands")},
+ {1, AnalogVideo_NTSC_M, _T("Canada")},
+ {1, AnalogVideo_NTSC_M, _T("Cayman Islands")},
+ {1, AnalogVideo_NTSC_M, _T("Dominica")},
+ {1, AnalogVideo_NTSC_M, _T("Dominican Republic")},
+ {1, AnalogVideo_NTSC_M, _T("Grenada")},
+ {1, AnalogVideo_NTSC_M, _T("Jamaica")},
+ {1, AnalogVideo_NTSC_M, _T("Montserrat")},
+ {1, AnalogVideo_NTSC_M, _T("Nevis")},
+ {1, AnalogVideo_NTSC_M, _T("St. Kitts")},
+ {1, AnalogVideo_NTSC_M, _T("St. Vincent and the Grenadines")},
+ {1, AnalogVideo_NTSC_M, _T("Trinidad and Tobago")},
+ {1, AnalogVideo_NTSC_M, _T("Turks and Caicos Islands")},
+ {1, AnalogVideo_NTSC_M, _T("Barbuda")},
+ {1, AnalogVideo_NTSC_M, _T("Puerto Rico")},
+ {1, AnalogVideo_NTSC_M, _T("Saint Lucia")},
+ {1, AnalogVideo_NTSC_M, _T("United States Virgin Islands")},
+*/ {2, AnalogVideo_NTSC_M, _T("Canada")},
+ {7, AnalogVideo_SECAM_D, _T("Russia")},
+/* {7, AnalogVideo_SECAM_D, _T("Kazakhstan")},
+ {7, AnalogVideo_SECAM_D, _T("Kyrgyzstan")},
+ {7, AnalogVideo_SECAM_D, _T("Tajikistan")},
+ {7, AnalogVideo_SECAM_D, _T("Turkmenistan")},
+ {7, AnalogVideo_SECAM_D, _T("Uzbekistan")},
+*/ {20, AnalogVideo_SECAM_B, _T("Egypt")},
+ {27, AnalogVideo_PAL_I, _T("South Africa")},
+ {30, AnalogVideo_SECAM_B, _T("Greece")},
+ {31, AnalogVideo_PAL_B, _T("Netherlands")},
+ {32, AnalogVideo_PAL_B, _T("Belgium")},
+ {33, AnalogVideo_SECAM_L, _T("France")},
+ {34, AnalogVideo_PAL_B, _T("Spain")},
+ {36, AnalogVideo_SECAM_D, _T("Hungary")},
+ {39, AnalogVideo_PAL_B, _T("Italy")},
+ {39, AnalogVideo_PAL_B, _T("Vatican City")},
+ {40, AnalogVideo_PAL_D, _T("Romania")},
+ {41, AnalogVideo_PAL_B, _T("Switzerland")},
+ {41, AnalogVideo_PAL_B, _T("Liechtenstein")},
+ {43, AnalogVideo_PAL_B, _T("Austria")},
+ {44, AnalogVideo_PAL_I, _T("United Kingdom")},
+ {45, AnalogVideo_PAL_B, _T("Denmark")},
+ {46, AnalogVideo_PAL_B, _T("Sweden")},
+ {47, AnalogVideo_PAL_B, _T("Norway")},
+ {48, AnalogVideo_PAL_B, _T("Poland")},
+ {49, AnalogVideo_PAL_B, _T("Germany")},
+ {51, AnalogVideo_NTSC_M, _T("Peru")},
+ {52, AnalogVideo_NTSC_M, _T("Mexico")},
+ {53, AnalogVideo_NTSC_M, _T("Cuba")},
+ {53, AnalogVideo_NTSC_M, _T("Guantanamo Bay")},
+ {54, AnalogVideo_PAL_N, _T("Argentina")},
+ {55, AnalogVideo_PAL_M, _T("Brazil")},
+ {56, AnalogVideo_NTSC_M, _T("Chile")},
+ {57, AnalogVideo_NTSC_M, _T("Colombia")},
+ {58, AnalogVideo_NTSC_M, _T("Bolivarian Republic of Venezuela")},
+ {60, AnalogVideo_PAL_B, _T("Malaysia")},
+ {61, AnalogVideo_PAL_B, _T("Australia")},
+ // {61, AnalogVideo_NTSC_M, _T("Cocos-Keeling Islands")},
+ {62, AnalogVideo_PAL_B, _T("Indonesia")},
+ {63, AnalogVideo_NTSC_M, _T("Philippines")},
+ {64, AnalogVideo_PAL_B, _T("New Zealand")},
+ {65, AnalogVideo_PAL_B, _T("Singapore")},
+ {66, AnalogVideo_PAL_B, _T("Thailand")},
+ {81, AnalogVideo_NTSC_M_J, _T("Japan")},
+ {82, AnalogVideo_NTSC_M, _T("Korea (South)")},
+ {84, AnalogVideo_NTSC_M, _T("Vietnam")},
+ {86, AnalogVideo_PAL_D, _T("China")},
+ {90, AnalogVideo_PAL_B, _T("Turkey")},
+ {91, AnalogVideo_PAL_B, _T("India")},
+ {92, AnalogVideo_PAL_B, _T("Pakistan")},
+ {93, AnalogVideo_PAL_B, _T("Afghanistan")},
+ {94, AnalogVideo_PAL_B, _T("Sri Lanka")},
+ {95, AnalogVideo_NTSC_M, _T("Myanmar")},
+ {98, AnalogVideo_SECAM_B, _T("Iran")},
+ {212, AnalogVideo_SECAM_B, _T("Morocco")},
+ {213, AnalogVideo_PAL_B, _T("Algeria")},
+ {216, AnalogVideo_SECAM_B, _T("Tunisia")},
+ {218, AnalogVideo_SECAM_B, _T("Libya")},
+ {220, AnalogVideo_SECAM_K, _T("Gambia")},
+ {221, AnalogVideo_SECAM_K, _T("Senegal Republic")},
+ {222, AnalogVideo_SECAM_B, _T("Mauritania")},
+ {223, AnalogVideo_SECAM_K, _T("Mali")},
+ {224, AnalogVideo_SECAM_K, _T("Guinea")},
+ {225, AnalogVideo_SECAM_K, _T("Cote D'Ivoire")},
+ {226, AnalogVideo_SECAM_K, _T("Burkina Faso")},
+ {227, AnalogVideo_SECAM_K, _T("Niger")},
+ {228, AnalogVideo_SECAM_K, _T("Togo")},
+ {229, AnalogVideo_SECAM_K, _T("Benin")},
+ {230, AnalogVideo_SECAM_B, _T("Mauritius")},
+ {231, AnalogVideo_PAL_B, _T("Liberia")},
+ {232, AnalogVideo_PAL_B, _T("Sierra Leone")},
+ {233, AnalogVideo_PAL_B, _T("Ghana")},
+ {234, AnalogVideo_PAL_B, _T("Nigeria")},
+ {235, AnalogVideo_PAL_B, _T("Chad")},
+ {236, AnalogVideo_PAL_B, _T("Central African Republic")},
+ {237, AnalogVideo_PAL_B, _T("Cameroon")},
+ {238, AnalogVideo_NTSC_M, _T("Cape Verde Islands")},
+ {239, AnalogVideo_PAL_B, _T("Sao Tome and Principe")},
+ {240, AnalogVideo_SECAM_B, _T("Equatorial Guinea")},
+ {241, AnalogVideo_SECAM_K, _T("Gabon")},
+ {242, AnalogVideo_SECAM_D, _T("Congo")},
+ {243, AnalogVideo_SECAM_K, _T("Congo(DRC)")},
+ {244, AnalogVideo_PAL_I, _T("Angola")},
+ {245, AnalogVideo_NTSC_M, _T("Guinea-Bissau")},
+ {246, AnalogVideo_NTSC_M, _T("Diego Garcia")},
+ {247, AnalogVideo_NTSC_M, _T("Ascension Island")},
+ {248, AnalogVideo_PAL_B, _T("Seychelle Islands")},
+ {249, AnalogVideo_PAL_B, _T("Sudan")},
+ {250, AnalogVideo_PAL_B, _T("Rwanda")},
+ {251, AnalogVideo_PAL_B, _T("Ethiopia")},
+ {252, AnalogVideo_PAL_B, _T("Somalia")},
+ {253, AnalogVideo_SECAM_K, _T("Djibouti")},
+ {254, AnalogVideo_PAL_B, _T("Kenya")},
+ {255, AnalogVideo_PAL_B, _T("Tanzania")},
+ {256, AnalogVideo_PAL_B, _T("Uganda")},
+ {257, AnalogVideo_SECAM_K, _T("Burundi")},
+ {258, AnalogVideo_PAL_B, _T("Mozambique")},
+ {260, AnalogVideo_PAL_B, _T("Zambia")},
+ {261, AnalogVideo_SECAM_K, _T("Madagascar")},
+ {262, AnalogVideo_SECAM_K, _T("Reunion Island")},
+ {263, AnalogVideo_PAL_B, _T("Zimbabwe")},
+ {264, AnalogVideo_PAL_I, _T("Namibia")},
+ {265, AnalogVideo_NTSC_M, _T("Malawi")},
+ {266, AnalogVideo_PAL_I, _T("Lesotho")},
+ {267, AnalogVideo_SECAM_K, _T("Botswana")},
+ {268, AnalogVideo_PAL_B, _T("Swaziland")},
+ {269, AnalogVideo_SECAM_K, _T("Mayotte Island")},
+// {269, AnalogVideo_NTSC_M, _T("Comoros")},
+ {290, AnalogVideo_NTSC_M, _T("St. Helena")},
+ {291, AnalogVideo_NTSC_M, _T("Eritrea")},
+ {297, AnalogVideo_NTSC_M, _T("Aruba")},
+ {298, AnalogVideo_PAL_B, _T("Faroe Islands")},
+ {299, AnalogVideo_NTSC_M, _T("Greenland")},
+ {350, AnalogVideo_PAL_B, _T("Gibraltar")},
+ {351, AnalogVideo_PAL_B, _T("Portugal")},
+ {352, AnalogVideo_PAL_B, _T("Luxembourg")},
+ {353, AnalogVideo_PAL_I, _T("Ireland")},
+ {354, AnalogVideo_PAL_B, _T("Iceland")},
+ {355, AnalogVideo_PAL_B, _T("Albania")},
+ {356, AnalogVideo_PAL_B, _T("Malta")},
+ {357, AnalogVideo_PAL_B, _T("Cyprus")},
+ {358, AnalogVideo_PAL_B, _T("Finland")},
+ {359, AnalogVideo_SECAM_D, _T("Bulgaria")},
+ {370, AnalogVideo_PAL_B, _T("Lithuania")},
+ {371, AnalogVideo_SECAM_D, _T("Latvia")},
+ {372, AnalogVideo_PAL_B, _T("Estonia")},
+ {373, AnalogVideo_SECAM_D, _T("Moldova")},
+ {374, AnalogVideo_SECAM_D, _T("Armenia")},
+ {375, AnalogVideo_SECAM_D, _T("Belarus")},
+ {376, AnalogVideo_NTSC_M, _T("Andorra")},
+ {377, AnalogVideo_SECAM_G, _T("Monaco")},
+ {378, AnalogVideo_PAL_B, _T("San Marino")},
+ {380, AnalogVideo_SECAM_D, _T("Ukraine")},
+ {381, AnalogVideo_PAL_B, _T("Serbia and Montenegro")},
+ {385, AnalogVideo_PAL_B, _T("Croatia")},
+ {386, AnalogVideo_PAL_B, _T("Slovenia")},
+ {387, AnalogVideo_PAL_B, _T("Bosnia and Herzegovina")},
+ {389, AnalogVideo_PAL_B, _T("F.Y.R.O.M. (Former Yugoslav Republic of Macedonia)")},
+ {420, AnalogVideo_PAL_D, _T("Czech Republic")},
+ {421, AnalogVideo_PAL_B, _T("Slovak Republic")},
+ {500, AnalogVideo_PAL_I, _T("Falkland Islands (Islas Malvinas)")},
+ {501, AnalogVideo_NTSC_M, _T("Belize")},
+ {502, AnalogVideo_NTSC_M, _T("Guatemala")},
+ {503, AnalogVideo_NTSC_M, _T("El Salvador")},
+ {504, AnalogVideo_NTSC_M, _T("Honduras")},
+ {505, AnalogVideo_NTSC_M, _T("Nicaragua")},
+ {506, AnalogVideo_NTSC_M, _T("Costa Rica")},
+ {507, AnalogVideo_NTSC_M, _T("Panama")},
+ {508, AnalogVideo_SECAM_K, _T("St. Pierre and Miquelon")},
+ {509, AnalogVideo_NTSC_M, _T("Haiti")},
+ {590, AnalogVideo_SECAM_K, _T("Guadeloupe")},
+// {590, AnalogVideo_NTSC_M, _T("French Antilles")},
+ {591, AnalogVideo_PAL_N, _T("Bolivia")},
+ {592, AnalogVideo_SECAM_K, _T("Guyana")},
+ {593, AnalogVideo_NTSC_M, _T("Ecuador")},
+ {594, AnalogVideo_SECAM_K, _T("French Guiana")},
+ {595, AnalogVideo_PAL_N, _T("Paraguay")},
+ {596, AnalogVideo_SECAM_K, _T("Martinique")},
+ {597, AnalogVideo_NTSC_M, _T("Suriname")},
+ {598, AnalogVideo_PAL_N, _T("Uruguay")},
+ {599, AnalogVideo_NTSC_M, _T("Netherlands Antilles")},
+ {670, AnalogVideo_NTSC_M, _T("Saipan Island")},
+// {670, AnalogVideo_NTSC_M, _T("Rota Island")},
+// {670, AnalogVideo_NTSC_M, _T("Tinian Island")},
+ {671, AnalogVideo_NTSC_M, _T("Guam")},
+ {672, AnalogVideo_NTSC_M, _T("Christmas Island")},
+ {672, AnalogVideo_NTSC_M, _T("Australian Antarctic Territory")},
+ //{672, AnalogVideo_PAL_B, _T("Norfolk Island")},
+ {673, AnalogVideo_PAL_B, _T("Brunei")},
+ {674, AnalogVideo_NTSC_M, _T("Nauru")},
+ {675, AnalogVideo_PAL_B, _T("Papua New Guinea")},
+ {676, AnalogVideo_NTSC_M, _T("Tonga")},
+ {677, AnalogVideo_NTSC_M, _T("Solomon Islands")},
+ {678, AnalogVideo_NTSC_M, _T("Vanuatu")},
+ {679, AnalogVideo_NTSC_M, _T("Fiji Islands")},
+ {680, AnalogVideo_NTSC_M, _T("Palau")},
+ {681, AnalogVideo_SECAM_K, _T("Wallis and Futuna Islands")},
+ {682, AnalogVideo_PAL_B, _T("Cook Islands")},
+ {683, AnalogVideo_NTSC_M, _T("Niue")},
+ {684, AnalogVideo_NTSC_M, _T("Territory of American Samoa")},
+ {685, AnalogVideo_PAL_B, _T("Samoa")},
+ {686, AnalogVideo_PAL_B, _T("Kiribati Republic")},
+ {687, AnalogVideo_SECAM_K, _T("New Caledonia")},
+ {688, AnalogVideo_NTSC_M, _T("Tuvalu")},
+ {689, AnalogVideo_SECAM_K, _T("French Polynesia")},
+ {690, AnalogVideo_NTSC_M, _T("Tokelau")},
+ {691, AnalogVideo_NTSC_M, _T("Micronesia")},
+ {692, AnalogVideo_NTSC_M, _T("Marshall Islands")},
+ {850, AnalogVideo_SECAM_D, _T("Korea (North)")},
+ {852, AnalogVideo_PAL_I, _T("Hong Kong SAR")},
+ {853, AnalogVideo_PAL_I, _T("Macao SAR")},
+ {855, AnalogVideo_PAL_B, _T("Cambodia")},
+ {856, AnalogVideo_PAL_B, _T("Laos")},
+ {871, AnalogVideo_NTSC_M, _T("INMARSAT (Atlantic-East)")},
+ {872, AnalogVideo_NTSC_M, _T("INMARSAT (Pacific)")},
+ {873, AnalogVideo_NTSC_M, _T("INMARSAT (Indian)")},
+ {874, AnalogVideo_NTSC_M, _T("INMARSAT (Atlantic-West)")},
+ {880, AnalogVideo_PAL_B, _T("Bangladesh")},
+ {886, AnalogVideo_NTSC_M, _T("Taiwan")},
+ {960, AnalogVideo_PAL_B, _T("Maldives")},
+ {961, AnalogVideo_SECAM_B, _T("Lebanon")},
+ {962, AnalogVideo_PAL_B, _T("Jordan")},
+ {963, AnalogVideo_SECAM_B, _T("Syria")},
+ {964, AnalogVideo_SECAM_B, _T("Iraq")},
+ {965, AnalogVideo_PAL_B, _T("Kuwait")},
+ {966, AnalogVideo_SECAM_B, _T("Saudi Arabia")},
+ {967, AnalogVideo_PAL_B, _T("Yemen")},
+ {968, AnalogVideo_PAL_B, _T("Oman")},
+ {971, AnalogVideo_PAL_B, _T("United Arab Emirates")},
+ {972, AnalogVideo_PAL_B, _T("Israel")},
+ {973, AnalogVideo_PAL_B, _T("Bahrain")},
+ {974, AnalogVideo_PAL_B, _T("Qatar")},
+ {975, AnalogVideo_NTSC_M, _T("Bhutan")},
+ {976, AnalogVideo_SECAM_D, _T("Mongolia")},
+ {977, AnalogVideo_PAL_B, _T("Nepal")},
+ {994, AnalogVideo_SECAM_D, _T("Azerbaijan")},
+ {995, AnalogVideo_SECAM_D,_T("Georgia")},
+};
+
+// COpenCapDeviceDlg dialog
+
+//IMPLEMENT_DYNAMIC(COpenCapDeviceDlg, CResizableDialog)
+COpenCapDeviceDlg::COpenCapDeviceDlg(CWnd* pParent /*=NULL*/)
+ : CResizableDialog(COpenCapDeviceDlg::IDD, pParent)
+ , m_vidstr(_T(""))
+ , m_audstr(_T(""))
+ , m_country(1)
+{
+}
+
+COpenCapDeviceDlg::~COpenCapDeviceDlg()
+{
+}
+
+void COpenCapDeviceDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_COMBO1, m_vidctrl);
+ DDX_Control(pDX, IDC_COMBO2, m_audctrl);
+ DDX_Control(pDX, IDC_COMBO9, m_countryctrl);
+}
+
+BEGIN_MESSAGE_MAP(COpenCapDeviceDlg, CResizableDialog)
+ ON_BN_CLICKED(IDOK, OnBnClickedOk)
+END_MESSAGE_MAP()
+
+
+// COpenCapDeviceDlg message handlers
+
+BOOL COpenCapDeviceDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AddAnchor(m_vidctrl, TOP_LEFT, TOP_RIGHT);
+ AddAnchor(m_audctrl, TOP_LEFT, TOP_RIGHT);
+ AddAnchor(m_countryctrl, TOP_LEFT, TOP_RIGHT);
+ AddAnchor(IDOK, TOP_CENTER);
+ AddAnchor(IDCANCEL, TOP_CENTER);
+
+ CRect r;
+ GetWindowRect(r);
+ CSize s = r.Size();
+ SetMinTrackSize(s);
+ s.cx = 1000;
+ SetMaxTrackSize(s);
+
+ CString dummy = _T("dummy");
+ CString vidstr = AfxGetApp()->GetProfileString(_T("Capture"), _T("VidDispName"), dummy);
+ CString audstr = AfxGetApp()->GetProfileString(_T("Capture"), _T("AudDispName"), dummy);
+ long country = AfxGetApp()->GetProfileInt(_T("Capture"), _T("Country"), 1);
+
+ int iSel = vidstr == dummy ? 0 : -1;
+
+ BeginEnumSysDev(CLSID_VideoInputDeviceCategory, pMoniker)
+ {
+ CComPtr<IPropertyBag> pPB;
+ pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB);
+
+ CComVariant var;
+ pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL);
+ int i = m_vidctrl.AddString(CString(var.bstrVal));
+
+ LPOLESTR strName = NULL;
+ if(SUCCEEDED(pMoniker->GetDisplayName(NULL, NULL, &strName)))
+ {
+ m_vidnames.Add(CString(strName));
+ if(vidstr == CString(strName)) iSel = i;
+ CoTaskMemFree(strName);
+ }
+ }
+ EndEnumSysDev
+
+ if(m_vidctrl.GetCount())
+ m_vidctrl.SetCurSel(iSel);
+
+ iSel = audstr == dummy ? 0 : -1;
+
+ BeginEnumSysDev(CLSID_AudioInputDeviceCategory, pMoniker)
+ {
+ CComPtr<IPropertyBag> pPB;
+ pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB);
+
+ CComVariant var;
+ pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL);
+ int i = m_audctrl.AddString(CString(var.bstrVal));
+
+ LPOLESTR strName = NULL;
+ if(SUCCEEDED(pMoniker->GetDisplayName(NULL, NULL, &strName)))
+ {
+ m_audnames.Add(CString(strName));
+ if(audstr == CString(strName)) iSel = i;
+ CoTaskMemFree(strName);
+ }
+ }
+ EndEnumSysDev
+
+ {
+ int i = m_audctrl.AddString(_T("<Video Capture Device>"));
+ m_audnames.Add(_T(""));
+ if(audstr.IsEmpty()) iSel = i;
+ }
+
+ if(m_audctrl.GetCount())
+ m_audctrl.SetCurSel(iSel);
+
+ iSel = 0;
+
+ for(int j = 0; j < countof(s_countrycodes); j++)
+ {
+ CString standard;
+ switch(s_countrycodes[j].standard)
+ {
+ case AnalogVideo_NTSC_M: standard = _T("NTSC M"); break;
+ case AnalogVideo_NTSC_M_J: standard = _T("NTSC M J"); break;
+ case AnalogVideo_NTSC_433: standard = _T("NTSC 433"); break;
+ case AnalogVideo_PAL_B: standard = _T("PAL B"); break;
+ case AnalogVideo_PAL_D: standard = _T("PAL D"); break;
+ case AnalogVideo_PAL_G: standard = _T("PAL G"); break;
+ case AnalogVideo_PAL_H: standard = _T("PAL H"); break;
+ case AnalogVideo_PAL_I: standard = _T("PAL I"); break;
+ case AnalogVideo_PAL_M: standard = _T("PAL M"); break;
+ case AnalogVideo_PAL_N: standard = _T("PAL N"); break;
+ case AnalogVideo_PAL_60: standard = _T("PAL 60"); break;
+ case AnalogVideo_SECAM_B: standard = _T("SECAM B"); break;
+ case AnalogVideo_SECAM_D: standard = _T("SECAM D"); break;
+ case AnalogVideo_SECAM_G: standard = _T("SECAM G"); break;
+ case AnalogVideo_SECAM_H: standard = _T("SECAM H"); break;
+ case AnalogVideo_SECAM_K: standard = _T("SECAM K"); break;
+ case AnalogVideo_SECAM_K1: standard = _T("SECAM K1"); break;
+ case AnalogVideo_SECAM_L: standard = _T("SECAM L"); break;
+ case AnalogVideo_SECAM_L1: standard = _T("SECAM L1"); break;
+ case AnalogVideo_PAL_N_COMBO: standard = _T("PAL N COMBO"); break;
+ }
+
+ CString str;
+ str.Format(_T("%d - %s - %s"), s_countrycodes[j].code, s_countrycodes[j].str, standard);
+
+ int i = m_countryctrl.AddString(str);
+ m_countryctrl.SetItemDataPtr(i, &s_countrycodes[j]);
+ if(country == s_countrycodes[j].code) iSel = i;
+ }
+
+ if(m_countryctrl.GetCount())
+ m_countryctrl.SetCurSel(iSel);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void COpenCapDeviceDlg::OnBnClickedOk()
+{
+ UpdateData();
+
+ if(m_vidctrl.GetCurSel() >= 0)
+ {
+ m_vidstr = m_vidnames[m_vidctrl.GetCurSel()];
+ AfxGetApp()->WriteProfileString(_T("Capture"), _T("VidDispName"), m_vidstr);
+ }
+
+ if(m_audctrl.GetCurSel() >= 0)
+ {
+ m_audstr = m_audnames[m_audctrl.GetCurSel()];
+ AfxGetApp()->WriteProfileString(_T("Capture"), _T("AudDispName"), m_audstr);
+ }
+
+ if(m_countryctrl.GetCurSel() >= 0)
+ {
+ m_country = ((cc_t*)m_countryctrl.GetItemDataPtr(m_countryctrl.GetCurSel()))->code;
+ AfxGetApp()->WriteProfileInt(_T("Capture"), _T("Country"), m_country);
+ }
+
+ OnOK();
+}
diff --git a/src/apps/mplayerc/OpenCapDeviceDlg.h b/src/apps/mplayerc/OpenCapDeviceDlg.h
new file mode 100644
index 000000000..f192aec18
--- /dev/null
+++ b/src/apps/mplayerc/OpenCapDeviceDlg.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "afxwin.h"
+#include <atlcoll.h>
+
+// COpenCapDeviceDlg dialog
+
+class COpenCapDeviceDlg : public CResizableDialog
+{
+// DECLARE_DYNAMIC(COpenCapDeviceDlg)
+
+private:
+ CAtlArray<CString> m_vidnames, m_audnames;
+
+public:
+ COpenCapDeviceDlg(CWnd* pParent = NULL); // standard constructor
+ virtual ~COpenCapDeviceDlg();
+
+ CComboBox m_vidctrl;
+ CComboBox m_audctrl;
+ CComboBox m_countryctrl;
+
+ CString m_vidstr, m_audstr;
+ long m_country;
+
+// Dialog Data
+ enum { IDD = IDD_OPENCAPDEVICE_DLG };
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnBnClickedOk();
+};
diff --git a/src/apps/mplayerc/OpenDlg.cpp b/src/apps/mplayerc/OpenDlg.cpp
new file mode 100644
index 000000000..e5e41b2f5
--- /dev/null
+++ b/src/apps/mplayerc/OpenDlg.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// OpenDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "OpenDlg.h"
+#include "OpenFileDlg.h"
+
+// COpenDlg dialog
+
+//IMPLEMENT_DYNAMIC(COpenDlg, CResizableDialog)
+COpenDlg::COpenDlg(CWnd* pParent /*=NULL*/)
+ : CResizableDialog(COpenDlg::IDD, pParent)
+ , m_path(_T(""))
+ , m_path2(_T(""))
+ , m_fMultipleFiles(false)
+ , m_fAppendPlaylist(FALSE)
+{
+}
+
+COpenDlg::~COpenDlg()
+{
+}
+
+void COpenDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_COMBO1, m_mrucombo);
+ DDX_CBString(pDX, IDC_COMBO1, m_path);
+ DDX_Control(pDX, IDC_COMBO2, m_mrucombo2);
+ DDX_CBString(pDX, IDC_COMBO2, m_path2);
+ DDX_Control(pDX, IDC_STATIC1, m_label2);
+ DDX_Check(pDX, IDC_CHECK1, m_fAppendPlaylist);
+}
+
+
+BEGIN_MESSAGE_MAP(COpenDlg, CResizableDialog)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedBrowsebutton)
+ ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedBrowsebutton2)
+ ON_BN_CLICKED(IDOK, OnBnClickedOk)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC1, OnUpdateDub)
+ ON_UPDATE_COMMAND_UI(IDC_COMBO2, OnUpdateDub)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateDub)
+END_MESSAGE_MAP()
+
+
+// COpenDlg message handlers
+
+BOOL COpenDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ CRecentFileList& MRU = AfxGetAppSettings().MRU;
+ MRU.ReadList();
+ m_mrucombo.ResetContent();
+ for(int i = 0; i < MRU.GetSize(); i++)
+ if(!MRU[i].IsEmpty())
+ m_mrucombo.AddString(MRU[i]);
+ CorrectComboListWidth(m_mrucombo, GetFont());
+
+ CRecentFileList& MRUDub = AfxGetAppSettings().MRUDub;
+ MRUDub.ReadList();
+ m_mrucombo2.ResetContent();
+ for(int i = 0; i < MRUDub.GetSize(); i++)
+ if(!MRUDub[i].IsEmpty())
+ m_mrucombo2.AddString(MRUDub[i]);
+ CorrectComboListWidth(m_mrucombo2, GetFont());
+
+ if(m_mrucombo.GetCount() > 0) m_mrucombo.SetCurSel(0);
+
+ AddAnchor(m_mrucombo, TOP_LEFT, TOP_RIGHT);
+ AddAnchor(m_mrucombo2, TOP_LEFT, TOP_RIGHT);
+ AddAnchor(IDC_BUTTON1, TOP_RIGHT);
+ AddAnchor(IDC_BUTTON2, TOP_RIGHT);
+ AddAnchor(IDOK, TOP_RIGHT);
+ AddAnchor(IDCANCEL, TOP_RIGHT);
+ AddAnchor(IDC_STATIC1, TOP_LEFT, TOP_RIGHT);
+
+ CRect r;
+ GetWindowRect(r);
+ CSize s = r.Size();
+ SetMinTrackSize(s);
+ s.cx = 1000;
+ SetMaxTrackSize(s);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+static CString GetFileName(CString str)
+{
+ CPath p = str;
+ p.StripPath();
+ return (LPCTSTR)p;
+}
+
+void COpenDlg::OnBnClickedBrowsebutton()
+{
+ UpdateData();
+
+ CString filter;
+ CAtlArray<CString> mask;
+ AfxGetAppSettings().Formats.GetFilter(filter, mask);
+
+ COpenFileDlg fd(mask, true, NULL, m_path,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT|OFN_ENABLEINCLUDENOTIFY,
+ filter, this);
+ if(fd.DoModal() != IDOK) return;
+
+ m_fns.RemoveAll();
+
+ POSITION pos = fd.GetStartPosition();
+ while(pos)
+ {
+/*
+ CString str = fd.GetNextPathName(pos);
+ POSITION insertpos = m_fns.GetTailPosition();
+ while(insertpos && GetFileName(str).CompareNoCase(GetFileName(m_fns.GetAt(insertpos))) <= 0)
+ m_fns.GetPrev(insertpos);
+ if(!insertpos) m_fns.AddHead(str);
+ else m_fns.InsertAfter(insertpos, str);
+*/
+ m_fns.AddTail(fd.GetNextPathName(pos));
+ }
+
+ if(m_fns.GetCount() > 1
+ || m_fns.GetCount() == 1
+ && (m_fns.GetHead()[m_fns.GetHead().GetLength()-1] == '\\'
+ || m_fns.GetHead()[m_fns.GetHead().GetLength()-1] == '*'))
+ {
+ m_fMultipleFiles = true;
+ EndDialog(IDOK);
+ return;
+ }
+
+ m_mrucombo.SetWindowText(fd.GetPathName());
+}
+
+void COpenDlg::OnBnClickedBrowsebutton2()
+{
+ UpdateData();
+
+ CString filter;
+ CAtlArray<CString> mask;
+ AfxGetAppSettings().Formats.GetAudioFilter(filter, mask);
+
+ COpenFileDlg fd(mask, false, NULL, m_path2,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_ENABLEINCLUDENOTIFY,
+ filter, this);
+
+ if(fd.DoModal() != IDOK) return;
+
+ m_mrucombo2.SetWindowText(fd.GetPathName());
+}
+
+void COpenDlg::OnBnClickedOk()
+{
+ UpdateData();
+
+ m_fns.RemoveAll();
+ m_fns.AddTail(m_path);
+ if(m_mrucombo2.IsWindowEnabled())
+ m_fns.AddTail(m_path2);
+
+ m_fMultipleFiles = false;
+
+ OnOK();
+}
+
+void COpenDlg::OnUpdateDub(CCmdUI* pCmdUI)
+{
+ m_mrucombo.GetWindowText(m_path);
+ pCmdUI->Enable(AfxGetAppSettings().Formats.GetEngine(m_path) == DirectShow);
+}
diff --git a/src/apps/mplayerc/OpenDlg.h b/src/apps/mplayerc/OpenDlg.h
new file mode 100644
index 000000000..53ce30ee5
--- /dev/null
+++ b/src/apps/mplayerc/OpenDlg.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "resource.h"
+
+// COpenDlg dialog
+
+class COpenDlg : public CResizableDialog
+{
+// DECLARE_DYNAMIC(COpenDlg)
+
+public:
+ COpenDlg(CWnd* pParent = NULL); // standard constructor
+ virtual ~COpenDlg();
+
+ bool m_fMultipleFiles;
+ CAtlList<CString> m_fns;
+
+// Dialog Data
+ enum { IDD = IDD_OPEN_DLG };
+ CComboBox m_mrucombo;
+ CString m_path;
+ CComboBox m_mrucombo2;
+ CString m_path2;
+ CStatic m_label2;
+ BOOL m_fAppendPlaylist;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnBnClickedBrowsebutton();
+ afx_msg void OnBnClickedBrowsebutton2();
+ afx_msg void OnBnClickedOk();
+ afx_msg void OnUpdateDub(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/OpenFileDlg.cpp b/src/apps/mplayerc/OpenFileDlg.cpp
new file mode 100644
index 000000000..11d0eb8df
--- /dev/null
+++ b/src/apps/mplayerc/OpenFileDlg.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// OpenFileDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include <shlobj.h>
+#include <dlgs.h>
+#include "OpenFileDlg.h"
+
+#define __DUMMY__ _T("*.*")
+
+bool COpenFileDlg::m_fAllowDirSelection = false;
+WNDPROC COpenFileDlg::m_wndProc = NULL;
+
+// COpenFileDlg
+
+IMPLEMENT_DYNAMIC(COpenFileDlg, CFileDialog)
+COpenFileDlg::COpenFileDlg(CAtlArray<CString>& mask, bool fAllowDirSelection, LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
+ DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd)
+ : CFileDialog(TRUE, lpszDefExt, lpszFileName, dwFlags|OFN_NOVALIDATE, lpszFilter, pParentWnd, 0)
+ , m_mask(mask)
+{
+ m_fAllowDirSelection = fAllowDirSelection;
+ m_pOFN->lpstrInitialDir = lpszFileName;
+
+ m_buff = new TCHAR[10000];
+ m_buff[0] = 0;
+ m_pOFN->lpstrFile = m_buff;
+ m_pOFN->nMaxFile = 10000;
+}
+
+COpenFileDlg::~COpenFileDlg()
+{
+ delete [] m_buff;
+}
+
+BEGIN_MESSAGE_MAP(COpenFileDlg, CFileDialog)
+ ON_WM_DESTROY()
+END_MESSAGE_MAP()
+
+
+// COpenFileDlg message handlers
+
+LRESULT CALLBACK COpenFileDlg::WindowProcNew(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if(message == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK
+ && m_fAllowDirSelection)
+ {
+ CAutoVectorPtr<TCHAR> path;
+ path.Allocate(MAX_PATH+1); // MAX_PATH should be bigger for multiple selection, but we are only interested if it's zero length
+ // note: allocating MAX_PATH only will cause a buffer overrun for too long strings, and will result in a silent app disappearing crash, 100% reproducable
+ if(::GetDlgItemText(hwnd, cmb13, (TCHAR*)path, MAX_PATH) == 0)
+ ::SendMessage(hwnd, CDM_SETCONTROLTEXT, edt1, (LPARAM)__DUMMY__);
+ }
+
+ return CallWindowProc(COpenFileDlg::m_wndProc, hwnd, message, wParam, lParam);
+}
+
+BOOL COpenFileDlg::OnInitDialog()
+{
+ CFileDialog::OnInitDialog();
+
+ m_wndProc = (WNDPROC)SetWindowLong(GetParent()->m_hWnd, GWL_WNDPROC, (LONG)WindowProcNew);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void COpenFileDlg::OnDestroy()
+{
+ int i = GetPathName().Find(__DUMMY__);
+ if(i >= 0) m_pOFN->lpstrFile[i] = m_pOFN->lpstrFile[i+1] = 0;
+
+ CFileDialog::OnDestroy();
+}
+
+BOOL COpenFileDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
+{
+ ASSERT(pResult != NULL);
+
+ OFNOTIFY* pNotify = (OFNOTIFY*)lParam;
+ // allow message map to override
+ if (__super::OnNotify(wParam, lParam, pResult))
+ {
+ ASSERT(pNotify->hdr.code != CDN_INCLUDEITEM);
+ return TRUE;
+ }
+
+ switch(pNotify->hdr.code)
+ {
+ case CDN_INCLUDEITEM:
+ if(OnIncludeItem((OFNOTIFYEX*)lParam, pResult))
+ return TRUE;
+ break;
+ }
+
+ return FALSE; // not handled
+}
+
+BOOL COpenFileDlg::OnIncludeItem(OFNOTIFYEX* pOFNEx, LRESULT* pResult)
+{
+ TCHAR buff[MAX_PATH];
+ if(!SHGetPathFromIDList((LPCITEMIDLIST)pOFNEx->pidl, buff))
+ {
+ STRRET s;
+ HRESULT hr = ((IShellFolder*)pOFNEx->psf)->GetDisplayNameOf((LPCITEMIDLIST)pOFNEx->pidl, SHGDN_NORMAL|SHGDN_FORPARSING, &s);
+ if(S_OK != hr) return FALSE;
+ switch(s.uType)
+ {
+ case STRRET_CSTR: _tcscpy(buff, CString(s.cStr)); break;
+ case STRRET_WSTR: _tcscpy(buff, CString(s.pOleStr)); CoTaskMemFree(s.pOleStr); break;
+ default: return FALSE;
+ }
+ }
+
+ CString fn(buff);
+/*
+ WIN32_FILE_ATTRIBUTE_DATA fad;
+ if(GetFileAttributesEx(fn, GetFileExInfoStandard, &fad)
+ && (fad.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
+ return FALSE;
+*/
+ int i = fn.ReverseFind('.'), j = fn.ReverseFind('\\');
+ if(i < 0 || i < j)
+ return FALSE;
+
+ CString mask = m_mask[pOFNEx->lpOFN->nFilterIndex-1] + _T(";");
+ CString ext = fn.Mid(i).MakeLower() + _T(";");
+
+ *pResult = mask.Find(ext) >= 0 || mask.Find(_T("*.*")) >= 0;
+
+ return TRUE;
+}
diff --git a/src/apps/mplayerc/OpenFileDlg.h b/src/apps/mplayerc/OpenFileDlg.h
new file mode 100644
index 000000000..ba89b6295
--- /dev/null
+++ b/src/apps/mplayerc/OpenFileDlg.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "afxwin.h"
+
+// COpenFileDlg
+
+class COpenFileDlg : public CFileDialog
+{
+ DECLARE_DYNAMIC(COpenFileDlg)
+
+private:
+ TCHAR* m_buff;
+ CAtlArray<CString>& m_mask;
+
+public:
+ COpenFileDlg(CAtlArray<CString>& mask, bool fAllowDirSelection,
+ LPCTSTR lpszDefExt = NULL,
+ LPCTSTR lpszFileName = NULL,
+ DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
+ LPCTSTR lpszFilter = NULL,
+ CWnd* pParentWnd = NULL);
+ virtual ~COpenFileDlg();
+
+ static bool m_fAllowDirSelection;
+ static WNDPROC m_wndProc;
+ static LRESULT CALLBACK WindowProcNew(HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam);
+
+ virtual BOOL OnInitDialog();
+
+protected:
+ DECLARE_MESSAGE_MAP()
+ virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
+ virtual BOOL OnIncludeItem(OFNOTIFYEX* pOFNEx, LRESULT* pResult);
+
+public:
+ afx_msg void OnDestroy();
+};
+
+
diff --git a/src/apps/mplayerc/PPageAccelTbl.cpp b/src/apps/mplayerc/PPageAccelTbl.cpp
new file mode 100644
index 000000000..cb3600e4c
--- /dev/null
+++ b/src/apps/mplayerc/PPageAccelTbl.cpp
@@ -0,0 +1,962 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageAccelTbl.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PPageAccelTbl.h"
+
+// CPPageAccelTbl dialog
+
+IMPLEMENT_DYNAMIC(CPPageAccelTbl, CPPageBase)
+CPPageAccelTbl::CPPageAccelTbl()
+ : CPPageBase(CPPageAccelTbl::IDD, CPPageAccelTbl::IDD)
+ , m_list(0)
+ , m_counter(0)
+ , m_fWinLirc(FALSE)
+ , m_WinLircLink(_T("http://winlirc.sourceforge.net/"))
+ , m_fUIce(FALSE)
+ , m_UIceLink(_T("http://www.mediatexx.com/"))
+{
+}
+
+CPPageAccelTbl::~CPPageAccelTbl()
+{
+}
+
+BOOL CPPageAccelTbl::PreTranslateMessage(MSG* pMsg)
+{
+ if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN
+ && (pMsg->hwnd == m_WinLircEdit.m_hWnd || pMsg->hwnd == m_UIceEdit.m_hWnd))
+ {
+ OnApply();
+ return TRUE;
+ }
+
+ return __super::PreTranslateMessage(pMsg);
+}
+
+
+void CPPageAccelTbl::SetupList()
+{
+ for(int row = 0; row < m_list.GetItemCount(); row++)
+ {
+ wmcmd& wc = m_wmcmds.GetAt((POSITION)m_list.GetItemData(row));
+
+ CString mod = MakeAccelModLabel(wc.fVirt);
+ m_list.SetItemText(row, COL_MOD, mod);
+
+ CString key = MakeAccelVkeyLabel(wc.key, wc.fVirt&FVIRTKEY);
+ m_list.SetItemText(row, COL_KEY, key);
+
+ CString type = (wc.fVirt&FVIRTKEY)?_T("VIRTKEY"):_T("ASCII");
+ m_list.SetItemText(row, COL_TYPE, type);
+
+ CString id;
+ id.Format(_T("%d"), wc.cmd);
+ m_list.SetItemText(row, COL_ID, id);
+
+ m_list.SetItemText(row, COL_MOUSE, MakeMouseButtonLabel(wc.mouse));
+
+ m_list.SetItemText(row, COL_APPCMD, MakeAppCommandLabel(wc.appcmd));
+
+ m_list.SetItemText(row, COL_RMCMD, CString(wc.rmcmd));
+
+ CString repcnt;
+ repcnt.Format(_T("%d"), wc.rmrepcnt);
+ m_list.SetItemText(row, COL_RMREPCNT, repcnt);
+ }
+}
+
+CString CPPageAccelTbl::MakeAccelModLabel(BYTE fVirt)
+{
+ CString str;
+ if(fVirt&FCONTROL) {if(!str.IsEmpty()) str += _T(" + "); str += _T("Ctrl");}
+ if(fVirt&FALT) {if(!str.IsEmpty()) str += _T(" + "); str += _T("Alt");}
+ if(fVirt&FSHIFT) {if(!str.IsEmpty()) str += _T(" + "); str += _T("Shift");}
+ if(str.IsEmpty()) str = _T("None");
+ return(str);
+}
+
+CString CPPageAccelTbl::MakeAccelVkeyLabel(WORD key, bool fVirtKey)
+{
+ CString str;
+
+ if(fVirtKey)
+ switch(key)
+ {
+ case VK_LBUTTON: str = _T("VK_LBUTTON"); break;
+ case VK_RBUTTON: str = _T("VK_RBUTTON"); break;
+ case VK_CANCEL: str = _T("VK_CANCEL"); break;
+ case VK_MBUTTON: str = _T("VK_MBUTTON"); break;
+ case VK_XBUTTON1: str = _T("VK_XBUTTON1"); break;
+ case VK_XBUTTON2: str = _T("VK_XBUTTON2"); break;
+ case VK_BACK: str = _T("VK_BACK"); break;
+ case VK_TAB: str = _T("VK_TAB"); break;
+ case VK_CLEAR: str = _T("VK_CLEAR"); break;
+ case VK_RETURN: str = _T("VK_RETURN"); break;
+ case VK_SHIFT: str = _T("VK_SHIFT"); break;
+ case VK_CONTROL: str = _T("VK_CONTROL"); break;
+ case VK_MENU: str = _T("VK_MENU"); break;
+ case VK_PAUSE: str = _T("VK_PAUSE"); break;
+ case VK_CAPITAL: str = _T("VK_CAPITAL"); break;
+// case VK_KANA: str = _T("VK_KANA"); break;
+// case VK_HANGEUL: str = _T("VK_HANGEUL"); break;
+ case VK_HANGUL: str = _T("VK_HANGUL"); break;
+ case VK_JUNJA: str = _T("VK_JUNJA"); break;
+ case VK_FINAL: str = _T("VK_FINAL"); break;
+// case VK_HANJA: str = _T("VK_HANJA"); break;
+ case VK_KANJI: str = _T("VK_KANJI"); break;
+ case VK_ESCAPE: str = _T("VK_ESCAPE"); break;
+ case VK_CONVERT: str = _T("VK_CONVERT"); break;
+ case VK_NONCONVERT: str = _T("VK_NONCONVERT"); break;
+ case VK_ACCEPT: str = _T("VK_ACCEPT"); break;
+ case VK_MODECHANGE: str = _T("VK_MODECHANGE"); break;
+ case VK_SPACE: str = _T("VK_SPACE"); break;
+ case VK_PRIOR: str = _T("VK_PRIOR"); break;
+ case VK_NEXT: str = _T("VK_NEXT"); break;
+ case VK_END: str = _T("VK_END"); break;
+ case VK_HOME: str = _T("VK_HOME"); break;
+ case VK_LEFT: str = _T("VK_LEFT"); break;
+ case VK_UP: str = _T("VK_UP"); break;
+ case VK_RIGHT: str = _T("VK_RIGHT"); break;
+ case VK_DOWN: str = _T("VK_DOWN"); break;
+ case VK_SELECT: str = _T("VK_SELECT"); break;
+ case VK_PRINT: str = _T("VK_PRINT"); break;
+ case VK_EXECUTE: str = _T("VK_EXECUTE"); break;
+ case VK_SNAPSHOT: str = _T("VK_SNAPSHOT"); break;
+ case VK_INSERT: str = _T("VK_INSERT"); break;
+ case VK_DELETE: str = _T("VK_DELETE"); break;
+ case VK_HELP: str = _T("VK_HELP"); break;
+ case VK_LWIN: str = _T("VK_LWIN"); break;
+ case VK_RWIN: str = _T("VK_RWIN"); break;
+ case VK_APPS: str = _T("VK_APPS"); break;
+ case VK_SLEEP: str = _T("VK_SLEEP"); break;
+ case VK_NUMPAD0: str = _T("VK_NUMPAD0"); break;
+ case VK_NUMPAD1: str = _T("VK_NUMPAD1"); break;
+ case VK_NUMPAD2: str = _T("VK_NUMPAD2"); break;
+ case VK_NUMPAD3: str = _T("VK_NUMPAD3"); break;
+ case VK_NUMPAD4: str = _T("VK_NUMPAD4"); break;
+ case VK_NUMPAD5: str = _T("VK_NUMPAD5"); break;
+ case VK_NUMPAD6: str = _T("VK_NUMPAD6"); break;
+ case VK_NUMPAD7: str = _T("VK_NUMPAD7"); break;
+ case VK_NUMPAD8: str = _T("VK_NUMPAD8"); break;
+ case VK_NUMPAD9: str = _T("VK_NUMPAD9"); break;
+ case VK_MULTIPLY: str = _T("VK_MULTIPLY"); break;
+ case VK_ADD: str = _T("VK_ADD"); break;
+ case VK_SEPARATOR: str = _T("VK_SEPARATOR"); break;
+ case VK_SUBTRACT: str = _T("VK_SUBTRACT"); break;
+ case VK_DECIMAL: str = _T("VK_DECIMAL"); break;
+ case VK_DIVIDE: str = _T("VK_DIVIDE"); break;
+ case VK_F1: str = _T("VK_F1"); break;
+ case VK_F2: str = _T("VK_F2"); break;
+ case VK_F3: str = _T("VK_F3"); break;
+ case VK_F4: str = _T("VK_F4"); break;
+ case VK_F5: str = _T("VK_F5"); break;
+ case VK_F6: str = _T("VK_F6"); break;
+ case VK_F7: str = _T("VK_F7"); break;
+ case VK_F8: str = _T("VK_F8"); break;
+ case VK_F9: str = _T("VK_F9"); break;
+ case VK_F10: str = _T("VK_F10"); break;
+ case VK_F11: str = _T("VK_F11"); break;
+ case VK_F12: str = _T("VK_F12"); break;
+ case VK_F13: str = _T("VK_F13"); break;
+ case VK_F14: str = _T("VK_F14"); break;
+ case VK_F15: str = _T("VK_F15"); break;
+ case VK_F16: str = _T("VK_F16"); break;
+ case VK_F17: str = _T("VK_F17"); break;
+ case VK_F18: str = _T("VK_F18"); break;
+ case VK_F19: str = _T("VK_F19"); break;
+ case VK_F20: str = _T("VK_F20"); break;
+ case VK_F21: str = _T("VK_F21"); break;
+ case VK_F22: str = _T("VK_F22"); break;
+ case VK_F23: str = _T("VK_F23"); break;
+ case VK_F24: str = _T("VK_F24"); break;
+ case VK_NUMLOCK: str = _T("VK_NUMLOCK"); break;
+ case VK_SCROLL: str = _T("VK_SCROLL"); break;
+// case VK_OEM_NEC_EQUAL: str = _T("VK_OEM_NEC_EQUAL"); break;
+ case VK_OEM_FJ_JISHO: str = _T("VK_OEM_FJ_JISHO"); break;
+ case VK_OEM_FJ_MASSHOU: str = _T("VK_OEM_FJ_MASSHOU"); break;
+ case VK_OEM_FJ_TOUROKU: str = _T("VK_OEM_FJ_TOUROKU"); break;
+ case VK_OEM_FJ_LOYA: str = _T("VK_OEM_FJ_LOYA"); break;
+ case VK_OEM_FJ_ROYA: str = _T("VK_OEM_FJ_ROYA"); break;
+ case VK_LSHIFT: str = _T("VK_LSHIFT"); break;
+ case VK_RSHIFT: str = _T("VK_RSHIFT"); break;
+ case VK_LCONTROL: str = _T("VK_LCONTROL"); break;
+ case VK_RCONTROL: str = _T("VK_RCONTROL"); break;
+ case VK_LMENU: str = _T("VK_LMENU"); break;
+ case VK_RMENU: str = _T("VK_RMENU"); break;
+ case VK_BROWSER_BACK: str = _T("VK_BROWSER_BACK"); break;
+ case VK_BROWSER_FORWARD: str = _T("VK_BROWSER_FORWARD"); break;
+ case VK_BROWSER_REFRESH: str = _T("VK_BROWSER_REFRESH"); break;
+ case VK_BROWSER_STOP: str = _T("VK_BROWSER_STOP"); break;
+ case VK_BROWSER_SEARCH: str = _T("VK_BROWSER_SEARCH"); break;
+ case VK_BROWSER_FAVORITES: str = _T("VK_BROWSER_FAVORITES"); break;
+ case VK_BROWSER_HOME: str = _T("VK_BROWSER_HOME"); break;
+ case VK_VOLUME_MUTE: str = _T("VK_VOLUME_MUTE"); break;
+ case VK_VOLUME_DOWN: str = _T("VK_VOLUME_DOWN"); break;
+ case VK_VOLUME_UP: str = _T("VK_VOLUME_UP"); break;
+ case VK_MEDIA_NEXT_TRACK: str = _T("VK_MEDIA_NEXT_TRACK"); break;
+ case VK_MEDIA_PREV_TRACK: str = _T("VK_MEDIA_PREV_TRACK"); break;
+ case VK_MEDIA_STOP: str = _T("VK_MEDIA_STOP"); break;
+ case VK_MEDIA_PLAY_PAUSE: str = _T("VK_MEDIA_PLAY_PAUSE"); break;
+ case VK_LAUNCH_MAIL: str = _T("VK_LAUNCH_MAIL"); break;
+ case VK_LAUNCH_MEDIA_SELECT: str = _T("VK_LAUNCH_MEDIA_SELECT"); break;
+ case VK_LAUNCH_APP1: str = _T("VK_LAUNCH_APP1"); break;
+ case VK_LAUNCH_APP2: str = _T("VK_LAUNCH_APP2"); break;
+ case VK_OEM_1: str = _T("VK_OEM_1"); break;
+ case VK_OEM_PLUS: str = _T("VK_OEM_PLUS"); break;
+ case VK_OEM_COMMA: str = _T("VK_OEM_COMMA"); break;
+ case VK_OEM_MINUS: str = _T("VK_OEM_MINUS"); break;
+ case VK_OEM_PERIOD: str = _T("VK_OEM_PERIOD"); break;
+ case VK_OEM_2: str = _T("VK_OEM_2"); break;
+ case VK_OEM_3: str = _T("VK_OEM_3"); break;
+ case VK_OEM_4: str = _T("VK_OEM_4"); break;
+ case VK_OEM_5: str = _T("VK_OEM_5"); break;
+ case VK_OEM_6: str = _T("VK_OEM_6"); break;
+ case VK_OEM_7: str = _T("VK_OEM_7"); break;
+ case VK_OEM_8: str = _T("VK_OEM_8"); break;
+ case VK_OEM_AX: str = _T("VK_OEM_AX"); break;
+ case VK_OEM_102: str = _T("VK_OEM_102"); break;
+ case VK_ICO_HELP: str = _T("VK_ICO_HELP"); break;
+ case VK_ICO_00: str = _T("VK_ICO_00"); break;
+ case VK_PROCESSKEY: str = _T("VK_PROCESSKEY"); break;
+ case VK_ICO_CLEAR: str = _T("VK_ICO_CLEAR"); break;
+ case VK_PACKET: str = _T("VK_PACKET"); break;
+ case VK_OEM_RESET: str = _T("VK_OEM_RESET"); break;
+ case VK_OEM_JUMP: str = _T("VK_OEM_JUMP"); break;
+ case VK_OEM_PA1: str = _T("VK_OEM_PA1"); break;
+ case VK_OEM_PA2: str = _T("VK_OEM_PA2"); break;
+ case VK_OEM_PA3: str = _T("VK_OEM_PA3"); break;
+ case VK_OEM_WSCTRL: str = _T("VK_OEM_WSCTRL"); break;
+ case VK_OEM_CUSEL: str = _T("VK_OEM_CUSEL"); break;
+ case VK_OEM_ATTN: str = _T("VK_OEM_ATTN"); break;
+ case VK_OEM_FINISH: str = _T("VK_OEM_FINISH"); break;
+ case VK_OEM_COPY: str = _T("VK_OEM_COPY"); break;
+ case VK_OEM_AUTO: str = _T("VK_OEM_AUTO"); break;
+ case VK_OEM_ENLW: str = _T("VK_OEM_ENLW"); break;
+ case VK_OEM_BACKTAB: str = _T("VK_OEM_BACKTAB"); break;
+ case VK_ATTN: str = _T("VK_ATTN"); break;
+ case VK_CRSEL: str = _T("VK_CRSEL"); break;
+ case VK_EXSEL: str = _T("VK_EXSEL"); break;
+ case VK_EREOF: str = _T("VK_EREOF"); break;
+ case VK_PLAY: str = _T("VK_PLAY"); break;
+ case VK_ZOOM: str = _T("VK_ZOOM"); break;
+ case VK_NONAME: str = _T("VK_NONAME"); break;
+ case VK_PA1: str = _T("VK_PA1"); break;
+ case VK_OEM_CLEAR: str = _T("VK_OEM_CLEAR"); break;
+ default:
+ if('0' <= key && key <= '9' || 'A' <= key && key <= 'Z')
+ str.Format(_T("%c"), (TCHAR)key);
+ break;
+ }
+
+ if(str.IsEmpty() || !fVirtKey)
+ {
+ str.Format(_T("%c, 0x%02x"), (TCHAR)key, key);
+ return(str);
+ }
+
+ return(str);
+}
+
+CString CPPageAccelTbl::MakeAccelShortcutLabel(UINT id)
+{
+ CList<wmcmd>& wmcmds = AfxGetAppSettings().wmcmds;
+ POSITION pos = wmcmds.GetHeadPosition();
+ while(pos)
+ {
+ ACCEL& a = wmcmds.GetNext(pos);
+ if(a.cmd == id)
+ return(MakeAccelShortcutLabel(a));
+ }
+
+ return(_T(""));
+}
+
+CString CPPageAccelTbl::MakeAccelShortcutLabel(ACCEL& a)
+{
+ CString str;
+
+ if(a.fVirt&1)
+ switch(a.key)
+ {
+ case VK_LBUTTON: str = _T("LBtn"); break;
+ case VK_RBUTTON: str = _T("RBtn"); break;
+ case VK_CANCEL: str = _T("Cancel"); break;
+ case VK_MBUTTON: str = _T("MBtn"); break;
+ case VK_XBUTTON1: str = _T("X1Btn"); break;
+ case VK_XBUTTON2: str = _T("X2Btn"); break;
+ case VK_BACK: str = _T("Back"); break;
+ case VK_TAB: str = _T("Tab"); break;
+ case VK_CLEAR: str = _T("Clear"); break;
+ case VK_RETURN: str = _T("Return"); break;
+ case VK_SHIFT: str = _T("Shift"); break;
+ case VK_CONTROL: str = _T("Ctrl"); break;
+ case VK_MENU: str = _T("Alt"); break;
+ case VK_PAUSE: str = _T("Pause"); break;
+ case VK_CAPITAL: str = _T("Capital"); break;
+// case VK_KANA: str = _T("Kana"); break;
+// case VK_HANGEUL: str = _T("Hangeul"); break;
+ case VK_HANGUL: str = _T("Hangul"); break;
+ case VK_JUNJA: str = _T("Junja"); break;
+ case VK_FINAL: str = _T("Final"); break;
+// case VK_HANJA: str = _T("Hanja"); break;
+ case VK_KANJI: str = _T("Kanji"); break;
+ case VK_ESCAPE: str = _T("Escape"); break;
+ case VK_CONVERT: str = _T("Convert"); break;
+ case VK_NONCONVERT: str = _T("Non Convert"); break;
+ case VK_ACCEPT: str = _T("Accept"); break;
+ case VK_MODECHANGE: str = _T("Mode Change"); break;
+ case VK_SPACE: str = _T("Space"); break;
+ case VK_PRIOR: str = _T("PgUp"); break;
+ case VK_NEXT: str = _T("PgDn"); break;
+ case VK_END: str = _T("End"); break;
+ case VK_HOME: str = _T("Home"); break;
+ case VK_LEFT: str = _T("Left"); break;
+ case VK_UP: str = _T("Up"); break;
+ case VK_RIGHT: str = _T("Right"); break;
+ case VK_DOWN: str = _T("Down"); break;
+ case VK_SELECT: str = _T("Select"); break;
+ case VK_PRINT: str = _T("Print"); break;
+ case VK_EXECUTE: str = _T("Execute"); break;
+ case VK_SNAPSHOT: str = _T("Snapshot"); break;
+ case VK_INSERT: str = _T("Insert"); break;
+ case VK_DELETE: str = _T("Delete"); break;
+ case VK_HELP: str = _T("Help"); break;
+ case VK_LWIN: str = _T("LWin"); break;
+ case VK_RWIN: str = _T("RWin"); break;
+ case VK_APPS: str = _T("Apps"); break;
+ case VK_SLEEP: str = _T("Sleep"); break;
+ case VK_NUMPAD0: str = _T("Numpad 0"); break;
+ case VK_NUMPAD1: str = _T("Numpad 1"); break;
+ case VK_NUMPAD2: str = _T("Numpad 2"); break;
+ case VK_NUMPAD3: str = _T("Numpad 3"); break;
+ case VK_NUMPAD4: str = _T("Numpad 4"); break;
+ case VK_NUMPAD5: str = _T("Numpad 5"); break;
+ case VK_NUMPAD6: str = _T("Numpad 6"); break;
+ case VK_NUMPAD7: str = _T("Numpad 7"); break;
+ case VK_NUMPAD8: str = _T("Numpad 8"); break;
+ case VK_NUMPAD9: str = _T("Numpad 9"); break;
+ case VK_MULTIPLY: str = _T("Multiply"); break;
+ case VK_ADD: str = _T("Add"); break;
+ case VK_SEPARATOR: str = _T("Separator"); break;
+ case VK_SUBTRACT: str = _T("Subtract"); break;
+ case VK_DECIMAL: str = _T("Decimal"); break;
+ case VK_DIVIDE: str = _T("Divide"); break;
+ case VK_F1: str = _T("F1"); break;
+ case VK_F2: str = _T("F2"); break;
+ case VK_F3: str = _T("F3"); break;
+ case VK_F4: str = _T("F4"); break;
+ case VK_F5: str = _T("F5"); break;
+ case VK_F6: str = _T("F6"); break;
+ case VK_F7: str = _T("F7"); break;
+ case VK_F8: str = _T("F8"); break;
+ case VK_F9: str = _T("F9"); break;
+ case VK_F10: str = _T("F10"); break;
+ case VK_F11: str = _T("F11"); break;
+ case VK_F12: str = _T("F12"); break;
+ case VK_F13: str = _T("F13"); break;
+ case VK_F14: str = _T("F14"); break;
+ case VK_F15: str = _T("F15"); break;
+ case VK_F16: str = _T("F16"); break;
+ case VK_F17: str = _T("F17"); break;
+ case VK_F18: str = _T("F18"); break;
+ case VK_F19: str = _T("F19"); break;
+ case VK_F20: str = _T("F20"); break;
+ case VK_F21: str = _T("F21"); break;
+ case VK_F22: str = _T("F22"); break;
+ case VK_F23: str = _T("F23"); break;
+ case VK_F24: str = _T("F24"); break;
+ case VK_NUMLOCK: str = _T("Numlock"); break;
+ case VK_SCROLL: str = _T("Scroll"); break;
+// case VK_OEM_NEC_EQUAL: str = _T("OEM NEC Equal"); break;
+ case VK_OEM_FJ_JISHO: str = _T("OEM FJ Jisho"); break;
+ case VK_OEM_FJ_MASSHOU: str = _T("OEM FJ Msshou"); break;
+ case VK_OEM_FJ_TOUROKU: str = _T("OEM FJ Touroku"); break;
+ case VK_OEM_FJ_LOYA: str = _T("OEM FJ Loya"); break;
+ case VK_OEM_FJ_ROYA: str = _T("OEM FJ Roya"); break;
+ case VK_LSHIFT: str = _T("LShift"); break;
+ case VK_RSHIFT: str = _T("RShift"); break;
+ case VK_LCONTROL: str = _T("LCtrl"); break;
+ case VK_RCONTROL: str = _T("RCtrl"); break;
+ case VK_LMENU: str = _T("LAlt"); break;
+ case VK_RMENU: str = _T("RAlt"); break;
+ case VK_BROWSER_BACK: str = _T("Browser Back"); break;
+ case VK_BROWSER_FORWARD: str = _T("Browser Forward"); break;
+ case VK_BROWSER_REFRESH: str = _T("Browser Refresh"); break;
+ case VK_BROWSER_STOP: str = _T("Browser Stop"); break;
+ case VK_BROWSER_SEARCH: str = _T("Browser Search"); break;
+ case VK_BROWSER_FAVORITES: str = _T("Browser Favorites"); break;
+ case VK_BROWSER_HOME: str = _T("Browser Home"); break;
+ case VK_VOLUME_MUTE: str = _T("Volume Mute"); break;
+ case VK_VOLUME_DOWN: str = _T("Volume Down"); break;
+ case VK_VOLUME_UP: str = _T("Volume Up"); break;
+ case VK_MEDIA_NEXT_TRACK: str = _T("Media Next Track"); break;
+ case VK_MEDIA_PREV_TRACK: str = _T("Media Prev Track"); break;
+ case VK_MEDIA_STOP: str = _T("Media Stop"); break;
+ case VK_MEDIA_PLAY_PAUSE: str = _T("Media Play/Pause"); break;
+ case VK_LAUNCH_MAIL: str = _T("Launch Mail"); break;
+ case VK_LAUNCH_MEDIA_SELECT: str = _T("Launch Media Select"); break;
+ case VK_LAUNCH_APP1: str = _T("Launch App1"); break;
+ case VK_LAUNCH_APP2: str = _T("Launch App2"); break;
+ case VK_OEM_1: str = _T("OEM 1"); break;
+ case VK_OEM_PLUS: str = _T("Plus"); break;
+ case VK_OEM_COMMA: str = _T("Comma"); break;
+ case VK_OEM_MINUS: str = _T("Minus"); break;
+ case VK_OEM_PERIOD: str = _T("Period"); break;
+ case VK_OEM_2: str = _T("OEM 2"); break;
+ case VK_OEM_3: str = _T("OEM 3"); break;
+ case VK_OEM_4: str = _T("OEM 4"); break;
+ case VK_OEM_5: str = _T("OEM 5"); break;
+ case VK_OEM_6: str = _T("OEM 6"); break;
+ case VK_OEM_7: str = _T("OEM 7"); break;
+ case VK_OEM_8: str = _T("OEM 8"); break;
+ case VK_OEM_AX: str = _T("OEM AX"); break;
+ case VK_OEM_102: str = _T("OEM 102"); break;
+ case VK_ICO_HELP: str = _T("ICO Help"); break;
+ case VK_ICO_00: str = _T("ICO 00"); break;
+ case VK_PROCESSKEY: str = _T("Process Key"); break;
+ case VK_ICO_CLEAR: str = _T("ICO Clear"); break;
+ case VK_PACKET: str = _T("Packet"); break;
+ case VK_OEM_RESET: str = _T("OEM Reset"); break;
+ case VK_OEM_JUMP: str = _T("OEM Jump"); break;
+ case VK_OEM_PA1: str = _T("OEM PA1"); break;
+ case VK_OEM_PA2: str = _T("OEM PA2"); break;
+ case VK_OEM_PA3: str = _T("OEM PA3"); break;
+ case VK_OEM_WSCTRL: str = _T("OEM WSCtrl"); break;
+ case VK_OEM_CUSEL: str = _T("OEM CUSEL"); break;
+ case VK_OEM_ATTN: str = _T("OEM ATTN"); break;
+ case VK_OEM_FINISH: str = _T("OEM Finish"); break;
+ case VK_OEM_COPY: str = _T("OEM Copy"); break;
+ case VK_OEM_AUTO: str = _T("OEM Auto"); break;
+ case VK_OEM_ENLW: str = _T("OEM ENLW"); break;
+ case VK_OEM_BACKTAB: str = _T("OEM Backtab"); break;
+ case VK_ATTN: str = _T("ATTN"); break;
+ case VK_CRSEL: str = _T("CRSEL"); break;
+ case VK_EXSEL: str = _T("EXSEL"); break;
+ case VK_EREOF: str = _T("EREOF"); break;
+ case VK_PLAY: str = _T("Play"); break;
+ case VK_ZOOM: str = _T("Zoom"); break;
+ case VK_NONAME: str = _T("Noname"); break;
+ case VK_PA1: str = _T("PA1"); break;
+ case VK_OEM_CLEAR: str = _T("OEM Clear"); break;
+ default:
+ if('0' <= a.key && a.key <= '9' || 'A' <= a.key && a.key <= 'Z')
+ str.Format(_T("%c"), (TCHAR)a.key);
+ break;
+ }
+
+ if(str.IsEmpty() || !(a.fVirt&1))
+ str.Format(_T("%c"), (TCHAR)a.key);
+
+ if(a.fVirt&(FCONTROL|FALT|FSHIFT))
+ str = MakeAccelModLabel(a.fVirt) + _T(" + ") + str;
+
+ str.Replace(_T(" + "), _T("+"));
+
+ return(str);
+}
+
+CString CPPageAccelTbl::MakeMouseButtonLabel(UINT mouse)
+{
+ CString ret;
+ switch(mouse)
+ {
+ case wmcmd::NONE: default: ret = _T("None"); break;
+ case wmcmd::LDOWN: ret = _T("Left Down"); break;
+ case wmcmd::LUP: ret = _T("Left Up"); break;
+ case wmcmd::LDBLCLK: ret = _T("Left DblClk"); break;
+ case wmcmd::MDOWN: ret = _T("Middle Down"); break;
+ case wmcmd::MUP: ret = _T("Middle Up"); break;
+ case wmcmd::MDBLCLK: ret = _T("Middle DblClk"); break;
+ case wmcmd::RDOWN: ret = _T("Right Down"); break;
+ case wmcmd::RUP: ret = _T("Right Up"); break;
+ case wmcmd::RDBLCLK: ret = _T("Right DblClk"); break;
+ case wmcmd::X1DOWN: ret = _T("X1 Down"); break;
+ case wmcmd::X1UP: ret = _T("X1 Up"); break;
+ case wmcmd::X1DBLCLK: ret = _T("X1 DblClk"); break;
+ case wmcmd::X2DOWN: ret = _T("X2 Down"); break;
+ case wmcmd::X2UP: ret = _T("X2 Up"); break;
+ case wmcmd::X2DBLCLK: ret = _T("X2 DblClk"); break;
+ case wmcmd::WUP: ret = _T("Wheel Up"); break;
+ case wmcmd::WDOWN: ret = _T("Wheel Down"); break;
+ }
+ return ret;
+}
+
+CString CPPageAccelTbl::MakeAppCommandLabel(UINT id)
+{
+ CString str;
+
+ ASSERT(id <= APPCOMMAND_LAST);
+
+ switch(id)
+ {
+ default: str = _T(""); break;
+ case APPCOMMAND_BROWSER_BACKWARD: str = _T("BROWSER_BACKWARD"); break;
+ case APPCOMMAND_BROWSER_FORWARD: str = _T("BROWSER_FORWARD"); break;
+ case APPCOMMAND_BROWSER_REFRESH: str = _T("BROWSER_REFRESH"); break;
+ case APPCOMMAND_BROWSER_STOP: str = _T("BROWSER_STOP"); break;
+ case APPCOMMAND_BROWSER_SEARCH: str = _T("BROWSER_SEARCH"); break;
+ case APPCOMMAND_BROWSER_FAVORITES: str = _T("BROWSER_FAVORITES"); break;
+ case APPCOMMAND_BROWSER_HOME: str = _T("BROWSER_HOME"); break;
+ case APPCOMMAND_VOLUME_MUTE: str = _T("VOLUME_MUTE"); break;
+ case APPCOMMAND_VOLUME_DOWN: str = _T("VOLUME_DOWN"); break;
+ case APPCOMMAND_VOLUME_UP: str = _T("VOLUME_UP"); break;
+ case APPCOMMAND_MEDIA_NEXTTRACK: str = _T("MEDIA_NEXTTRACK"); break;
+ case APPCOMMAND_MEDIA_PREVIOUSTRACK: str = _T("MEDIA_PREVIOUSTRACK"); break;
+ case APPCOMMAND_MEDIA_STOP: str = _T("MEDIA_STOP"); break;
+ case APPCOMMAND_MEDIA_PLAY_PAUSE: str = _T("MEDIA_PLAY_PAUSE"); break;
+ case APPCOMMAND_LAUNCH_MAIL: str = _T("LAUNCH_MAIL"); break;
+ case APPCOMMAND_LAUNCH_MEDIA_SELECT: str = _T("LAUNCH_MEDIA_SELECT"); break;
+ case APPCOMMAND_LAUNCH_APP1: str = _T("LAUNCH_APP1"); break;
+ case APPCOMMAND_LAUNCH_APP2: str = _T("LAUNCH_APP2"); break;
+ case APPCOMMAND_BASS_DOWN: str = _T("BASS_DOWN"); break;
+ case APPCOMMAND_BASS_BOOST: str = _T("BASS_BOOST"); break;
+ case APPCOMMAND_BASS_UP: str = _T("BASS_UP"); break;
+ case APPCOMMAND_TREBLE_DOWN: str = _T("TREBLE_DOWN"); break;
+ case APPCOMMAND_TREBLE_UP: str = _T("TREBLE_UP"); break;
+ case APPCOMMAND_MICROPHONE_VOLUME_MUTE: str = _T("MICROPHONE_VOLUME_MUTE"); break;
+ case APPCOMMAND_MICROPHONE_VOLUME_DOWN: str = _T("MICROPHONE_VOLUME_DOWN"); break;
+ case APPCOMMAND_MICROPHONE_VOLUME_UP: str = _T("MICROPHONE_VOLUME_UP"); break;
+ case APPCOMMAND_HELP: str = _T("HELP"); break;
+ case APPCOMMAND_FIND: str = _T("FIND"); break;
+ case APPCOMMAND_NEW: str = _T("NEW"); break;
+ case APPCOMMAND_OPEN: str = _T("OPEN"); break;
+ case APPCOMMAND_CLOSE: str = _T("CLOSE"); break;
+ case APPCOMMAND_SAVE: str = _T("SAVE"); break;
+ case APPCOMMAND_PRINT: str = _T("PRINT"); break;
+ case APPCOMMAND_UNDO: str = _T("UNDO"); break;
+ case APPCOMMAND_REDO: str = _T("REDO"); break;
+ case APPCOMMAND_COPY: str = _T("COPY"); break;
+ case APPCOMMAND_CUT: str = _T("CUT"); break;
+ case APPCOMMAND_PASTE: str = _T("PASTE"); break;
+ case APPCOMMAND_REPLY_TO_MAIL: str = _T("REPLY_TO_MAIL"); break;
+ case APPCOMMAND_FORWARD_MAIL: str = _T("FORWARD_MAIL"); break;
+ case APPCOMMAND_SEND_MAIL: str = _T("SEND_MAIL"); break;
+ case APPCOMMAND_SPELL_CHECK: str = _T("SPELL_CHECK"); break;
+ case APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE: str = _T("DICTATE_OR_COMMAND_CONTROL_TOGGLE"); break;
+ case APPCOMMAND_MIC_ON_OFF_TOGGLE: str = _T("MIC_ON_OFF_TOGGLE"); break;
+ case APPCOMMAND_CORRECTION_LIST: str = _T("CORRECTION_LIST"); break;
+ case APPCOMMAND_MEDIA_PLAY: str = _T("MEDIA_PLAY"); break;
+ case APPCOMMAND_MEDIA_PAUSE: str = _T("MEDIA_PAUSE"); break;
+ case APPCOMMAND_MEDIA_RECORD: str = _T("MEDIA_RECORD"); break;
+ case APPCOMMAND_MEDIA_FAST_FORWARD: str = _T("MEDIA_FAST_FORWARD"); break;
+ case APPCOMMAND_MEDIA_REWIND: str = _T("MEDIA_REWIND"); break;
+ case APPCOMMAND_MEDIA_CHANNEL_UP: str = _T("MEDIA_CHANNEL_UP"); break;
+ case APPCOMMAND_MEDIA_CHANNEL_DOWN: str = _T("MEDIA_CHANNEL_DOWN"); break;
+ }
+
+ return str;
+}
+void CPPageAccelTbl::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Text(pDX, IDC_EDIT1, m_WinLircAddr);
+ DDX_Control(pDX, IDC_EDIT1, m_WinLircEdit);
+ DDX_Control(pDX, IDC_STATICLINK, m_WinLircLink);
+ DDX_Check(pDX, IDC_CHECK1, m_fWinLirc);
+ DDX_Text(pDX, IDC_EDIT2, m_UIceAddr);
+ DDX_Control(pDX, IDC_EDIT2, m_UIceEdit);
+ DDX_Control(pDX, IDC_STATICLINK2, m_UIceLink);
+ DDX_Check(pDX, IDC_CHECK9, m_fUIce);
+}
+
+BEGIN_MESSAGE_MAP(CPPageAccelTbl, CPPageBase)
+ ON_NOTIFY(LVN_BEGINLABELEDIT, IDC_LIST1, OnBeginlabeleditList)
+ ON_NOTIFY(LVN_DOLABELEDIT, IDC_LIST1, OnDolabeleditList)
+ ON_NOTIFY(LVN_ENDLABELEDIT, IDC_LIST1, OnEndlabeleditList)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+ ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
+ ON_WM_TIMER()
+ ON_WM_CTLCOLOR()
+END_MESSAGE_MAP()
+
+// CPPageAccelTbl message handlers
+
+BOOL CPPageAccelTbl::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_wmcmds.RemoveAll();
+ m_wmcmds.AddTail(&s.wmcmds);
+ m_fWinLirc = s.fWinLirc;
+ m_WinLircAddr = s.WinLircAddr;
+ m_fUIce = s.fUIce;
+ m_UIceAddr = s.UIceAddr;
+
+ UpdateData(FALSE);
+
+ CRect r;
+ GetDlgItem(IDC_PLACEHOLDER)->GetWindowRect(r);
+ ScreenToClient(r);
+
+ m_list.CreateEx(
+ WS_EX_CLIENTEDGE,
+ WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_TABSTOP|LVS_REPORT|LVS_AUTOARRANGE|LVS_SHOWSELALWAYS,
+ r, this, IDC_LIST1);
+
+ m_list.SetExtendedStyle(m_list.GetExtendedStyle()|LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER);
+
+ for(int i = 0, j = m_list.GetHeaderCtrl()->GetItemCount(); i < j; i++) m_list.DeleteColumn(0);
+ m_list.InsertColumn(COL_CMD, _T("Command"), LVCFMT_LEFT, 80);
+ m_list.InsertColumn(COL_MOD, _T("Modifier"), LVCFMT_LEFT, 40);
+ m_list.InsertColumn(COL_KEY, _T("Key"), LVCFMT_LEFT, 40);
+ m_list.InsertColumn(COL_TYPE, _T("Type"), LVCFMT_LEFT, 40);
+ m_list.InsertColumn(COL_ID, _T("ID"), LVCFMT_LEFT, 40);
+ m_list.InsertColumn(COL_MOUSE, _T("Mouse"), LVCFMT_LEFT, 80);
+ m_list.InsertColumn(COL_APPCMD, _T("App Command"), LVCFMT_LEFT, 120);
+ m_list.InsertColumn(COL_RMCMD, _T("RemoteCmd"), LVCFMT_LEFT, 80);
+ m_list.InsertColumn(COL_RMREPCNT, _T("RepCnt"), LVCFMT_CENTER, 60);
+
+ POSITION pos = m_wmcmds.GetHeadPosition();
+ for(int i = 0; pos; i++)
+ {
+ int row = m_list.InsertItem(m_list.GetItemCount(), m_wmcmds.GetAt(pos).name, COL_CMD);
+ m_list.SetItemData(row, (DWORD_PTR)pos);
+ m_wmcmds.GetNext(pos);
+ }
+
+ SetupList();
+
+ m_list.SetColumnWidth(COL_CMD, LVSCW_AUTOSIZE);
+ m_list.SetColumnWidth(COL_MOD, LVSCW_AUTOSIZE);
+ m_list.SetColumnWidth(COL_KEY, LVSCW_AUTOSIZE);
+ m_list.SetColumnWidth(COL_TYPE, LVSCW_AUTOSIZE);
+ m_list.SetColumnWidth(COL_ID, LVSCW_AUTOSIZE_USEHEADER);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageAccelTbl::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ s.wmcmds.RemoveAll();
+ s.wmcmds.AddTail(&m_wmcmds);
+
+ CAtlArray<ACCEL> pAccel;
+ pAccel.SetCount(m_wmcmds.GetCount());
+ POSITION pos = m_wmcmds.GetHeadPosition();
+ for(int i = 0; pos; i++) pAccel[i] = m_wmcmds.GetNext(pos);
+ if(s.hAccel) DestroyAcceleratorTable(s.hAccel);
+ s.hAccel = CreateAcceleratorTable(pAccel.GetData(), pAccel.GetCount());
+
+ GetParentFrame()->m_hAccelTable = s.hAccel;
+
+ s.fWinLirc = !!m_fWinLirc;
+ s.WinLircAddr = m_WinLircAddr;
+ if(s.fWinLirc) s.WinLircClient.Connect(m_WinLircAddr);
+ s.fUIce = !!m_fUIce;
+ s.UIceAddr = m_UIceAddr;
+ if(s.fUIce) s.UIceClient.Connect(m_UIceAddr);
+
+ return __super::OnApply();
+}
+
+void CPPageAccelTbl::OnBnClickedButton1()
+{
+ m_list.SetFocus();
+
+ for(int i = 0, j = m_list.GetItemCount(); i < j; i++)
+ {
+ m_list.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
+ }
+}
+
+void CPPageAccelTbl::OnBnClickedButton2()
+{
+ m_list.SetFocus();
+
+ POSITION pos = m_list.GetFirstSelectedItemPosition();
+ if(!pos) return;
+
+ AppSettings& s = AfxGetAppSettings();
+
+ while(pos)
+ {
+ wmcmd& wc = m_wmcmds.GetAt((POSITION)m_list.GetItemData(m_list.GetNextSelectedItem(pos)));
+ wc.Restore();
+ }
+
+ SetupList();
+
+ SetModified();
+}
+
+void CPPageAccelTbl::OnBeginlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
+ LV_ITEM* pItem = &pDispInfo->item;
+
+ *pResult = FALSE;
+
+ if(pItem->iItem < 0)
+ return;
+
+ if(pItem->iSubItem == COL_MOD || pItem->iSubItem == COL_KEY || pItem->iSubItem == COL_TYPE
+ || pItem->iSubItem == COL_MOUSE || pItem->iSubItem == COL_APPCMD
+ || pItem->iSubItem == COL_RMCMD || pItem->iSubItem == COL_RMREPCNT)
+ {
+ *pResult = TRUE;
+ }
+}
+
+static BYTE s_mods[] = {0,FALT,FCONTROL,FSHIFT,FCONTROL|FALT,FCONTROL|FSHIFT,FALT|FSHIFT,FCONTROL|FALT|FSHIFT};
+
+void CPPageAccelTbl::OnDolabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
+ LV_ITEM* pItem = &pDispInfo->item;
+
+ *pResult = FALSE;
+
+ if(pItem->iItem < 0)
+ return;
+
+ wmcmd& wc = m_wmcmds.GetAt((POSITION)m_list.GetItemData(pItem->iItem));
+ ACCEL& a = wc;
+
+ CAtlList<CString> sl;
+ int nSel = -1;
+
+ if(pItem->iSubItem == COL_MOD)
+ {
+ for(int i = 0; i < countof(s_mods); i++)
+ {
+ sl.AddTail(MakeAccelModLabel(s_mods[i]));
+ if((a.fVirt&~3) == s_mods[i]) nSel = i;
+ }
+
+ m_list.ShowInPlaceComboBox(pItem->iItem, pItem->iSubItem, sl, nSel);
+
+ *pResult = TRUE;
+ }
+ else if(pItem->iSubItem == COL_KEY)
+ {
+ for(int i = 0; i < 256; i++)
+ {
+ sl.AddTail(MakeAccelVkeyLabel(i, a.fVirt&FVIRTKEY));
+ if(a.key == i) nSel = i;
+ }
+
+ m_list.ShowInPlaceComboBox(pItem->iItem, pItem->iSubItem, sl, nSel);
+
+ *pResult = TRUE;
+ }
+ else if(pItem->iSubItem == COL_TYPE)
+ {
+ sl.AddTail(_T("VIRTKEY"));
+ sl.AddTail(_T("ASCII"));
+
+ nSel = !(a.fVirt&FVIRTKEY);
+
+ m_list.ShowInPlaceComboBox(pItem->iItem, pItem->iSubItem, sl, nSel);
+
+ *pResult = TRUE;
+ }
+ else if(pItem->iSubItem == COL_MOUSE)
+ {
+ for(UINT i = 0; i < wmcmd::LAST; i++)
+ {
+ sl.AddTail(MakeMouseButtonLabel(i));
+ if(wc.mouse == i) nSel = i;
+ }
+
+ m_list.ShowInPlaceComboBox(pItem->iItem, pItem->iSubItem, sl, nSel);
+
+ *pResult = TRUE;
+ }
+ else if(pItem->iSubItem == COL_APPCMD)
+ {
+ for(int i = 0; i <= APPCOMMAND_LAST; i++)
+ {
+ sl.AddTail(MakeAppCommandLabel(i));
+ if(wc.appcmd == i) nSel = i;
+ }
+
+ m_list.ShowInPlaceComboBox(pItem->iItem, pItem->iSubItem, sl, nSel);
+
+ *pResult = TRUE;
+ }
+ else if(pItem->iSubItem == COL_RMCMD)
+ {
+ m_list.ShowInPlaceEdit(pItem->iItem, pItem->iSubItem);
+
+ *pResult = TRUE;
+ }
+ else if(pItem->iSubItem == COL_RMREPCNT)
+ {
+ m_list.ShowInPlaceEdit(pItem->iItem, pItem->iSubItem);
+
+ *pResult = TRUE;
+ }
+}
+
+void CPPageAccelTbl::OnEndlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
+ LV_ITEM* pItem = &pDispInfo->item;
+
+ *pResult = FALSE;
+
+ if(!m_list.m_fInPlaceDirty)
+ return;
+
+ if(pItem->iItem < 0)
+ return;
+
+ wmcmd& wc = m_wmcmds.GetAt((POSITION)m_list.GetItemData(pItem->iItem));
+
+ if(pItem->iSubItem == COL_MOD)
+ {
+ if(pItem->lParam >= 0 && pItem->lParam < countof(s_mods))
+ {
+ wc.fVirt = (wc.fVirt&3) | (s_mods[pItem->lParam]&~3);
+ m_list.SetItemText(pItem->iItem, COL_MOD, pItem->pszText);
+ *pResult = TRUE;
+ }
+ }
+ else if(pItem->iSubItem == COL_KEY)
+ {
+ int i = pItem->lParam;
+ if(i >= 0 && i < 256)
+ {
+ wc.key = (WORD)i;
+ m_list.SetItemText(pItem->iItem, COL_KEY, pItem->pszText);
+ *pResult = TRUE;
+ }
+ }
+ else if(pItem->iSubItem == COL_TYPE)
+ {
+ int i = pItem->lParam;
+ if(i >= 0 && i < 2)
+ {
+ wc.fVirt = (wc.fVirt&~FVIRTKEY) | (i == 0 ? FVIRTKEY : 0);
+ m_list.SetItemText(pItem->iItem, COL_KEY, MakeAccelVkeyLabel(wc.key, wc.fVirt&FVIRTKEY));
+ m_list.SetItemText(pItem->iItem, COL_TYPE, (wc.fVirt&FVIRTKEY)?_T("VIRTKEY"):_T("ASCII"));
+ *pResult = TRUE;
+ }
+ }
+ else if(pItem->iSubItem == COL_APPCMD)
+ {
+ int i = pItem->lParam;
+ if(i >= 0 && i <= APPCOMMAND_LAST)
+ {
+ wc.appcmd = (WORD)i;
+ m_list.SetItemText(pItem->iItem, COL_APPCMD, pItem->pszText);
+ *pResult = TRUE;
+ }
+ }
+ else if(pItem->iSubItem == COL_MOUSE)
+ {
+ wc.mouse = pItem->lParam;
+ m_list.SetItemText(pItem->iItem, COL_MOUSE, pItem->pszText);
+ }
+ else if(pItem->iSubItem == COL_RMCMD)
+ {
+ wc.rmcmd = CStringA(CString(pItem->pszText)).Trim();
+ wc.rmcmd.Replace(' ', '_');
+ m_list.SetItemText(pItem->iItem, pItem->iSubItem, CString(wc.rmcmd));
+ *pResult = TRUE;
+ }
+ else if(pItem->iSubItem == COL_RMREPCNT)
+ {
+ CString str = CString(pItem->pszText).Trim();
+ wc.rmrepcnt = _tcstol(str, NULL, 10);
+ str.Format(_T("%d"), wc.rmrepcnt);
+ m_list.SetItemText(pItem->iItem, pItem->iSubItem, str);
+ *pResult = TRUE;
+ }
+
+ if(*pResult)
+ SetModified();
+}
+
+
+void CPPageAccelTbl::OnTimer(UINT nIDEvent)
+{
+ UpdateData();
+
+ if(m_fWinLirc)
+ {
+ CString addr;
+ m_WinLircEdit.GetWindowText(addr);
+ AfxGetAppSettings().WinLircClient.Connect(addr);
+ }
+
+ m_WinLircEdit.Invalidate();
+
+ if(m_fUIce)
+ {
+ CString addr;
+ m_UIceEdit.GetWindowText(addr);
+ AfxGetAppSettings().UIceClient.Connect(addr);
+ }
+
+ m_UIceEdit.Invalidate();
+
+ m_counter++;
+
+ __super::OnTimer(nIDEvent);
+}
+
+HBRUSH CPPageAccelTbl::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+ HBRUSH hbr = __super::OnCtlColor(pDC, pWnd, nCtlColor);
+
+ int status = -1;
+
+ if(*pWnd == m_WinLircEdit)
+ status = AfxGetAppSettings().WinLircClient.GetStatus();
+ else if(*pWnd == m_UIceEdit)
+ status = AfxGetAppSettings().UIceClient.GetStatus();
+
+ if(status == 0 || status == 2 && (m_counter&1))
+ pDC->SetTextColor(0x0000ff);
+ else if(status == 1)
+ pDC->SetTextColor(0x008000);
+
+ return hbr;
+}
+
+BOOL CPPageAccelTbl::OnSetActive()
+{
+ SetTimer(1, 1000, NULL);
+
+ return CPPageBase::OnSetActive();
+}
+
+BOOL CPPageAccelTbl::OnKillActive()
+{
+ KillTimer(1);
+
+ return CPPageBase::OnKillActive();
+}
+
diff --git a/src/apps/mplayerc/PPageAccelTbl.h b/src/apps/mplayerc/PPageAccelTbl.h
new file mode 100644
index 000000000..9322dc375
--- /dev/null
+++ b/src/apps/mplayerc/PPageAccelTbl.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "PPageBase.h"
+#include "PlayerListCtrl.h"
+#include "StaticLink.h"
+
+// CPPageAccelTbl dialog
+
+class CPPageAccelTbl : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageAccelTbl)
+
+private:
+ enum {COL_CMD, COL_MOD, COL_KEY, COL_TYPE, COL_ID, COL_MOUSE, COL_APPCMD, COL_RMCMD, COL_RMREPCNT};
+ CList<wmcmd> m_wmcmds;
+
+ void SetupList();
+
+ int m_counter;
+
+public:
+ CPPageAccelTbl();
+ virtual ~CPPageAccelTbl();
+
+ static CString MakeAccelModLabel(BYTE fVirt);
+ static CString MakeAccelVkeyLabel(WORD key, bool fVirtKey);
+ static CString MakeAccelShortcutLabel(UINT id);
+ static CString MakeAccelShortcutLabel(ACCEL& a);
+ static CString MakeMouseButtonLabel(UINT mouse);
+ static CString MakeAppCommandLabel(UINT id);
+
+ enum {APPCOMMAND_LAST=APPCOMMAND_MEDIA_CHANNEL_DOWN};
+
+// Dialog Data
+ enum { IDD = IDD_PPAGEACCELTBL };
+ CPlayerListCtrl m_list;
+ BOOL m_fWinLirc;
+ CString m_WinLircAddr;
+ CEdit m_WinLircEdit;
+ CStaticLink m_WinLircLink;
+ BOOL m_fUIce;
+ CString m_UIceAddr;
+ CEdit m_UIceEdit;
+ CStaticLink m_UIceLink;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ virtual BOOL OnSetActive();
+ virtual BOOL OnKillActive();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnBeginlabeleditList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnDolabeleditList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnEndlabeleditList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnBnClickedButton2();
+ afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+ afx_msg void OnTimer(UINT nIDEvent);
+};
diff --git a/src/apps/mplayerc/PPageAudioSwitcher.cpp b/src/apps/mplayerc/PPageAudioSwitcher.cpp
new file mode 100644
index 000000000..65839a2c1
--- /dev/null
+++ b/src/apps/mplayerc/PPageAudioSwitcher.cpp
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageAudioSwitcher.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include <math.h>
+#include "mplayerc.h"
+#include "PPageAudioSwitcher.h"
+
+// CPPageAudioSwitcher dialog
+
+IMPLEMENT_DYNAMIC(CPPageAudioSwitcher, CPPageBase)
+CPPageAudioSwitcher::CPPageAudioSwitcher(IFilterGraph* pFG)
+ : CPPageBase(CPPageAudioSwitcher::IDD, CPPageAudioSwitcher::IDD)
+ , m_fAudioNormalize(FALSE)
+ , m_fAudioNormalizeRecover(FALSE)
+ , m_fDownSampleTo441(FALSE)
+ , m_fCustomChannelMapping(FALSE)
+ , m_nChannels(0)
+ , m_fEnableAudioSwitcher(FALSE)
+ , m_dwChannelMask(0)
+ , m_tAudioTimeShift(0)
+ , m_fAudioTimeShift(FALSE)
+ , m_AudioBoost(0)
+{
+ m_pASF = FindFilter(__uuidof(CAudioSwitcherFilter), pFG);
+}
+
+CPPageAudioSwitcher::~CPPageAudioSwitcher()
+{
+}
+
+void CPPageAudioSwitcher::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Check(pDX, IDC_CHECK5, m_fAudioNormalize);
+ DDX_Check(pDX, IDC_CHECK6, m_fAudioNormalizeRecover);
+ DDX_Slider(pDX, IDC_SLIDER1, m_AudioBoost);
+ DDX_Control(pDX, IDC_SLIDER1, m_AudioBoostCtrl);
+ DDX_Check(pDX, IDC_CHECK3, m_fDownSampleTo441);
+ DDX_Check(pDX, IDC_CHECK1, m_fCustomChannelMapping);
+ DDX_Control(pDX, IDC_EDIT1, m_nChannelsCtrl);
+ DDX_Text(pDX, IDC_EDIT1, m_nChannels);
+ DDX_Control(pDX, IDC_SPIN1, m_nChannelsSpinCtrl);
+ DDX_Control(pDX, IDC_LIST1, m_list);
+ DDX_Check(pDX, IDC_CHECK2, m_fEnableAudioSwitcher);
+ DDX_Control(pDX, IDC_CHECK3, m_fDownSampleTo441Ctrl);
+ DDX_Control(pDX, IDC_CHECK1, m_fCustomChannelMappingCtrl);
+ DDX_Control(pDX, IDC_EDIT2, m_tAudioTimeShiftCtrl);
+ DDX_Control(pDX, IDC_SPIN2, m_tAudioTimeShiftSpin);
+ DDX_Text(pDX, IDC_EDIT2, m_tAudioTimeShift);
+ DDX_Check(pDX, IDC_CHECK4, m_fAudioTimeShift);
+ DDX_Control(pDX, IDC_CHECK4, m_fAudioTimeShiftCtrl);
+}
+
+BEGIN_MESSAGE_MAP(CPPageAudioSwitcher, CPPageBase)
+ ON_NOTIFY(NM_CLICK, IDC_LIST1, OnNMClickList1)
+ ON_WM_DRAWITEM()
+ ON_EN_CHANGE(IDC_EDIT1, OnEnChangeEdit1)
+ ON_UPDATE_COMMAND_UI(IDC_SLIDER1, OnUpdateAudioSwitcher)
+ ON_UPDATE_COMMAND_UI(IDC_CHECK5, OnUpdateAudioSwitcher)
+ ON_UPDATE_COMMAND_UI(IDC_CHECK6, OnUpdateAudioSwitcher)
+ ON_UPDATE_COMMAND_UI(IDC_CHECK3, OnUpdateAudioSwitcher)
+ ON_UPDATE_COMMAND_UI(IDC_CHECK4, OnUpdateAudioSwitcher)
+ ON_UPDATE_COMMAND_UI(IDC_EDIT2, OnUpdateAudioSwitcher)
+ ON_UPDATE_COMMAND_UI(IDC_SPIN2, OnUpdateAudioSwitcher)
+ ON_UPDATE_COMMAND_UI(IDC_CHECK1, OnUpdateAudioSwitcher)
+ ON_UPDATE_COMMAND_UI(IDC_EDIT1, OnUpdateChannelMapping)
+ ON_UPDATE_COMMAND_UI(IDC_SPIN1, OnUpdateChannelMapping)
+ ON_UPDATE_COMMAND_UI(IDC_LIST1, OnUpdateChannelMapping)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC1, OnUpdateChannelMapping)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC2, OnUpdateChannelMapping)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC3, OnUpdateChannelMapping)
+ ON_WM_HSCROLL()
+END_MESSAGE_MAP()
+
+
+// CPPageAudioSwitcher message handlers
+
+BOOL CPPageAudioSwitcher::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_fEnableAudioSwitcher = s.fEnableAudioSwitcher;
+ m_fAudioNormalize = s.fAudioNormalize;
+ m_fAudioNormalizeRecover = s.fAudioNormalizeRecover;
+ m_AudioBoost = (int)(50.0f*log10(s.AudioBoost));
+ m_AudioBoostCtrl.SetRange(0, 100);
+ m_fDownSampleTo441 = s.fDownSampleTo441;
+ m_fAudioTimeShift = s.fAudioTimeShift;
+ m_tAudioTimeShift = s.tAudioTimeShift;
+ m_tAudioTimeShiftSpin.SetRange32(-1000*60*60*24, 1000*60*60*24);
+ m_fCustomChannelMapping = s.fCustomChannelMapping;
+ memcpy(m_pSpeakerToChannelMap, s.pSpeakerToChannelMap, sizeof(s.pSpeakerToChannelMap));
+
+ if(m_pASF)
+ m_pASF->GetInputSpeakerConfig(&m_dwChannelMask);
+
+ m_nChannels = 1;
+ m_nChannelsSpinCtrl.SetRange(1, 18);
+
+ if(m_pASF)
+ m_nChannels = m_pASF->GetNumberOfInputChannels();
+
+ m_list.InsertColumn(0, _T(""), LVCFMT_LEFT, 100);
+ m_list.InsertItem(0, _T(""));
+ m_list.InsertItem(1, _T("Front Left"));
+ m_list.InsertItem(2, _T("Front Right"));
+ m_list.InsertItem(3, _T("Front Center"));
+ m_list.InsertItem(4, _T("Low Frequency"));
+ m_list.InsertItem(5, _T("Back Left"));
+ m_list.InsertItem(6, _T("Back Right"));
+ m_list.InsertItem(7, _T("Front Left of Center"));
+ m_list.InsertItem(8, _T("Front Right of Center"));
+ m_list.InsertItem(9, _T("Back Center"));
+ m_list.InsertItem(10, _T("Side Left"));
+ m_list.InsertItem(11, _T("Side Right"));
+ m_list.InsertItem(12, _T("Top Center"));
+ m_list.InsertItem(13, _T("Top Front Left"));
+ m_list.InsertItem(14, _T("Top Front Center"));
+ m_list.InsertItem(15, _T("Top Front Right"));
+ m_list.InsertItem(16, _T("Top Back Left"));
+ m_list.InsertItem(17, _T("Top Back Center"));
+ m_list.InsertItem(18, _T("Top Back Right"));
+ m_list.SetColumnWidth(0, LVSCW_AUTOSIZE);
+
+ for(int i = 1; i <= 18; i++)
+ {
+ m_list.InsertColumn(i, _T(""), LVCFMT_CENTER, 16);
+ CString n;
+ n.Format(_T("%d"), i);
+ m_list.SetItemText(0, i, n);
+// m_list.SetColumnWidth(i, LVSCW_AUTOSIZE);
+// m_list.SetColumnWidth(i, m_list.GetColumnWidth(i)*8/10);
+ }
+
+ UpdateData(FALSE);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageAudioSwitcher::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ s.fEnableAudioSwitcher = !!m_fEnableAudioSwitcher;
+ s.fAudioNormalize = !!m_fAudioNormalize;
+ s.fAudioNormalizeRecover = !!m_fAudioNormalizeRecover;
+ s.AudioBoost = (float)pow(10.0, (double)m_AudioBoost/50);
+ s.fDownSampleTo441 = !!m_fDownSampleTo441;
+ s.fAudioTimeShift = !!m_fAudioTimeShift;
+ s.tAudioTimeShift = m_tAudioTimeShift;
+ s.fCustomChannelMapping = !!m_fCustomChannelMapping;
+ memcpy(s.pSpeakerToChannelMap, m_pSpeakerToChannelMap, sizeof(m_pSpeakerToChannelMap));
+
+ if(m_pASF)
+ {
+ m_pASF->SetSpeakerConfig(s.fCustomChannelMapping, s.pSpeakerToChannelMap);
+ m_pASF->EnableDownSamplingTo441(s.fDownSampleTo441);
+ m_pASF->SetAudioTimeShift(s.fAudioTimeShift ? 10000i64*s.tAudioTimeShift : 0);
+ m_pASF->SetNormalizeBoost(s.fAudioNormalize, s.fAudioNormalizeRecover, s.AudioBoost);
+ }
+
+ return __super::OnApply();
+}
+
+void CPPageAudioSwitcher::OnNMClickList1(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)pNMHDR;
+
+ if(lpnmlv->iItem > 0 && lpnmlv->iSubItem > 0 && lpnmlv->iSubItem <= m_nChannels)
+ {
+ UpdateData();
+ m_pSpeakerToChannelMap[m_nChannels-1][lpnmlv->iItem-1] ^= 1<<(lpnmlv->iSubItem-1);
+ m_list.RedrawItems(lpnmlv->iItem, lpnmlv->iItem);
+ SetModified();
+
+ if(GetKeyState(VK_SHIFT) & 0x8000)
+ {
+ OnApply();
+ }
+ }
+
+ *pResult = 0;
+}
+
+void CPPageAudioSwitcher::OnEnChangeEdit1()
+{
+ if(IsWindow(m_list.m_hWnd))
+ {
+ UpdateData();
+ m_list.Invalidate();
+ }
+}
+
+#include <math.h>
+
+void CPPageAudioSwitcher::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
+{
+ if(nIDCtl != IDC_LIST1) return;
+
+// if(lpDrawItemStruct->itemID == 0)
+// UpdateData();
+
+ CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
+
+ pDC->SetBkMode(TRANSPARENT);
+
+ CPen p(PS_INSIDEFRAME, 1, 0xe0e0e0);
+ CPen* old = pDC->SelectObject(&p);
+
+ pDC->MoveTo(lpDrawItemStruct->rcItem.left, lpDrawItemStruct->rcItem.bottom-1);
+ pDC->LineTo(lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom-1);
+
+ CHeaderCtrl* pHeader = m_list.GetHeaderCtrl();
+ int nColumnCount = pHeader->GetItemCount();
+
+ for(int i = 0; i < nColumnCount; i++)
+ {
+ CRect r, rb;
+ m_list.GetSubItemRect(lpDrawItemStruct->itemID, i, LVIR_BOUNDS, rb);
+ m_list.GetSubItemRect(lpDrawItemStruct->itemID, i, LVIR_LABEL, r);
+
+ pDC->MoveTo(r.right-1, r.top);
+ pDC->LineTo(r.right-1, r.bottom-1);
+
+ CSize s = pDC->GetTextExtent(m_list.GetItemText(lpDrawItemStruct->itemID, i));
+
+ if(i == 0)
+ {
+ r.left = rb.left;
+
+ if(lpDrawItemStruct->itemID == 0)
+ {
+ pDC->MoveTo(0, 0);
+ pDC->LineTo(r.right, r.bottom-1);
+ }
+ else
+ {
+ pDC->SetTextColor(m_list.IsWindowEnabled() ? 0 : 0xb0b0b0);
+ pDC->TextOut(r.left+1, (r.top+r.bottom-s.cy)/2, m_list.GetItemText(lpDrawItemStruct->itemID, i));
+ }
+ }
+ else
+ {
+ pDC->SetTextColor(i > m_nChannels ? 0xe0e0e0 : (!m_list.IsWindowEnabled() ? 0xb0b0b0 : 0));
+
+ if(lpDrawItemStruct->itemID == 0)
+ {
+ pDC->TextOut((r.left+r.right-s.cx)/2, (r.top+r.bottom-s.cy)/2, m_list.GetItemText(lpDrawItemStruct->itemID, i));
+ }
+ else
+ {
+ if(m_dwChannelMask & (1<<(lpDrawItemStruct->itemID-1)))
+ {
+ int nBitsSet = 0;
+
+ for(int j = 1; j <= (1<<(lpDrawItemStruct->itemID-1)); j <<= 1)
+ {
+ if(m_dwChannelMask & j)
+ nBitsSet++;
+ }
+
+ if(nBitsSet == i)
+ {
+ COLORREF tmp = pDC->GetTextColor();
+
+ pDC->SetTextColor(0xe0e0e0);
+ CFont f;
+ f.CreatePointFont(MulDiv(100, 96, pDC->GetDeviceCaps(LOGPIXELSX)), _T("Marlett"));
+ CFont* old = pDC->SelectObject(&f);
+ s = pDC->GetTextExtent(_T("g"));
+ pDC->TextOut((r.left+r.right-s.cx)/2, (r.top+r.bottom-s.cy)/2, _T("g"));
+
+ pDC->SetTextColor(tmp);
+ }
+ }
+
+ if(m_pSpeakerToChannelMap[m_nChannels-1][lpDrawItemStruct->itemID-1] & (1<<(i-1)))
+ {
+ CFont f;
+ f.CreatePointFont(MulDiv(100, 96, pDC->GetDeviceCaps(LOGPIXELSX)), _T("Marlett"));
+ CFont* old = pDC->SelectObject(&f);
+ s = pDC->GetTextExtent(_T("a"));
+ pDC->TextOut((r.left+r.right-s.cx)/2, (r.top+r.bottom-s.cy)/2, _T("a"));
+ pDC->SelectObject(old);
+ }
+ }
+ }
+ }
+
+ pDC->SelectObject(old);
+}
+
+void CPPageAudioSwitcher::OnUpdateAudioSwitcher(CCmdUI* pCmdUI)
+{
+// UpdateData();
+ pCmdUI->Enable(IsDlgButtonChecked(IDC_CHECK2)/*m_fEnableAudioSwitcher*/);
+}
+
+void CPPageAudioSwitcher::OnUpdateChannelMapping(CCmdUI* pCmdUI)
+{
+// UpdateData();
+ pCmdUI->Enable(IsDlgButtonChecked(IDC_CHECK2)/*m_fEnableAudioSwitcher*/
+ && IsDlgButtonChecked(IDC_CHECK1)/*m_fCustomChannelMapping*/);
+}
+
+void CPPageAudioSwitcher::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+ SetModified();
+
+ __super::OnHScroll(nSBCode, nPos, pScrollBar);
+}
diff --git a/src/apps/mplayerc/PPageAudioSwitcher.h b/src/apps/mplayerc/PPageAudioSwitcher.h
new file mode 100644
index 000000000..87f51adc8
--- /dev/null
+++ b/src/apps/mplayerc/PPageAudioSwitcher.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "PPageBase.h"
+#include "FloatEdit.h"
+#include "..\..\filters\switcher\AudioSwitcher\AudioSwitcher.h"
+
+// CPPageAudioSwitcher dialog
+
+class CPPageAudioSwitcher : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageAudioSwitcher)
+
+private:
+ CComQIPtr<IAudioSwitcherFilter> m_pASF;
+ DWORD m_pSpeakerToChannelMap[18][18];
+ DWORD m_dwChannelMask;
+
+public:
+ CPPageAudioSwitcher(IFilterGraph* pFG);
+ virtual ~CPPageAudioSwitcher();
+
+// Dialog Data
+ enum { IDD = IDD_PPAGEAUDIOSWITCHER };
+
+ BOOL m_fEnableAudioSwitcher;
+ BOOL m_fAudioNormalize;
+ BOOL m_fAudioNormalizeRecover;
+ int m_AudioBoost;
+ CSliderCtrl m_AudioBoostCtrl;
+ BOOL m_fDownSampleTo441;
+ CButton m_fDownSampleTo441Ctrl;
+ BOOL m_fCustomChannelMapping;
+ CButton m_fCustomChannelMappingCtrl;
+ CEdit m_nChannelsCtrl;
+ int m_nChannels;
+ CSpinButtonCtrl m_nChannelsSpinCtrl;
+ CListCtrl m_list;
+ int m_tAudioTimeShift;
+ CButton m_fAudioTimeShiftCtrl;
+ CIntEdit m_tAudioTimeShiftCtrl;
+ CSpinButtonCtrl m_tAudioTimeShiftSpin;
+ BOOL m_fAudioTimeShift;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnNMClickList1(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
+ afx_msg void OnEnChangeEdit1();
+ afx_msg void OnUpdateAudioSwitcher(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateChannelMapping(CCmdUI* pCmdUI);
+public:
+ afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+};
diff --git a/src/apps/mplayerc/PPageBase.cpp b/src/apps/mplayerc/PPageBase.cpp
new file mode 100644
index 000000000..517cf21c3
--- /dev/null
+++ b/src/apps/mplayerc/PPageBase.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageBase.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PPageBase.h"
+
+// CPPageBase dialog
+
+IMPLEMENT_DYNAMIC(CPPageBase, CCmdUIPropertyPage)
+CPPageBase::CPPageBase(UINT nIDTemplate, UINT nIDCaption)
+ : CCmdUIPropertyPage(nIDTemplate, nIDCaption)
+{
+}
+
+CPPageBase::~CPPageBase()
+{
+}
+
+void CPPageBase::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+}
+
+void CPPageBase::CreateToolTip()
+{
+ m_wndToolTip.Create(this);
+ m_wndToolTip.Activate(TRUE);
+ m_wndToolTip.SetMaxTipWidth(300);
+ m_wndToolTip.SetDelayTime(TTDT_AUTOPOP, 10000);
+ for(CWnd* pChild = GetWindow(GW_CHILD); pChild; pChild = pChild->GetWindow(GW_HWNDNEXT))
+ {
+ CString strToolTip;
+ if(strToolTip.LoadString(pChild->GetDlgCtrlID()))
+ m_wndToolTip.AddTool(pChild, strToolTip);
+ }
+}
+
+BOOL CPPageBase::PreTranslateMessage(MSG* pMsg)
+{
+ if(IsWindow(m_wndToolTip))
+ if(pMsg->message >= WM_MOUSEFIRST && pMsg->message <= WM_MOUSELAST)
+ {
+ MSG msg;
+ memcpy(&msg, pMsg, sizeof(MSG));
+ for(HWND hWndParent = ::GetParent(msg.hwnd);
+ hWndParent && hWndParent != m_hWnd;
+ hWndParent = ::GetParent(hWndParent))
+ {
+ msg.hwnd = hWndParent;
+ }
+
+ if(msg.hwnd)
+ {
+ m_wndToolTip.RelayEvent(&msg);
+ }
+ }
+
+ return __super::PreTranslateMessage(pMsg);
+}
+
+BEGIN_MESSAGE_MAP(CPPageBase, CCmdUIPropertyPage)
+ ON_WM_DESTROY()
+END_MESSAGE_MAP()
+
+
+// CPPageBase message handlers
+
+BOOL CPPageBase::OnSetActive()
+{
+ AfxGetApp()->WriteProfileInt(ResStr(IDS_R_SETTINGS), _T("LastUsedPage"), (UINT)m_pPSP->pszTemplate);
+
+ return __super::OnSetActive();
+}
+
+void CPPageBase::OnDestroy()
+{
+ __super::OnDestroy();
+
+ m_wndToolTip.DestroyWindow();
+} \ No newline at end of file
diff --git a/src/apps/mplayerc/PPageBase.h b/src/apps/mplayerc/PPageBase.h
new file mode 100644
index 000000000..25f00fba7
--- /dev/null
+++ b/src/apps/mplayerc/PPageBase.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+// CPPageBase dialog
+
+class CPPageBase : public CCmdUIPropertyPage
+{
+ DECLARE_DYNAMIC(CPPageBase)
+
+protected:
+ CToolTipCtrl m_wndToolTip;
+ void CreateToolTip();
+
+public:
+ CPPageBase(UINT nIDTemplate, UINT nIDCaption = 0);
+ virtual ~CPPageBase();
+
+// Dialog Data
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ virtual BOOL OnSetActive();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnDestroy();
+};
diff --git a/src/apps/mplayerc/PPageCasimir.cpp b/src/apps/mplayerc/PPageCasimir.cpp
new file mode 100644
index 000000000..a72f5cdcb
--- /dev/null
+++ b/src/apps/mplayerc/PPageCasimir.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// CPPageCasimir.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "MainFrm.h"
+#include "PPageOutput.h"
+#include "../../../include/moreuuids.h"
+#include ".\ppagecasimir.h"
+
+// CPPageCasimir dialog
+
+IMPLEMENT_DYNAMIC(CPPageCasimir, CPPageBase)
+CPPageCasimir::CPPageCasimir()
+ : CPPageBase(CPPageCasimir::IDD, CPPageCasimir::IDD)
+ , m_fMonitorAutoRefreshRate(FALSE)
+ , m_fD3DFullscreen(FALSE)
+ , m_fRememberDVDPos(FALSE)
+ , m_fRememberFilePos(FALSE)
+{
+}
+
+CPPageCasimir::~CPPageCasimir()
+{
+}
+
+void CPPageCasimir::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Check(pDX, IDC_AUTO_REFRESHRATE_CHECK, m_fMonitorAutoRefreshRate);
+ DDX_Check(pDX, IDC_FULLSCREEN_MONITOR_CHECK, m_fD3DFullscreen);
+ DDX_Control(pDX, IDC_SLI_CONTRAST, m_SliContrast);
+ DDX_Control(pDX, IDC_SLI_BRIGHTNESS, m_SliBrightness);
+ DDX_Control(pDX, IDC_SLI_HUE, m_SliHue);
+ DDX_Control(pDX, IDC_SLI_SATURATION, m_SliSaturation);
+ DDX_Check(pDX, IDC_DVD_POS, m_fRememberDVDPos);
+ DDX_Check(pDX, IDC_FILE_POS, m_fRememberFilePos);
+}
+
+
+BEGIN_MESSAGE_MAP(CPPageCasimir, CPPageBase)
+ ON_WM_HSCROLL()
+ ON_BN_CLICKED(IDC_RESET, OnBnClickedReset)
+END_MESSAGE_MAP()
+
+
+// CPPageCasimir message handlers
+
+BOOL CPPageCasimir::OnInitDialog()
+{
+ COLORPROPERTY_RANGE* ControlRange;
+ __super::OnInitDialog();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_fMonitorAutoRefreshRate = s.fMonitorAutoRefreshRate;
+ m_fD3DFullscreen = s.fD3DFullscreen;
+ m_fRememberDVDPos = s.fRememberDVDPos;
+ m_fRememberFilePos = s.fRememberFilePos;
+
+ UpdateData(FALSE);
+
+ CreateToolTip();
+
+ ControlRange = AfxGetMyApp()->GetColorControl (Contrast);
+ if (ControlRange)
+ {
+ m_dContrast = s.dContrast;
+ m_SliContrast.EnableWindow (TRUE);
+ m_SliContrast.SetRange ((int)ControlRange->MinValue*100, (int)ControlRange->MaxValue*100);
+ m_SliContrast.SetTicFreq ((int)(ControlRange->MaxValue - ControlRange->MinValue) * 10);
+ m_SliContrast.SetPos ((int)(m_dContrast*100));
+ }
+
+ ControlRange = AfxGetMyApp()->GetColorControl (Brightness);
+ if (ControlRange)
+ {
+ m_dBrightness = s.dBrightness;
+ m_SliBrightness.EnableWindow (TRUE);
+ m_SliBrightness.SetRange ((int)ControlRange->MinValue, (int)ControlRange->MaxValue);
+ m_SliBrightness.SetTicFreq ((int)(ControlRange->MaxValue - ControlRange->MinValue) / 10);
+ m_SliBrightness.SetPos ((int)m_dBrightness);
+ }
+
+ ControlRange = AfxGetMyApp()->GetColorControl (Hue);
+ if (ControlRange)
+ {
+ m_dHue = s.dHue;
+ m_SliHue.EnableWindow (TRUE);
+ m_SliHue.SetRange ((int)ControlRange->MinValue, (int)ControlRange->MaxValue);
+ m_SliHue.SetTicFreq ((int)(ControlRange->MaxValue - ControlRange->MinValue) / 10);
+ m_SliHue.SetPos ((int)m_dHue);
+ }
+
+ ControlRange = AfxGetMyApp()->GetColorControl (Saturation);
+ if (ControlRange)
+ {
+ m_dSaturation = s.dSaturation;
+ m_SliSaturation.EnableWindow (TRUE);
+ m_SliSaturation.SetRange ((int)ControlRange->MinValue*100, (int)ControlRange->MaxValue*100);
+ m_SliSaturation.SetTicFreq ((int)(ControlRange->MaxValue - ControlRange->MinValue) * 10);
+ m_SliSaturation.SetPos ((int)(m_dSaturation*100));
+ }
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageCasimir::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ s.dBrightness = m_dBrightness;
+ s.dContrast = m_dContrast;
+ s.dHue = m_dHue;
+ s.dSaturation = m_dSaturation;
+ s.fMonitorAutoRefreshRate = m_fMonitorAutoRefreshRate ? true : false;
+ s.fD3DFullscreen = m_fD3DFullscreen ? true : false;
+ s.fRememberDVDPos = m_fRememberDVDPos ? true : false;
+ s.fRememberFilePos = m_fRememberFilePos ? true : false;
+
+ return __super::OnApply();
+}
+
+
+void CPPageCasimir::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+ if(*pScrollBar == m_SliContrast)
+ {
+ UpdateData();
+ m_dContrast = (float)(m_SliContrast.GetPos()/100.0);
+ }
+ else if(*pScrollBar == m_SliBrightness)
+ {
+ UpdateData();
+ m_dBrightness = (float)m_SliBrightness.GetPos();
+ }
+ else if(*pScrollBar == m_SliHue)
+ {
+ UpdateData();
+ m_dHue = (float)m_SliHue.GetPos();
+ }
+ else if(*pScrollBar == m_SliSaturation)
+ {
+ UpdateData();
+ m_dSaturation = (float)(m_SliSaturation.GetPos()/100.0);
+ }
+
+ SetModified();
+
+ ((CMainFrame*)AfxGetMyApp()->GetMainWnd())->SetVMR9ColorControl(m_dBrightness, m_dContrast, m_dHue, m_dSaturation);
+
+ __super::OnHScroll(nSBCode, nPos, pScrollBar);
+}
+
+void CPPageCasimir::OnBnClickedReset()
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ UpdateData(FALSE);
+
+ m_dContrast = AfxGetMyApp()->GetColorControl (Contrast)->DefaultValue;
+ m_dBrightness = AfxGetMyApp()->GetColorControl (Brightness)->DefaultValue;
+ m_dHue = AfxGetMyApp()->GetColorControl (Hue)->DefaultValue;
+ m_dSaturation = AfxGetMyApp()->GetColorControl (Saturation)->DefaultValue;
+
+ m_SliContrast.SetPos ((int)m_dContrast*100);
+ m_SliBrightness.SetPos ((int)m_dBrightness);
+ m_SliHue.SetPos ((int)m_dHue);
+ m_SliSaturation.SetPos ((int)m_dSaturation*100);
+
+ ((CMainFrame*)AfxGetMyApp()->GetMainWnd())->SetVMR9ColorControl(m_dBrightness, m_dContrast, m_dHue, m_dSaturation);
+}
+
+void CPPageCasimir::OnCancel()
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ ((CMainFrame*)AfxGetMyApp()->GetMainWnd())->SetVMR9ColorControl(s.dBrightness, s.dContrast, s.dHue, s.dSaturation);
+ __super::OnCancel();
+}
diff --git a/src/apps/mplayerc/PPageCasimir.h b/src/apps/mplayerc/PPageCasimir.h
new file mode 100644
index 000000000..13d63c728
--- /dev/null
+++ b/src/apps/mplayerc/PPageCasimir.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "PPageBase.h"
+#include "afxcmn.h"
+
+// CPPageCasimir dialog
+
+class CPPageCasimir : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageCasimir)
+
+private:
+ CStringArray m_AudioRendererDisplayNames;
+
+ float m_dBrightness;
+ float m_dContrast;
+ float m_dHue;
+ float m_dSaturation;
+
+public:
+ CPPageCasimir();
+ virtual ~CPPageCasimir();
+
+// Dialog Data
+ enum { IDD = IDD_PPAGECASIMIR };
+ BOOL m_fMonitorAutoRefreshRate;
+ BOOL m_fD3DFullscreen;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+
+ CSliderCtrl m_SliContrast;
+ CSliderCtrl m_SliBrightness;
+ CSliderCtrl m_SliHue;
+ CSliderCtrl m_SliSaturation;
+ afx_msg void OnBnClickedReset();
+ BOOL m_fRememberDVDPos;
+ BOOL m_fRememberFilePos;
+ virtual void OnCancel();
+};
diff --git a/src/apps/mplayerc/PPageDVD.cpp b/src/apps/mplayerc/PPageDVD.cpp
new file mode 100644
index 000000000..e0813b539
--- /dev/null
+++ b/src/apps/mplayerc/PPageDVD.cpp
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageDVD.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PPageDVD.h"
+
+struct
+{
+ LCID lcid;
+ TCHAR name[64];
+}
+LCIDNameList[] =
+{
+ {0x0000, _T("Default")},
+ {0x0436, _T("Afrikaans")},
+ {0x041c, _T("Albanian")},
+ {0x0401, _T("Arabic (Saudi Arabia)")},
+ {0x0801, _T("Arabic (Iraq)")},
+ {0x0c01, _T("Arabic (Egypt)")},
+ {0x1001, _T("Arabic (Libya)")},
+ {0x1401, _T("Arabic (Algeria)")},
+ {0x1801, _T("Arabic (Morocco)")},
+ {0x1c01, _T("Arabic (Tunisia)")},
+ {0x2001, _T("Arabic (Oman)")},
+ {0x2401, _T("Arabic (Yemen)")},
+ {0x2801, _T("Arabic (Syria)")},
+ {0x2c01, _T("Arabic (Jordan)")},
+ {0x3001, _T("Arabic (Lebanon)")},
+ {0x3401, _T("Arabic (Kuwait)")},
+ {0x3801, _T("Arabic (U.A.E.)")},
+ {0x3c01, _T("Arabic (Bahrain)")},
+ {0x4001, _T("Arabic (Qatar)")},
+ {0x042b, _T("Armenian")},
+ {0x042c, _T("Azeri (Latin)")},
+ {0x082c, _T("Azeri (Cyrillic)")},
+ {0x042d, _T("Basque")},
+ {0x0423, _T("Belarusian")},
+ {0x0402, _T("Bulgarian")},
+ {0x0455, _T("Burmese")},
+ {0x0403, _T("Catalan")},
+ {0x0404, _T("Chinese (Taiwan)")},
+ {0x0804, _T("Chinese (PRC)")},
+ {0x0c04, _T("Chinese (Hong Kong SAR, PRC)")},
+ {0x1004, _T("Chinese (Singapore)")},
+ {0x1404, _T("Chinese (Macau SAR)")},
+ {0x041a, _T("Croatian")},
+ {0x0405, _T("Czech")},
+ {0x0406, _T("Danish")},
+ {0x0465, _T("Divehi")},
+ {0x0413, _T("Dutch (Netherlands)")},
+ {0x0813, _T("Dutch (Belgium)")},
+ {0x0409, _T("English (United States)")},
+ {0x0809, _T("English (United Kingdom)")},
+ {0x0c09, _T("English (Australian)")},
+ {0x1009, _T("English (Canadian)")},
+ {0x1409, _T("English (New Zealand)")},
+ {0x1809, _T("English (Ireland)")},
+ {0x1c09, _T("English (South Africa)")},
+ {0x2009, _T("English (Jamaica)")},
+ {0x2409, _T("English (Caribbean)")},
+ {0x2809, _T("English (Belize)")},
+ {0x2c09, _T("English (Trinidad)")},
+ {0x3009, _T("English (Zimbabwe)")},
+ {0x3409, _T("English (Philippines)")},
+ {0x0425, _T("Estonian")},
+ {0x0438, _T("Faeroese")},
+ {0x0429, _T("Farsi")},
+ {0x040b, _T("Finnish")},
+ {0x040c, _T("French (Standard)")},
+ {0x080c, _T("French (Belgian)")},
+ {0x0c0c, _T("French (Canadian)")},
+ {0x100c, _T("French (Switzerland)")},
+ {0x140c, _T("French (Luxembourg)")},
+ {0x180c, _T("French (Monaco)")},
+ {0x0456, _T("Galician")},
+ {0x0437, _T("Georgian")},
+ {0x0407, _T("German (Standard)")},
+ {0x0807, _T("German (Switzerland)")},
+ {0x0c07, _T("German (Austria)")},
+ {0x1007, _T("German (Luxembourg)")},
+ {0x1407, _T("German (Liechtenstein)")},
+ {0x0408, _T("Greek")},
+ {0x0447, _T("Gujarati")},
+ {0x040d, _T("Hebrew")},
+ {0x0439, _T("Hindi")},
+ {0x040e, _T("Hungarian")},
+ {0x040f, _T("Icelandic")},
+ {0x0421, _T("Indonesian")},
+ {0x0410, _T("Italian (Standard)")},
+ {0x0810, _T("Italian (Switzerland)")},
+ {0x0411, _T("Japanese")},
+ {0x044b, _T("Kannada")},
+ {0x0457, _T("Konkani")},
+ {0x0412, _T("Korean")},
+ {0x0812, _T("Korean (Johab)")},
+ {0x0440, _T("Kyrgyz")},
+ {0x0426, _T("Latvian")},
+ {0x0427, _T("Lithuanian")},
+ {0x0827, _T("Lithuanian (Classic)")},
+ {0x042f, _T("FYRO Macedonian")},
+ {0x043e, _T("Malay (Malaysian)")},
+ {0x083e, _T("Malay (Brunei Darussalam)")},
+ {0x044e, _T("Marathi")},
+ {0x0450, _T("Mongolian")},
+ {0x0414, _T("Norwegian (Bokmal)")},
+ {0x0814, _T("Norwegian (Nynorsk)")},
+ {0x0415, _T("Polish")},
+ {0x0416, _T("Portuguese (Brazil)")},
+ {0x0816, _T("Portuguese (Portugal)")},
+ {0x0446, _T("Punjabi")},
+ {0x0418, _T("Romanian")},
+ {0x0419, _T("Russian")},
+ {0x044f, _T("Sanskrit")},
+ {0x0c1a, _T("Serbian (Cyrillic)")},
+ {0x081a, _T("Serbian (Latin)")},
+ {0x041b, _T("Slovak")},
+ {0x0424, _T("Slovenian")},
+ {0x040a, _T("Spanish (Spain, Traditional Sort)")},
+ {0x080a, _T("Spanish (Mexican)")},
+ {0x0c0a, _T("Spanish (Spain, International Sort)")},
+ {0x100a, _T("Spanish (Guatemala)")},
+ {0x140a, _T("Spanish (Costa Rica)")},
+ {0x180a, _T("Spanish (Panama)")},
+ {0x1c0a, _T("Spanish (Dominican Republic)")},
+ {0x200a, _T("Spanish (Venezuela)")},
+ {0x240a, _T("Spanish (Colombia)")},
+ {0x280a, _T("Spanish (Peru)")},
+ {0x2c0a, _T("Spanish (Argentina)")},
+ {0x300a, _T("Spanish (Ecuador)")},
+ {0x340a, _T("Spanish (Chile)")},
+ {0x380a, _T("Spanish (Uruguay)")},
+ {0x3c0a, _T("Spanish (Paraguay)")},
+ {0x400a, _T("Spanish (Bolivia)")},
+ {0x440a, _T("Spanish (El Salvador)")},
+ {0x480a, _T("Spanish (Honduras)")},
+ {0x4c0a, _T("Spanish (Nicaragua)")},
+ {0x500a, _T("Spanish (Puerto Rico)")},
+ {0x0430, _T("Sutu")},
+ {0x0441, _T("Swahili (Kenya)")},
+ {0x041d, _T("Swedish")},
+ {0x081d, _T("Swedish (Finland)")},
+ {0x045a, _T("Syriac")},
+ {0x0449, _T("Tamil")},
+ {0x0444, _T("Tatar (Tatarstan)")},
+ {0x044a, _T("Telugu")},
+ {0x041e, _T("Thai")},
+ {0x041f, _T("Turkish")},
+ {0x0422, _T("Ukrainian")},
+ {0x0420, _T("Urdu (Pakistan)")},
+ {0x0820, _T("Urdu (India)")},
+ {0x0443, _T("Uzbek (Latin)")},
+ {0x0843, _T("Uzbek (Cyrillic)")},
+ {0x042a, _T("Vietnamese")}
+};
+
+
+// CPPageDVD dialog
+
+IMPLEMENT_DYNAMIC(CPPageDVD, CPPageBase)
+CPPageDVD::CPPageDVD()
+ : CPPageBase(CPPageDVD::IDD, CPPageDVD::IDD)
+ , m_iDVDLocation(0)
+ , m_iDVDLangType(0)
+ , m_dvdpath(_T(""))
+ , m_fAutoSpeakerConf(FALSE)
+{
+}
+
+CPPageDVD::~CPPageDVD()
+{
+}
+
+void CPPageDVD::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Radio(pDX, IDC_RADIO1, m_iDVDLocation);
+ DDX_Radio(pDX, IDC_RADIO3, m_iDVDLangType);
+ DDX_Control(pDX, IDC_LIST1, m_lcids);
+ DDX_Text(pDX, IDC_DVDPATH, m_dvdpath);
+ DDX_Control(pDX, IDC_DVDPATH, m_dvdpathctrl);
+ DDX_Control(pDX, IDC_BUTTON1, m_dvdpathselctrl);
+ DDX_Check(pDX, IDC_CHECK1, m_fAutoSpeakerConf);
+}
+
+void CPPageDVD::UpdateLCIDList()
+{
+ UpdateData();
+
+ LCID lcid = m_iDVDLangType == 0 ? m_idMenuLang
+ : m_iDVDLangType == 1 ? m_idAudioLang
+ : m_idSubtitlesLang;
+
+ for(int i = 0; i < m_lcids.GetCount(); i++)
+ {
+ if(m_lcids.GetItemData(i) == lcid)
+ {
+ m_lcids.SetCurSel(i);
+ m_lcids.SetTopIndex(i);
+ break;
+ }
+ }
+}
+
+BEGIN_MESSAGE_MAP(CPPageDVD, CPPageBase)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+ ON_CONTROL_RANGE(BN_CLICKED, IDC_RADIO3, IDC_RADIO5, OnBnClickedLangradio123)
+ ON_LBN_SELCHANGE(IDC_LIST1, OnLbnSelchangeList1)
+ ON_UPDATE_COMMAND_UI(IDC_DVDPATH, OnUpdateDVDPath)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateDVDPath)
+END_MESSAGE_MAP()
+
+
+// CPPageDVD message handlers
+
+BOOL CPPageDVD::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_iDVDLocation = s.fUseDVDPath ? 1 : 0;
+ m_dvdpath = s.sDVDPath;
+ m_iDVDLangType = 0;
+
+ m_idMenuLang = s.idMenuLang;
+ m_idAudioLang = s.idAudioLang;
+ m_idSubtitlesLang = s.idSubtitlesLang;
+ m_fAutoSpeakerConf = s.fAutoSpeakerConf;
+
+ UpdateData(FALSE);
+
+ for(int i = 0; i < countof(LCIDNameList); i++)
+ {
+ m_lcids.AddString(LCIDNameList[i].name);
+ m_lcids.SetItemData(i, LCIDNameList[i].lcid);
+ }
+
+ UpdateLCIDList();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageDVD::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ s.sDVDPath = m_dvdpath;
+ s.fUseDVDPath = (m_iDVDLocation == 1);
+ s.idMenuLang = m_idMenuLang;
+ s.idAudioLang = m_idAudioLang;
+ s.idSubtitlesLang = m_idSubtitlesLang;
+ s.fAutoSpeakerConf = !!m_fAutoSpeakerConf;
+
+ return __super::OnApply();
+}
+
+void CPPageDVD::OnBnClickedButton1()
+{
+ TCHAR path[MAX_PATH];
+
+ BROWSEINFO bi;
+ bi.hwndOwner = m_hWnd;
+ bi.pidlRoot = NULL;
+ bi.pszDisplayName = path;
+ bi.lpszTitle = _T("Select the path for the DVD:");
+ bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_VALIDATE | BIF_USENEWUI | BIF_NONEWFOLDERBUTTON;
+ bi.lpfn = NULL;
+ bi.lParam = 0;
+ bi.iImage = 0;
+
+ LPITEMIDLIST iil;
+ if(iil = SHBrowseForFolder(&bi))
+ {
+ SHGetPathFromIDList(iil, path);
+ m_dvdpath = path;
+
+ UpdateData(FALSE);
+
+ SetModified();
+ }
+}
+
+void CPPageDVD::OnBnClickedLangradio123(UINT nID)
+{
+ UpdateLCIDList();
+}
+
+void CPPageDVD::OnLbnSelchangeList1()
+{
+ LCID& lcid = m_iDVDLangType == 0 ? m_idMenuLang
+ : m_iDVDLangType == 1 ? m_idAudioLang
+ : m_idSubtitlesLang;
+
+ lcid = m_lcids.GetItemData(m_lcids.GetCurSel());
+
+ SetModified();
+}
+
+void CPPageDVD::OnUpdateDVDPath(CCmdUI* pCmdUI)
+{
+ UpdateData();
+
+ pCmdUI->Enable(m_iDVDLocation == 1);
+}
diff --git a/src/apps/mplayerc/PPageDVD.h b/src/apps/mplayerc/PPageDVD.h
new file mode 100644
index 000000000..8581a51c7
--- /dev/null
+++ b/src/apps/mplayerc/PPageDVD.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "PPageBase.h"
+
+// CPPageDVD dialog
+
+class CPPageDVD : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageDVD)
+
+private:
+ void UpdateLCIDList();
+
+public:
+ CPPageDVD();
+ virtual ~CPPageDVD();
+
+ CListBox m_lcids;
+ CString m_dvdpath;
+ CEdit m_dvdpathctrl;
+ CButton m_dvdpathselctrl;
+ int m_iDVDLocation;
+ int m_iDVDLangType;
+
+ LCID m_idMenuLang;
+ LCID m_idAudioLang;
+ LCID m_idSubtitlesLang;
+
+ BOOL m_fAutoSpeakerConf;
+
+// Dialog Data
+ enum { IDD = IDD_PPAGEDVD};
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnBnClickedLangradio123(UINT nID);
+ afx_msg void OnLbnSelchangeList1();
+ afx_msg void OnUpdateDVDPath(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/PPageExternalFilters.cpp b/src/apps/mplayerc/PPageExternalFilters.cpp
new file mode 100644
index 000000000..6810bf0d9
--- /dev/null
+++ b/src/apps/mplayerc/PPageExternalFilters.cpp
@@ -0,0 +1,731 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageExternalFilters.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PPageExternalFilters.h"
+#include "ComPropertySheet.h"
+#include "RegFilterChooserDlg.h"
+#include "SelectMediaType.h"
+#include "FGFilter.h"
+#include "..\..\..\include\moreuuids.h"
+
+#include <initguid.h>
+#include <Dmoreg.h>
+
+// CPPageExternalFilters dialog
+
+IMPLEMENT_DYNAMIC(CPPageExternalFilters, CPPageBase)
+CPPageExternalFilters::CPPageExternalFilters()
+ : CPPageBase(CPPageExternalFilters::IDD, CPPageExternalFilters::IDD)
+ , m_iLoadType(FilterOverride::PREFERRED)
+ , m_pLastSelFilter(NULL)
+{
+}
+
+CPPageExternalFilters::~CPPageExternalFilters()
+{
+}
+
+void CPPageExternalFilters::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_LIST1, m_filters);
+ DDX_Radio(pDX, IDC_RADIO1, m_iLoadType);
+ DDX_Control(pDX, IDC_EDIT1, m_dwMerit);
+ DDX_Control(pDX, IDC_TREE2, m_tree);
+}
+
+void CPPageExternalFilters::StepUp(CCheckListBox& list)
+{
+ int i = list.GetCurSel();
+ if(i < 1) return;
+
+ CString str;
+ list.GetText(i, str);
+ DWORD_PTR dwItemData = list.GetItemData(i);
+ int nCheck = list.GetCheck(i);
+ list.DeleteString(i);
+ i--;
+ list.InsertString(i, str);
+ list.SetItemData(i, dwItemData);
+ list.SetCheck(i, nCheck);
+ list.SetCurSel(i);
+}
+
+void CPPageExternalFilters::StepDown(CCheckListBox& list)
+{
+ int i = list.GetCurSel();
+ if(i < 0 || i >= list.GetCount()-1) return;
+
+ CString str;
+ list.GetText(i, str);
+ DWORD_PTR dwItemData = list.GetItemData(i);
+ int nCheck = list.GetCheck(i);
+ list.DeleteString(i);
+ i++;
+ list.InsertString(i, str);
+ list.SetItemData(i, dwItemData);
+ list.SetCheck(i, nCheck);
+ list.SetCurSel(i);
+}
+
+FilterOverride* CPPageExternalFilters::GetCurFilter()
+{
+ int i = m_filters.GetCurSel();
+ return i >= 0 ? (FilterOverride*)m_pFilters.GetAt((POSITION)m_filters.GetItemDataPtr(i)) : (FilterOverride*)NULL;
+}
+
+void CPPageExternalFilters::SetupMajorTypes(CAtlArray<GUID>& guids)
+{
+ guids.RemoveAll();
+ guids.Add(MEDIATYPE_NULL);
+ guids.Add(MEDIATYPE_Video);
+ guids.Add(MEDIATYPE_Audio);
+ guids.Add(MEDIATYPE_Text);
+ guids.Add(MEDIATYPE_Midi);
+ guids.Add(MEDIATYPE_Stream);
+ guids.Add(MEDIATYPE_Interleaved);
+ guids.Add(MEDIATYPE_File);
+ guids.Add(MEDIATYPE_ScriptCommand);
+ guids.Add(MEDIATYPE_AUXLine21Data);
+ guids.Add(MEDIATYPE_VBI);
+ guids.Add(MEDIATYPE_Timecode);
+ guids.Add(MEDIATYPE_LMRT);
+ guids.Add(MEDIATYPE_URL_STREAM);
+ guids.Add(MEDIATYPE_MPEG1SystemStream);
+ guids.Add(MEDIATYPE_AnalogVideo);
+ guids.Add(MEDIATYPE_AnalogAudio);
+ guids.Add(MEDIATYPE_MPEG2_PACK);
+ guids.Add(MEDIATYPE_MPEG2_PES);
+ guids.Add(MEDIATYPE_MPEG2_SECTIONS);
+ guids.Add(MEDIATYPE_DVD_ENCRYPTED_PACK);
+ guids.Add(MEDIATYPE_DVD_NAVIGATION);
+}
+
+void CPPageExternalFilters::SetupSubTypes(CAtlArray<GUID>& guids)
+{
+ guids.RemoveAll();
+ guids.Add(MEDIASUBTYPE_None);
+ guids.Add(MEDIASUBTYPE_CLPL);
+ guids.Add(MEDIASUBTYPE_YUYV);
+ guids.Add(MEDIASUBTYPE_IYUV);
+ guids.Add(MEDIASUBTYPE_YVU9);
+ guids.Add(MEDIASUBTYPE_Y411);
+ guids.Add(MEDIASUBTYPE_Y41P);
+ guids.Add(MEDIASUBTYPE_YUY2);
+ guids.Add(MEDIASUBTYPE_YVYU);
+ guids.Add(MEDIASUBTYPE_UYVY);
+ guids.Add(MEDIASUBTYPE_Y211);
+ guids.Add(MEDIASUBTYPE_CLJR);
+ guids.Add(MEDIASUBTYPE_IF09);
+ guids.Add(MEDIASUBTYPE_CPLA);
+ guids.Add(MEDIASUBTYPE_MJPG);
+ guids.Add(MEDIASUBTYPE_TVMJ);
+ guids.Add(MEDIASUBTYPE_WAKE);
+ guids.Add(MEDIASUBTYPE_CFCC);
+ guids.Add(MEDIASUBTYPE_IJPG);
+ guids.Add(MEDIASUBTYPE_Plum);
+ guids.Add(MEDIASUBTYPE_DVCS);
+ guids.Add(MEDIASUBTYPE_DVSD);
+ guids.Add(MEDIASUBTYPE_MDVF);
+ guids.Add(MEDIASUBTYPE_RGB1);
+ guids.Add(MEDIASUBTYPE_RGB4);
+ guids.Add(MEDIASUBTYPE_RGB8);
+ guids.Add(MEDIASUBTYPE_RGB565);
+ guids.Add(MEDIASUBTYPE_RGB555);
+ guids.Add(MEDIASUBTYPE_RGB24);
+ guids.Add(MEDIASUBTYPE_RGB32);
+ guids.Add(MEDIASUBTYPE_ARGB1555);
+ guids.Add(MEDIASUBTYPE_ARGB4444);
+ guids.Add(MEDIASUBTYPE_ARGB32);
+ guids.Add(MEDIASUBTYPE_A2R10G10B10);
+ guids.Add(MEDIASUBTYPE_A2B10G10R10);
+ guids.Add(MEDIASUBTYPE_AYUV);
+ guids.Add(MEDIASUBTYPE_AI44);
+ guids.Add(MEDIASUBTYPE_IA44);
+ guids.Add(MEDIASUBTYPE_RGB32_D3D_DX7_RT);
+ guids.Add(MEDIASUBTYPE_RGB16_D3D_DX7_RT);
+ guids.Add(MEDIASUBTYPE_ARGB32_D3D_DX7_RT);
+ guids.Add(MEDIASUBTYPE_ARGB4444_D3D_DX7_RT);
+ guids.Add(MEDIASUBTYPE_ARGB1555_D3D_DX7_RT);
+ guids.Add(MEDIASUBTYPE_RGB32_D3D_DX9_RT);
+ guids.Add(MEDIASUBTYPE_RGB16_D3D_DX9_RT);
+ guids.Add(MEDIASUBTYPE_ARGB32_D3D_DX9_RT);
+ guids.Add(MEDIASUBTYPE_ARGB4444_D3D_DX9_RT);
+ guids.Add(MEDIASUBTYPE_ARGB1555_D3D_DX9_RT);
+ guids.Add(MEDIASUBTYPE_YV12);
+ guids.Add(MEDIASUBTYPE_NV12);
+ guids.Add(MEDIASUBTYPE_IMC1);
+ guids.Add(MEDIASUBTYPE_IMC2);
+ guids.Add(MEDIASUBTYPE_IMC3);
+ guids.Add(MEDIASUBTYPE_IMC4);
+ guids.Add(MEDIASUBTYPE_S340);
+ guids.Add(MEDIASUBTYPE_S342);
+ guids.Add(MEDIASUBTYPE_Overlay);
+ guids.Add(MEDIASUBTYPE_MPEG1Packet);
+ guids.Add(MEDIASUBTYPE_MPEG1Payload);
+ guids.Add(MEDIASUBTYPE_MPEG1AudioPayload);
+ guids.Add(MEDIASUBTYPE_MPEG1System);
+ guids.Add(MEDIASUBTYPE_MPEG1VideoCD);
+ guids.Add(MEDIASUBTYPE_MPEG1Video);
+ guids.Add(MEDIASUBTYPE_MPEG1Audio);
+ guids.Add(MEDIASUBTYPE_Avi);
+ guids.Add(MEDIASUBTYPE_Asf);
+ guids.Add(MEDIASUBTYPE_QTMovie);
+ guids.Add(MEDIASUBTYPE_QTRpza);
+ guids.Add(MEDIASUBTYPE_QTSmc);
+ guids.Add(MEDIASUBTYPE_QTRle);
+ guids.Add(MEDIASUBTYPE_QTJpeg);
+ guids.Add(MEDIASUBTYPE_PCMAudio_Obsolete);
+ guids.Add(MEDIASUBTYPE_PCM);
+ guids.Add(MEDIASUBTYPE_WAVE);
+ guids.Add(MEDIASUBTYPE_AU);
+ guids.Add(MEDIASUBTYPE_AIFF);
+ guids.Add(MEDIASUBTYPE_dvsd);
+ guids.Add(MEDIASUBTYPE_dvhd);
+ guids.Add(MEDIASUBTYPE_dvsl);
+ guids.Add(MEDIASUBTYPE_dv25);
+ guids.Add(MEDIASUBTYPE_dv50);
+ guids.Add(MEDIASUBTYPE_dvh1);
+ guids.Add(MEDIASUBTYPE_Line21_BytePair);
+ guids.Add(MEDIASUBTYPE_Line21_GOPPacket);
+ guids.Add(MEDIASUBTYPE_Line21_VBIRawData);
+ guids.Add(MEDIASUBTYPE_TELETEXT);
+ guids.Add(MEDIASUBTYPE_DRM_Audio);
+ guids.Add(MEDIASUBTYPE_IEEE_FLOAT);
+ guids.Add(MEDIASUBTYPE_DOLBY_AC3_SPDIF);
+ guids.Add(MEDIASUBTYPE_RAW_SPORT);
+ guids.Add(MEDIASUBTYPE_SPDIF_TAG_241h);
+ guids.Add(MEDIASUBTYPE_DssVideo);
+ guids.Add(MEDIASUBTYPE_DssAudio);
+ guids.Add(MEDIASUBTYPE_VPVideo);
+ guids.Add(MEDIASUBTYPE_VPVBI);
+ guids.Add(MEDIASUBTYPE_ATSC_SI);
+ guids.Add(MEDIASUBTYPE_DVB_SI);
+ guids.Add(MEDIASUBTYPE_MPEG2DATA);
+ guids.Add(MEDIASUBTYPE_MPEG2_VIDEO);
+ guids.Add(MEDIASUBTYPE_MPEG2_PROGRAM);
+ guids.Add(MEDIASUBTYPE_MPEG2_TRANSPORT);
+ guids.Add(MEDIASUBTYPE_MPEG2_TRANSPORT_STRIDE);
+ guids.Add(MEDIASUBTYPE_MPEG2_AUDIO);
+ guids.Add(MEDIASUBTYPE_DOLBY_AC3);
+ guids.Add(MEDIASUBTYPE_DVD_SUBPICTURE);
+ guids.Add(MEDIASUBTYPE_DVD_LPCM_AUDIO);
+ guids.Add(MEDIASUBTYPE_DTS);
+ guids.Add(MEDIASUBTYPE_SDDS);
+ guids.Add(MEDIASUBTYPE_DVD_NAVIGATION_PCI);
+ guids.Add(MEDIASUBTYPE_DVD_NAVIGATION_DSI);
+ guids.Add(MEDIASUBTYPE_DVD_NAVIGATION_PROVIDER);
+ guids.Add(MEDIASUBTYPE_I420);
+ guids.Add(MEDIASUBTYPE_WAVE_DOLBY_AC3);
+ guids.Add(MEDIASUBTYPE_WAVE_DTS);
+}
+
+BEGIN_MESSAGE_MAP(CPPageExternalFilters, CPPageBase)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateFilter)
+ ON_UPDATE_COMMAND_UI(IDC_RADIO1, OnUpdateFilter)
+ ON_UPDATE_COMMAND_UI(IDC_RADIO2, OnUpdateFilter)
+ ON_UPDATE_COMMAND_UI(IDC_RADIO3, OnUpdateFilter)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON3, OnUpdateFilterUp)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON4, OnUpdateFilterDown)
+ ON_UPDATE_COMMAND_UI(IDC_EDIT1, OnUpdateFilterMerit)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON5, OnUpdateFilter)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON6, OnUpdateSubType)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON7, OnUpdateDeleteType)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON8, OnUpdateFilter)
+ ON_BN_CLICKED(IDC_BUTTON1, OnAddRegistered)
+ ON_BN_CLICKED(IDC_BUTTON2, OnRemoveFilter)
+ ON_BN_CLICKED(IDC_BUTTON3, OnMoveFilterUp)
+ ON_BN_CLICKED(IDC_BUTTON4, OnMoveFilterDown)
+ ON_LBN_DBLCLK(IDC_LIST1, OnLbnDblclkFilter)
+ ON_BN_CLICKED(IDC_BUTTON5, OnAddMajorType)
+ ON_BN_CLICKED(IDC_BUTTON6, OnAddSubType)
+ ON_BN_CLICKED(IDC_BUTTON7, OnDeleteType)
+ ON_BN_CLICKED(IDC_BUTTON8, OnResetTypes)
+ ON_LBN_SELCHANGE(IDC_LIST1, OnLbnSelchangeList1)
+ ON_BN_CLICKED(IDC_RADIO1, OnBnClickedRadio)
+ ON_BN_CLICKED(IDC_RADIO2, OnBnClickedRadio)
+ ON_BN_CLICKED(IDC_RADIO3, OnBnClickedRadio)
+ ON_EN_CHANGE(IDC_EDIT1, OnEnChangeEdit1)
+ ON_NOTIFY(NM_DBLCLK, IDC_TREE2, OnNMDblclkTree2)
+ ON_WM_DROPFILES()
+END_MESSAGE_MAP()
+
+
+// CPPageExternalFilters message handlers
+
+BOOL CPPageExternalFilters::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ DragAcceptFiles(TRUE);
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_pFilters.RemoveAll();
+
+ POSITION pos = s.filters.GetHeadPosition();
+ while(pos)
+ {
+ CAutoPtr<FilterOverride> f(new FilterOverride(s.filters.GetNext(pos)));
+
+ CString name(_T("<unknown>"));
+
+ if(f->type == FilterOverride::REGISTERED)
+ {
+ name = CFGFilterRegistry(f->dispname).GetName();
+ if(name.IsEmpty()) name = f->name + _T(" <not registered>");
+ }
+ else if(f->type == FilterOverride::EXTERNAL)
+ {
+ name = f->name;
+ if(f->fTemporary) name += _T(" <temporary>");
+ if(!CPath(MakeFullPath(f->path)).FileExists()) name += _T(" <not found!>");
+ }
+
+ int i = m_filters.AddString(name);
+ m_filters.SetCheck(i, f->fDisabled ? 0 : 1);
+ m_filters.SetItemDataPtr(i, m_pFilters.AddTail(f));
+ }
+
+ UpdateData(FALSE);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageExternalFilters::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ s.filters.RemoveAll();
+
+ for(int i = 0; i < m_filters.GetCount(); i++)
+ {
+ if(POSITION pos = (POSITION)m_filters.GetItemData(i))
+ {
+ CAutoPtr<FilterOverride> f(new FilterOverride(m_pFilters.GetAt(pos)));
+ f->fDisabled = !m_filters.GetCheck(i);
+ s.filters.AddTail(f);
+ }
+ }
+
+ return __super::OnApply();
+}
+
+void CPPageExternalFilters::OnUpdateFilter(CCmdUI* pCmdUI)
+{
+ if(FilterOverride* f = GetCurFilter())
+ {
+ pCmdUI->Enable(!(pCmdUI->m_nID == IDC_RADIO2 && f->type == FilterOverride::EXTERNAL));
+ }
+ else
+ {
+ pCmdUI->Enable(FALSE);
+ }
+}
+
+void CPPageExternalFilters::OnUpdateFilterUp(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_filters.GetCurSel() > 0);
+}
+
+void CPPageExternalFilters::OnUpdateFilterDown(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_filters.GetCurSel() >= 0 && m_filters.GetCurSel() < m_filters.GetCount()-1);
+}
+
+void CPPageExternalFilters::OnUpdateFilterMerit(CCmdUI* pCmdUI)
+{
+ UpdateData();
+ pCmdUI->Enable(m_iLoadType == FilterOverride::MERIT);
+}
+
+void CPPageExternalFilters::OnUpdateSubType(CCmdUI* pCmdUI)
+{
+ HTREEITEM node = m_tree.GetSelectedItem();
+ pCmdUI->Enable(node != NULL && m_tree.GetItemData(node) == NULL);
+}
+
+void CPPageExternalFilters::OnUpdateDeleteType(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(!!m_tree.GetSelectedItem());
+}
+
+void CPPageExternalFilters::OnAddRegistered()
+{
+ CRegFilterChooserDlg dlg(this);
+ if(dlg.DoModal() == IDOK)
+ {
+ while(!dlg.m_filters.IsEmpty())
+ {
+ if(FilterOverride* f = dlg.m_filters.RemoveHead())
+ {
+ CAutoPtr<FilterOverride> p(f);
+
+ CString name = f->name;
+
+ if(f->type == FilterOverride::EXTERNAL)
+ {
+ if(!CPath(MakeFullPath(f->path)).FileExists()) name += _T(" <not found!>");
+ }
+
+ int i = m_filters.AddString(name);
+ m_filters.SetItemDataPtr(i, m_pFilters.AddTail(p));
+ m_filters.SetCheck(i, 1);
+
+ if(dlg.m_filters.IsEmpty())
+ {
+ m_filters.SetCurSel(i);
+ OnLbnSelchangeList1();
+ }
+ }
+ }
+ }
+}
+
+void CPPageExternalFilters::OnRemoveFilter()
+{
+ int i = m_filters.GetCurSel();
+ m_pFilters.RemoveAt((POSITION)m_filters.GetItemDataPtr(i));
+ m_filters.DeleteString(i);
+ if(i >= m_filters.GetCount()) i--;
+ m_filters.SetCurSel(i);
+ OnLbnSelchangeList1();
+}
+
+void CPPageExternalFilters::OnMoveFilterUp()
+{
+ StepUp(m_filters);
+}
+
+void CPPageExternalFilters::OnMoveFilterDown()
+{
+ StepDown(m_filters);
+}
+
+void CPPageExternalFilters::OnLbnDblclkFilter()
+{
+ if(FilterOverride* f = GetCurFilter())
+ {
+ CComPtr<IBaseFilter> pBF;
+ CString name;
+
+ if(f->type == FilterOverride::REGISTERED)
+ {
+ CStringW namew;
+ if(CreateFilter(f->dispname, &pBF, namew))
+ name = namew;
+ }
+ else if(f->type == FilterOverride::EXTERNAL)
+ {
+ if(SUCCEEDED(LoadExternalFilter(f->path, f->clsid, &pBF)))
+ name = f->name;
+ }
+
+ if(CComQIPtr<ISpecifyPropertyPages> pSPP = pBF)
+ {
+ CComPropertySheet ps(name, this);
+ if(ps.AddPages(pSPP) > 0)
+ {
+ CComPtr<IFilterGraph> pFG;
+ if(SUCCEEDED(pFG.CoCreateInstance(CLSID_FilterGraph)))
+ pFG->AddFilter(pBF, L"");
+
+ ps.DoModal();
+ }
+ }
+ }
+}
+
+void CPPageExternalFilters::OnAddMajorType()
+{
+ FilterOverride* f = GetCurFilter();
+ if(!f) return;
+
+ CAtlArray<GUID> guids;
+ SetupMajorTypes(guids);
+
+ CSelectMediaType dlg(guids, MEDIATYPE_NULL, this);
+ if(dlg.DoModal() == IDOK)
+ {
+ POSITION pos = f->guids.GetHeadPosition();
+ while(pos)
+ {
+ if(f->guids.GetNext(pos) == dlg.m_guid) {AfxMessageBox(_T("Already on the list!")); return;}
+ f->guids.GetNext(pos);
+ }
+
+ f->guids.AddTail(dlg.m_guid);
+ pos = f->guids.GetTailPosition();
+ f->guids.AddTail(GUID_NULL);
+
+ CString major = GetMediaTypeName(dlg.m_guid);
+ CString sub = GetMediaTypeName(GUID_NULL);
+
+ HTREEITEM node = m_tree.InsertItem(major);
+ m_tree.SetItemData(node, NULL);
+
+ node = m_tree.InsertItem(sub, node);
+ m_tree.SetItemData(node, (DWORD_PTR)pos);
+ }
+}
+
+void CPPageExternalFilters::OnAddSubType()
+{
+ FilterOverride* f = GetCurFilter();
+ if(!f) return;
+
+ HTREEITEM node = m_tree.GetSelectedItem();
+ if(!node) return;
+
+ HTREEITEM child = m_tree.GetChildItem(node);
+ if(!child) return;
+
+ POSITION pos = (POSITION)m_tree.GetItemData(child);
+ GUID major = f->guids.GetAt(pos);
+
+ CAtlArray<GUID> guids;
+ SetupSubTypes(guids);
+
+ CSelectMediaType dlg(guids, MEDIASUBTYPE_NULL, this);
+ if(dlg.DoModal() == IDOK)
+ {
+ for(child = m_tree.GetChildItem(node); child; child = m_tree.GetNextSiblingItem(child))
+ {
+ pos = (POSITION)m_tree.GetItemData(child);
+ f->guids.GetNext(pos);
+ if(f->guids.GetAt(pos) == dlg.m_guid) {AfxMessageBox(_T("Already on the list!")); return;}
+ }
+
+ f->guids.AddTail(major);
+ pos = f->guids.GetTailPosition();
+ f->guids.AddTail(dlg.m_guid);
+
+ CString sub = GetMediaTypeName(dlg.m_guid);
+
+ node = m_tree.InsertItem(sub, node);
+ m_tree.SetItemData(node, (DWORD_PTR)pos);
+ }
+}
+
+void CPPageExternalFilters::OnDeleteType()
+{
+ if(FilterOverride* f = GetCurFilter())
+ {
+ HTREEITEM node = m_tree.GetSelectedItem();
+ if(!node) return;
+
+ POSITION pos = (POSITION)m_tree.GetItemData(node);
+
+ if(pos == NULL)
+ {
+ for(HTREEITEM child = m_tree.GetChildItem(node); child; child = m_tree.GetNextSiblingItem(child))
+ {
+ pos = (POSITION)m_tree.GetItemData(child);
+
+ POSITION pos1 = pos;
+ f->guids.GetNext(pos);
+ POSITION pos2 = pos;
+ f->guids.GetNext(pos);
+
+ f->guids.RemoveAt(pos1);
+ f->guids.RemoveAt(pos2);
+ }
+
+ m_tree.DeleteItem(node);
+ }
+ else
+ {
+ HTREEITEM parent = m_tree.GetParentItem(node);
+
+ POSITION pos1 = pos;
+ f->guids.GetNext(pos);
+ POSITION pos2 = pos;
+ f->guids.GetNext(pos);
+
+ m_tree.DeleteItem(node);
+
+ if(!m_tree.ItemHasChildren(parent))
+ {
+ f->guids.SetAt(pos2, GUID_NULL);
+ node = m_tree.InsertItem(GetMediaTypeName(GUID_NULL), parent);
+ m_tree.SetItemData(node, (DWORD_PTR)pos1);
+ }
+ else
+ {
+ f->guids.RemoveAt(pos1);
+ f->guids.RemoveAt(pos2);
+ }
+ }
+ }
+}
+
+void CPPageExternalFilters::OnResetTypes()
+{
+ if(FilterOverride* f = GetCurFilter())
+ {
+ f->guids.RemoveAll();
+ f->guids.AddTailList(&f->backup);
+
+ m_pLastSelFilter = NULL;
+ OnLbnSelchangeList1();
+ }
+}
+
+void CPPageExternalFilters::OnLbnSelchangeList1()
+{
+ if(FilterOverride* f = GetCurFilter())
+ {
+ if(m_pLastSelFilter == f) return;
+ m_pLastSelFilter = f;
+
+ m_iLoadType = f->iLoadType;
+ UpdateData(FALSE);
+ m_dwMerit = f->dwMerit;
+
+ HTREEITEM dummy_item = m_tree.InsertItem(_T(""), 0,0, NULL, TVI_FIRST);
+ if(dummy_item)
+ for(HTREEITEM item = m_tree.GetNextVisibleItem(dummy_item); item; item = m_tree.GetNextVisibleItem(dummy_item))
+ m_tree.DeleteItem(item);
+
+ CMapStringToPtr map;
+
+ POSITION pos = f->guids.GetHeadPosition();
+ while(pos)
+ {
+ POSITION tmp = pos;
+ CString major = GetMediaTypeName(f->guids.GetNext(pos));
+ CString sub = GetMediaTypeName(f->guids.GetNext(pos));
+
+ HTREEITEM node = NULL;
+
+ void* val = NULL;
+ if(map.Lookup(major, val)) node = (HTREEITEM)val;
+ else map[major] = node = m_tree.InsertItem(major);
+ m_tree.SetItemData(node, NULL);
+
+ node = m_tree.InsertItem(sub, node);
+ m_tree.SetItemData(node, (DWORD_PTR)tmp);
+ }
+
+ m_tree.DeleteItem(dummy_item);
+
+ for(HTREEITEM item = m_tree.GetFirstVisibleItem(); item; item = m_tree.GetNextVisibleItem(item))
+ m_tree.Expand(item, TVE_EXPAND);
+
+ m_tree.EnsureVisible(m_tree.GetRootItem());
+ }
+ else
+ {
+ m_pLastSelFilter = NULL;
+
+ m_iLoadType = FilterOverride::PREFERRED;
+ UpdateData(FALSE);
+ m_dwMerit = 0;
+
+ m_tree.DeleteAllItems();
+ }
+}
+
+void CPPageExternalFilters::OnBnClickedRadio()
+{
+ UpdateData();
+ if(FilterOverride* f = GetCurFilter())
+ f->iLoadType = m_iLoadType;
+}
+
+void CPPageExternalFilters::OnEnChangeEdit1()
+{
+ UpdateData();
+ if(FilterOverride* f = GetCurFilter())
+ {
+ DWORD dw;
+ if(m_dwMerit.GetDWORD(dw))
+ f->dwMerit = dw;
+ }
+}
+
+void CPPageExternalFilters::OnNMDblclkTree2(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ *pResult = 0;
+
+ if(FilterOverride* f = GetCurFilter())
+ {
+ HTREEITEM node = m_tree.GetSelectedItem();
+ if(!node) return;
+
+ POSITION pos = (POSITION)m_tree.GetItemData(node);
+ if(!pos) return;
+
+ f->guids.GetNext(pos);
+ if(!pos) return;
+
+ CAtlArray<GUID> guids;
+ SetupSubTypes(guids);
+
+ CSelectMediaType dlg(guids, f->guids.GetAt(pos), this);
+ if(dlg.DoModal() == IDOK)
+ {
+ f->guids.SetAt(pos, dlg.m_guid);
+ m_tree.SetItemText(node, GetMediaTypeName(dlg.m_guid));
+ }
+ }
+}
+
+void CPPageExternalFilters::OnDropFiles(HDROP hDropInfo)
+{
+ SetActiveWindow();
+
+ UINT nFiles = ::DragQueryFile(hDropInfo, (UINT)-1, NULL, 0);
+ for(UINT iFile = 0; iFile < nFiles; iFile++)
+ {
+ TCHAR szFileName[_MAX_PATH];
+ ::DragQueryFile(hDropInfo, iFile, szFileName, _MAX_PATH);
+
+ CFilterMapper2 fm2(false);
+ fm2.Register(szFileName);
+
+ while(!fm2.m_filters.IsEmpty())
+ {
+ if(FilterOverride* f = fm2.m_filters.RemoveHead())
+ {
+ CAutoPtr<FilterOverride> p(f);
+ int i = m_filters.AddString(f->name);
+ m_filters.SetItemDataPtr(i, m_pFilters.AddTail(p));
+ m_filters.SetCheck(i, 1);
+
+ if(fm2.m_filters.IsEmpty())
+ {
+ m_filters.SetCurSel(i);
+ OnLbnSelchangeList1();
+ }
+ }
+ }
+ }
+ ::DragFinish(hDropInfo);
+}
diff --git a/src/apps/mplayerc/PPageExternalFilters.h b/src/apps/mplayerc/PPageExternalFilters.h
new file mode 100644
index 000000000..1fa3043dc
--- /dev/null
+++ b/src/apps/mplayerc/PPageExternalFilters.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "PPageBase.h"
+#include "floatedit.h"
+#include "mplayerc.h"
+
+// CPPageExternalFilters dialog
+
+class CPPageExternalFilters : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageExternalFilters)
+
+private:
+ void StepUp(CCheckListBox& list);
+ void StepDown(CCheckListBox& list);
+
+ CAutoPtrList<FilterOverride> m_pFilters;
+ FilterOverride* m_pLastSelFilter;
+ FilterOverride* GetCurFilter();
+
+ void SetupMajorTypes(CAtlArray<GUID>& guids);
+ void SetupSubTypes(CAtlArray<GUID>& guids);
+
+public:
+ CPPageExternalFilters();
+ virtual ~CPPageExternalFilters();
+
+// Dialog Data
+ enum { IDD = IDD_PPAGEEXTERNALFILTERS };
+
+ CCheckListBox m_filters;
+ int m_iLoadType;
+ CHexEdit m_dwMerit;
+ CTreeCtrl m_tree;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnUpdateFilter(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateFilterUp(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateFilterDown(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateFilterMerit(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateSubType(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateDeleteType(CCmdUI* pCmdUI);
+ afx_msg void OnAddRegistered();
+ afx_msg void OnRemoveFilter();
+ afx_msg void OnMoveFilterUp();
+ afx_msg void OnMoveFilterDown();
+ afx_msg void OnLbnDblclkFilter();
+ afx_msg void OnAddMajorType();
+ afx_msg void OnAddSubType();
+ afx_msg void OnDeleteType();
+ afx_msg void OnResetTypes();
+ afx_msg void OnLbnSelchangeList1();
+ afx_msg void OnBnClickedRadio();
+ afx_msg void OnEnChangeEdit1();
+ afx_msg void OnNMDblclkTree2(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnDropFiles(HDROP hDropInfo);
+};
diff --git a/src/apps/mplayerc/PPageFileInfoClip.cpp b/src/apps/mplayerc/PPageFileInfoClip.cpp
new file mode 100644
index 000000000..da48375af
--- /dev/null
+++ b/src/apps/mplayerc/PPageFileInfoClip.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageFileInfoClip.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PPageFileInfoClip.h"
+#include <atlbase.h>
+#include <qnetwork.h>
+#include "..\..\DSUtil\DSUtil.h"
+
+// CPPageFileInfoClip dialog
+
+IMPLEMENT_DYNAMIC(CPPageFileInfoClip, CPropertyPage)
+CPPageFileInfoClip::CPPageFileInfoClip(CString fn, IFilterGraph* pFG)
+ : CPropertyPage(CPPageFileInfoClip::IDD, CPPageFileInfoClip::IDD)
+ , m_fn(fn)
+ , m_pFG(pFG)
+ , m_clip(_T("None"))
+ , m_author(_T("None"))
+ , m_copyright(_T("None"))
+ , m_rating(_T("None"))
+ , m_location(_T("None"))
+ , m_hIcon(NULL)
+{
+}
+
+CPPageFileInfoClip::~CPPageFileInfoClip()
+{
+ if(m_hIcon) DestroyIcon(m_hIcon);
+}
+
+void CPPageFileInfoClip::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_DEFAULTICON, m_icon);
+ DDX_Text(pDX, IDC_EDIT1, m_fn);
+ DDX_Text(pDX, IDC_EDIT4, m_clip);
+ DDX_Text(pDX, IDC_EDIT3, m_author);
+ DDX_Text(pDX, IDC_EDIT2, m_copyright);
+ DDX_Text(pDX, IDC_EDIT5, m_rating);
+ DDX_Text(pDX, IDC_EDIT6, m_location);
+ DDX_Control(pDX, IDC_EDIT7, m_desc);
+}
+
+BEGIN_MESSAGE_MAP(CPPageFileInfoClip, CPropertyPage)
+END_MESSAGE_MAP()
+
+
+// CPPageFileInfoClip message handlers
+
+BOOL CPPageFileInfoClip::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ if(m_hIcon = LoadIcon(m_fn, false))
+ m_icon.SetIcon(m_hIcon);
+
+ m_fn.TrimRight('/');
+ int i = max(m_fn.ReverseFind('\\'), m_fn.ReverseFind('/'));
+ if(i >= 0 && i < m_fn.GetLength()-1)
+ {
+ m_location = m_fn.Left(i);
+ m_fn = m_fn.Mid(i+1);
+
+ if(m_location.GetLength() == 2 && m_location[1] == ':')
+ m_location += '\\';
+ }
+
+ bool fEmpty = true;
+ BeginEnumFilters(m_pFG, pEF, pBF)
+ {
+ if(CComQIPtr<IAMMediaContent, &IID_IAMMediaContent> pAMMC = pBF)
+ {
+ CComBSTR bstr;
+ if(SUCCEEDED(pAMMC->get_Title(&bstr)) && wcslen(bstr.m_str) > 0) {m_clip = bstr.m_str; fEmpty = false;}
+ if(SUCCEEDED(pAMMC->get_AuthorName(&bstr)) && wcslen(bstr.m_str) > 0) {m_author = bstr.m_str; fEmpty = false;}
+ if(SUCCEEDED(pAMMC->get_Copyright(&bstr)) && wcslen(bstr.m_str) > 0) {m_copyright = bstr.m_str; fEmpty = false;}
+ if(SUCCEEDED(pAMMC->get_Rating(&bstr)) && wcslen(bstr.m_str) > 0) {m_rating = bstr.m_str; fEmpty = false;}
+ if(SUCCEEDED(pAMMC->get_Description(&bstr)) && wcslen(bstr.m_str) > 0) {m_desc.SetWindowText(CString(bstr.m_str)); fEmpty = false;}
+ if(!fEmpty) break;
+ }
+ }
+ EndEnumFilters
+
+ UpdateData(FALSE);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
diff --git a/src/apps/mplayerc/PPageFileInfoClip.h b/src/apps/mplayerc/PPageFileInfoClip.h
new file mode 100644
index 000000000..4cff6be86
--- /dev/null
+++ b/src/apps/mplayerc/PPageFileInfoClip.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "afxwin.h"
+
+// CPPageFileInfoClip dialog
+
+class CPPageFileInfoClip : public CPropertyPage
+{
+ DECLARE_DYNAMIC(CPPageFileInfoClip)
+
+private:
+ CComPtr<IFilterGraph> m_pFG;
+ HICON m_hIcon;
+
+public:
+ CPPageFileInfoClip(CString fn, IFilterGraph* pFG);
+ virtual ~CPPageFileInfoClip();
+
+// Dialog Data
+ enum { IDD = IDD_FILEPROPCLIP };
+
+ CStatic m_icon;
+ CString m_fn;
+ CString m_clip;
+ CString m_author;
+ CString m_copyright;
+ CString m_rating;
+ CString m_location;
+ CEdit m_desc;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+};
diff --git a/src/apps/mplayerc/PPageFileInfoDetails.cpp b/src/apps/mplayerc/PPageFileInfoDetails.cpp
new file mode 100644
index 000000000..4067bb3b0
--- /dev/null
+++ b/src/apps/mplayerc/PPageFileInfoDetails.cpp
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageFileInfoDetails.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PPageFileInfoDetails.h"
+#include <atlbase.h>
+#include "..\..\DSUtil\DSUtil.h"
+#include "d3d9.h"
+#include "Vmr9.h"
+#include "..\..\..\include\moreuuids.h"
+
+// CPPageFileInfoDetails dialog
+
+IMPLEMENT_DYNAMIC(CPPageFileInfoDetails, CPropertyPage)
+CPPageFileInfoDetails::CPPageFileInfoDetails(CString fn, IFilterGraph* pFG, ISubPicAllocatorPresenter* pCAP)
+ : CPropertyPage(CPPageFileInfoDetails::IDD, CPPageFileInfoDetails::IDD)
+ , m_fn(fn)
+ , m_pFG(pFG)
+ , m_pCAP(pCAP)
+ , m_hIcon(NULL)
+ , m_type(_T("Not known"))
+ , m_size(_T("Not known"))
+ , m_time(_T("Not known"))
+ , m_res(_T("Not known"))
+ , m_created(_T("Not known"))
+{
+}
+
+CPPageFileInfoDetails::~CPPageFileInfoDetails()
+{
+ if(m_hIcon) DestroyIcon(m_hIcon);
+}
+
+void CPPageFileInfoDetails::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_DEFAULTICON, m_icon);
+ DDX_Text(pDX, IDC_EDIT1, m_fn);
+ DDX_Text(pDX, IDC_EDIT4, m_type);
+ DDX_Text(pDX, IDC_EDIT3, m_size);
+ DDX_Text(pDX, IDC_EDIT2, m_time);
+ DDX_Text(pDX, IDC_EDIT5, m_res);
+ DDX_Text(pDX, IDC_EDIT6, m_created);
+ DDX_Control(pDX, IDC_EDIT7, m_encoding);
+}
+
+BEGIN_MESSAGE_MAP(CPPageFileInfoDetails, CPropertyPage)
+END_MESSAGE_MAP()
+
+inline int LNKO(int a, int b)
+{
+ if(a == 0 || b == 0)
+ return(1);
+
+ while(a != b)
+ {
+ if(a < b) b -= a;
+ else if(a > b) a -= b;
+ }
+
+ return(a);
+}
+
+// CPPageFileInfoDetails message handlers
+
+static bool GetProperty(IFilterGraph* pFG, LPCOLESTR propName, VARIANT* vt)
+{
+ BeginEnumFilters(pFG, pEF, pBF)
+ {
+ if(CComQIPtr<IPropertyBag> pPB = pBF)
+ if(SUCCEEDED(pPB->Read(propName, vt, NULL)))
+ return true;
+ }
+ EndEnumFilters
+
+ return false;
+}
+
+static CString FormatDateTime(FILETIME tm)
+{
+ SYSTEMTIME t;
+ FileTimeToSystemTime(&tm, &t);
+ TCHAR buff[256];
+ GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &t, NULL, buff, 256);
+ CString ret(buff);
+ ret += _T(" ");
+ GetTimeFormat(LOCALE_USER_DEFAULT, 0, &t, NULL, buff, 256);
+ ret += buff;
+ return ret;
+}
+
+BOOL CPPageFileInfoDetails::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ CString ext = m_fn.Left(m_fn.Find(_T("://"))+1).TrimRight(':');
+ if(ext.IsEmpty() || !ext.CompareNoCase(_T("file")))
+ ext = _T(".") + m_fn.Mid(m_fn.ReverseFind('.')+1);
+
+ if(m_hIcon = LoadIcon(m_fn, false))
+ m_icon.SetIcon(m_hIcon);
+
+ if(!LoadType(ext, m_type))
+ m_type = _T("Not known");
+
+ CComVariant vt;
+ if(::GetProperty(m_pFG, L"CurFile.TimeCreated", &vt))
+ {
+ if(V_VT(&vt) == VT_UI8)
+ {
+ ULARGE_INTEGER uli;
+ uli.QuadPart = V_UI8(&vt);
+
+ FILETIME ft;
+ ft.dwLowDateTime = uli.LowPart;
+ ft.dwHighDateTime = uli.HighPart;
+
+ m_created = FormatDateTime(ft);
+ }
+ }
+
+ WIN32_FIND_DATA wfd;
+ HANDLE hFind = FindFirstFile(m_fn, &wfd);
+ if(hFind != INVALID_HANDLE_VALUE)
+ {
+ FindClose(hFind);
+
+ __int64 size = (__int64(wfd.nFileSizeHigh)<<32)|wfd.nFileSizeLow;
+ __int64 shortsize = size;
+ CString measure = _T("B");
+ if(shortsize > 10240) shortsize /= 1024, measure = _T("KB");
+ if(shortsize > 10240) shortsize /= 1024, measure = _T("MB");
+ if(shortsize > 10240) shortsize /= 1024, measure = _T("GB");
+ m_size.Format(_T("%I64d%s (%I64d bytes)"), shortsize, measure, size);
+
+ if(m_created.IsEmpty())
+ {
+ m_created = FormatDateTime(wfd.ftCreationTime);
+ }
+ }
+
+ REFERENCE_TIME rtDur = 0;
+ CComQIPtr<IMediaSeeking> pMS = m_pFG;
+ if(pMS && SUCCEEDED(pMS->GetDuration(&rtDur)) && rtDur > 0)
+ {
+ m_time.Format(_T("%02d:%02d:%02d"),
+ int(rtDur/10000000/60/60),
+ int((rtDur/10000000/60)%60),
+ int((rtDur/10000000)%60));
+ }
+
+ CSize wh(0, 0), arxy(0, 0);
+ long fps = 0;
+
+ if(m_pCAP)
+ {
+ wh = m_pCAP->GetVideoSize(false);
+ arxy = m_pCAP->GetVideoSize(true);
+ }
+ else
+ {
+ if(CComQIPtr<IBasicVideo> pBV = m_pFG)
+ {
+ if(SUCCEEDED(pBV->GetVideoSize(&wh.cx, &wh.cy)))
+ {
+ if(CComQIPtr<IBasicVideo2> pBV2 = m_pFG)
+ pBV2->GetPreferredAspectRatio(&arxy.cx, &arxy.cy);
+ }
+ else
+ {
+ wh.SetSize(0, 0);
+ }
+ }
+
+ if(wh.cx == 0 && wh.cy == 0)
+ {
+ BeginEnumFilters(m_pFG, pEF, pBF)
+ {
+ if(CComQIPtr<IBasicVideo> pBV = pBF)
+ {
+ pBV->GetVideoSize(&wh.cx, &wh.cy);
+ if(CComQIPtr<IBasicVideo2> pBV2 = pBF)
+ pBV2->GetPreferredAspectRatio(&arxy.cx, &arxy.cy);
+ break;
+ }
+ else if(CComQIPtr<IVMRWindowlessControl> pWC = pBF)
+ {
+ pWC->GetNativeVideoSize(&wh.cx, &wh.cy, &arxy.cx, &arxy.cy);
+ break;
+ }
+ else if(CComQIPtr<IVMRWindowlessControl9> pWC = pBF)
+ {
+ pWC->GetNativeVideoSize(&wh.cx, &wh.cy, &arxy.cx, &arxy.cy);
+ break;
+ }
+ }
+ EndEnumFilters
+ }
+ }
+
+ if(wh.cx > 0 && wh.cy > 0)
+ {
+ m_res.Format(_T("%d x %d"), wh.cx, wh.cy);
+
+ int lnko = 0;
+ do
+ {
+ lnko = LNKO(arxy.cx, arxy.cy);
+ if(lnko > 1) arxy.cx /= lnko, arxy.cy /= lnko;
+ }
+ while(lnko > 1);
+
+ if(arxy.cx > 0 && arxy.cy > 0 && arxy.cx*wh.cy != arxy.cy*wh.cx)
+ {
+ CString ar;
+ ar.Format(_T(" (AR %d:%d)"), arxy.cx, arxy.cy);
+ m_res += ar;
+ }
+ }
+
+ m_fn.TrimRight('/');
+ m_fn.Replace('\\', '/');
+ m_fn = m_fn.Mid(m_fn.ReverseFind('/')+1);
+
+ UpdateData(FALSE);
+
+ InitEncoding();
+
+ m_pFG = NULL;
+ m_pCAP = NULL;
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CPPageFileInfoDetails::InitEncoding()
+{
+ CAtlList<CString> sl;
+
+ BeginEnumFilters(m_pFG, pEF, pBF)
+ {
+ CComPtr<IBaseFilter> pUSBF = GetUpStreamFilter(pBF);
+
+ if(GetCLSID(pBF) == CLSID_NetShowSource)
+ {
+ continue;
+ }
+ else if(GetCLSID(pUSBF) != CLSID_NetShowSource)
+ {
+ if(IPin* pPin = GetFirstPin(pBF, PINDIR_INPUT))
+ {
+ CMediaType mt;
+ if(FAILED(pPin->ConnectionMediaType(&mt)) || mt.majortype != MEDIATYPE_Stream)
+ continue;
+ }
+
+ if(IPin* pPin = GetFirstPin(pBF, PINDIR_OUTPUT))
+ {
+ CMediaType mt;
+ if(SUCCEEDED(pPin->ConnectionMediaType(&mt)) && mt.majortype == MEDIATYPE_Stream)
+ continue;
+ }
+ }
+
+ BeginEnumPins(pBF, pEP, pPin)
+ {
+ CMediaTypeEx mt;
+ PIN_DIRECTION dir;
+ if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_OUTPUT
+ || FAILED(pPin->ConnectionMediaType(&mt)))
+ continue;
+
+ CString str = mt.ToString();
+
+ if(!str.IsEmpty())
+ {
+ sl.AddTail(mt.ToString() + CString(L" [" + GetPinName(pPin) + L"]"));
+ }
+ }
+ EndEnumPins
+ }
+ EndEnumFilters
+
+ CString text = Implode(sl, '\n');
+ text.Replace(_T("\n"), _T("\r\n"));
+ m_encoding.SetWindowText(text);
+}
diff --git a/src/apps/mplayerc/PPageFileInfoDetails.h b/src/apps/mplayerc/PPageFileInfoDetails.h
new file mode 100644
index 000000000..8950ee067
--- /dev/null
+++ b/src/apps/mplayerc/PPageFileInfoDetails.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "..\..\subpic\ISubPic.h"
+#include "afxwin.h"
+
+// CPPageFileInfoDetails dialog
+
+class CPPageFileInfoDetails : public CPropertyPage
+{
+ DECLARE_DYNAMIC(CPPageFileInfoDetails)
+
+private:
+ CComPtr<IFilterGraph> m_pFG;
+ CComPtr<ISubPicAllocatorPresenter> m_pCAP;
+
+ HICON m_hIcon;
+
+ void InitEncoding();
+
+public:
+ CPPageFileInfoDetails(CString fn, IFilterGraph* pFG, ISubPicAllocatorPresenter* pCAP);
+ virtual ~CPPageFileInfoDetails();
+
+// Dialog Data
+ enum { IDD = IDD_FILEPROPDETAILS };
+
+ CStatic m_icon;
+ CString m_fn;
+ CString m_type;
+ CString m_size;
+ CString m_time;
+ CString m_res;
+ CString m_created;
+ CEdit m_encoding;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+};
diff --git a/src/apps/mplayerc/PPageFileInfoRes.cpp b/src/apps/mplayerc/PPageFileInfoRes.cpp
new file mode 100644
index 000000000..43a747dd9
--- /dev/null
+++ b/src/apps/mplayerc/PPageFileInfoRes.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageFileInfoRes.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PPageFileInfoRes.h"
+#include ".\ppagefileinfores.h"
+
+// CPPageFileInfoRes dialog
+
+IMPLEMENT_DYNAMIC(CPPageFileInfoRes, CPPageBase)
+CPPageFileInfoRes::CPPageFileInfoRes(CString fn, IFilterGraph* pFG)
+ : CPPageBase(CPPageFileInfoRes::IDD, CPPageFileInfoRes::IDD)
+ , m_fn(fn)
+ , m_hIcon(NULL)
+ , m_pFG(pFG)
+{
+}
+
+CPPageFileInfoRes::~CPPageFileInfoRes()
+{
+ if(m_hIcon) DestroyIcon(m_hIcon);
+}
+
+void CPPageFileInfoRes::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_DEFAULTICON, m_icon);
+ DDX_Text(pDX, IDC_EDIT1, m_fn);
+ DDX_Control(pDX, IDC_LIST1, m_list);
+}
+
+BEGIN_MESSAGE_MAP(CPPageFileInfoRes, CPPageBase)
+ ON_BN_CLICKED(IDC_BUTTON1, OnSaveAs)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateSaveAs)
+ ON_NOTIFY(NM_DBLCLK, IDC_LIST1, OnNMDblclkList1)
+END_MESSAGE_MAP()
+
+// CPPageFileInfoRes message handlers
+
+BOOL CPPageFileInfoRes::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ if(m_hIcon = LoadIcon(m_fn, false))
+ m_icon.SetIcon(m_hIcon);
+
+ m_fn.TrimRight('/');
+ int i = max(m_fn.ReverseFind('\\'), m_fn.ReverseFind('/'));
+ if(i >= 0 && i < m_fn.GetLength()-1)
+ m_fn = m_fn.Mid(i+1);
+
+ m_list.SetExtendedStyle(m_list.GetExtendedStyle()|LVS_EX_FULLROWSELECT);
+
+ m_list.InsertColumn(0, _T("Name"), LVCFMT_LEFT, 187);
+ m_list.InsertColumn(1, _T("Mime Type"), LVCFMT_LEFT, 127);
+
+ BeginEnumFilters(m_pFG, pEF, pBF)
+ {
+ if(CComQIPtr<IDSMResourceBag> pRB = pBF)
+ if(pRB && pRB->ResGetCount() > 0)
+ {
+ for(DWORD i = 0; i < pRB->ResGetCount(); i++)
+ {
+ CComBSTR name, desc, mime;
+ BYTE* pData = NULL;
+ DWORD len = 0;
+ if(SUCCEEDED(pRB->ResGet(i, &name, &desc, &mime, &pData, &len, NULL)))
+ {
+ CDSMResource r;
+ r.name = name;
+ r.desc = desc;
+ r.mime = mime;
+ r.data.SetCount(len);
+ memcpy(r.data.GetData(), pData, r.data.GetCount());
+ CoTaskMemFree(pData);
+ POSITION pos = m_res.AddTail(r);
+ int iItem = m_list.InsertItem(m_list.GetItemCount(), CString(name));
+ m_list.SetItemText(iItem, 1, CString(mime));
+ m_list.SetItemData(iItem, (DWORD_PTR)pos);
+ }
+ }
+ }
+ }
+ EndEnumFilters
+
+ UpdateData(FALSE);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CPPageFileInfoRes::OnSaveAs()
+{
+ int i = m_list.GetSelectionMark();
+ if(i < 0) return;
+
+ CDSMResource& r = m_res.GetAt((POSITION)m_list.GetItemData(i));
+
+ CFileDialog fd(FALSE, NULL, CString(r.name),
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
+ _T("All files|*.*||"), this, 0);
+ if(fd.DoModal() == IDOK)
+ {
+ if(FILE* f = _tfopen(fd.GetPathName(), _T("wb")))
+ {
+ fwrite(r.data.GetData(), 1, r.data.GetCount(), f);
+ fclose(f);
+ }
+ }
+}
+
+void CPPageFileInfoRes::OnUpdateSaveAs(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_list.GetSelectedCount());
+}
+
+void CPPageFileInfoRes::OnNMDblclkList1(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ int i = m_list.GetSelectionMark();
+ if(i < 0) return;
+
+ CDSMResource& r = m_res.GetAt((POSITION)m_list.GetItemData(i));
+
+ CString url;
+ url.Format(_T("http://localhost:%d/convres.html?id=%x"), AfxGetAppSettings().nWebServerPort, (DWORD)&r);
+ ShellExecute(NULL, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT);
+
+ *pResult = 0;
+}
diff --git a/src/apps/mplayerc/PPageFileInfoRes.h b/src/apps/mplayerc/PPageFileInfoRes.h
new file mode 100644
index 000000000..030d73fb2
--- /dev/null
+++ b/src/apps/mplayerc/PPageFileInfoRes.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "afxwin.h"
+#include "afxcmn.h"
+#include "..\..\DSUtil\DSMPropertyBag.h"
+#include "PPageBase.h"
+
+// CPPageFileInfoRes dialog
+
+class CPPageFileInfoRes : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageFileInfoRes)
+
+private:
+ CComPtr<IFilterGraph> m_pFG;
+ HICON m_hIcon;
+ CAtlList<CDSMResource> m_res;
+
+public:
+ CPPageFileInfoRes(CString fn, IFilterGraph* pFG); // standard constructor
+ virtual ~CPPageFileInfoRes();
+
+// Dialog Data
+ enum { IDD = IDD_FILEPROPRES };
+
+ CStatic m_icon;
+ CString m_fn;
+ CListCtrl m_list;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnSaveAs();
+ afx_msg void OnUpdateSaveAs(CCmdUI* pCmdUI);
+ afx_msg void OnNMDblclkList1(NMHDR *pNMHDR, LRESULT *pResult);
+};
diff --git a/src/apps/mplayerc/PPageFileInfoSheet.cpp b/src/apps/mplayerc/PPageFileInfoSheet.cpp
new file mode 100644
index 000000000..90495d2f0
--- /dev/null
+++ b/src/apps/mplayerc/PPageFileInfoSheet.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageFileInfoSheet.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "MainFrm.h"
+#include "PPageFileInfoSheet.h"
+
+// CPPageFileInfoSheet
+
+IMPLEMENT_DYNAMIC(CPPageFileInfoSheet, CPropertySheet)
+CPPageFileInfoSheet::CPPageFileInfoSheet(CString fn, CMainFrame* pParentWnd)
+ : CPropertySheet(ResStr(IDS_PROPSHEET_PROPERTIES), pParentWnd, 0)
+ , m_clip(fn, pParentWnd->pGB)
+ , m_details(fn, pParentWnd->pGB, pParentWnd->m_pCAP)
+ , m_res(fn, pParentWnd->pGB)
+{
+ AddPage(&m_clip);
+ AddPage(&m_details);
+
+ BeginEnumFilters(pParentWnd->pGB, pEF, pBF)
+ {
+ if(CComQIPtr<IDSMResourceBag> pRB = pBF)
+ if(pRB && pRB->ResGetCount() > 0)
+ {
+ AddPage(&m_res);
+ break;
+ }
+ }
+ EndEnumFilters
+}
+
+CPPageFileInfoSheet::~CPPageFileInfoSheet()
+{
+}
+
+
+BEGIN_MESSAGE_MAP(CPPageFileInfoSheet, CPropertySheet)
+END_MESSAGE_MAP()
+
+// CPPageFileInfoSheet message handlers
+
+BOOL CPPageFileInfoSheet::OnInitDialog()
+{
+ BOOL fRet = __super::OnInitDialog();
+
+ GetDlgItem(IDCANCEL)->ShowWindow(SW_HIDE);
+ GetDlgItem(ID_APPLY_NOW)->ShowWindow(SW_HIDE);
+ GetDlgItem(IDOK)->SetWindowText(_T("Close"));
+
+ CRect r;
+ GetDlgItem(ID_APPLY_NOW)->GetWindowRect(&r);
+ ScreenToClient(r);
+ GetDlgItem(IDOK)->MoveWindow(r);
+
+ return fRet;
+}
+
diff --git a/src/apps/mplayerc/PPageFileInfoSheet.h b/src/apps/mplayerc/PPageFileInfoSheet.h
new file mode 100644
index 000000000..1a80ecad5
--- /dev/null
+++ b/src/apps/mplayerc/PPageFileInfoSheet.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "PPageFileInfoClip.h"
+#include "PPageFileInfoDetails.h"
+#include "PPageFileInfoRes.h"
+
+class CMainFrame;
+
+// CPPageFileInfoSheet
+
+class CPPageFileInfoSheet : public CPropertySheet
+{
+ DECLARE_DYNAMIC(CPPageFileInfoSheet)
+
+private:
+ CPPageFileInfoClip m_clip;
+ CPPageFileInfoDetails m_details;
+ CPPageFileInfoRes m_res;
+
+public:
+ CPPageFileInfoSheet(CString fn, CMainFrame* pParentWnd);
+ virtual ~CPPageFileInfoSheet();
+
+protected:
+ virtual BOOL OnInitDialog();
+
+ DECLARE_MESSAGE_MAP()
+};
+
+
diff --git a/src/apps/mplayerc/PPageFormats.cpp b/src/apps/mplayerc/PPageFormats.cpp
new file mode 100644
index 000000000..847fe4644
--- /dev/null
+++ b/src/apps/mplayerc/PPageFormats.cpp
@@ -0,0 +1,767 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageFormats.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PPageFormats.h"
+
+// CPPageFormats dialog
+
+IMPLEMENT_DYNAMIC(CPPageFormats, CPPageBase)
+CPPageFormats::CPPageFormats()
+ : CPPageBase(CPPageFormats::IDD, CPPageFormats::IDD)
+ , m_list(0)
+ , m_exts(_T(""))
+ , m_iRtspHandler(0)
+ , m_fRtspFileExtFirst(FALSE)
+{
+}
+
+CPPageFormats::~CPPageFormats()
+{
+}
+
+void CPPageFormats::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_LIST1, m_list);
+ DDX_Text(pDX, IDC_EDIT1, m_exts);
+ DDX_Control(pDX, IDC_STATIC1, m_autoplay);
+ DDX_Control(pDX, IDC_CHECK1, m_apvideo);
+ DDX_Control(pDX, IDC_CHECK2, m_apmusic);
+ DDX_Control(pDX, IDC_CHECK3, m_apaudiocd);
+ DDX_Control(pDX, IDC_CHECK4, m_apdvd);
+ DDX_Radio(pDX, IDC_RADIO1, m_iRtspHandler);
+ DDX_Check(pDX, IDC_CHECK5, m_fRtspFileExtFirst);
+}
+
+int CPPageFormats::GetChecked(int iItem)
+{
+ LVITEM lvi;
+ lvi.iItem = iItem;
+ lvi.iSubItem = 0;
+ lvi.mask = LVIF_IMAGE;
+ m_list.GetItem(&lvi);
+ return(lvi.iImage);
+}
+
+void CPPageFormats::SetChecked(int iItem, int iChecked)
+{
+ LVITEM lvi;
+ lvi.iItem = iItem;
+ lvi.iSubItem = 0;
+ lvi.mask = LVIF_IMAGE;
+ lvi.iImage = iChecked;
+ m_list.SetItem(&lvi);
+}
+
+static bool MakeRegParams(CString ext, CString& path, CString& fn, CString& extfile, CString& cmd)
+{
+ if(ext.GetLength() == 0)
+ return(false);
+
+ TCHAR buff[MAX_PATH];
+ if(::GetModuleFileName(AfxGetInstanceHandle(), buff, MAX_PATH) == 0)
+ return(false);
+
+ path = buff;
+
+ fn = path.Mid(path.ReverseFind('\\')+1).MakeLower();
+ if(fn.IsEmpty())
+ return(false);
+
+ extfile = ext.TrimLeft('.')+_T("file");
+
+ cmd = _T("\"") + path + _T("\" \"%1\"");
+
+ return(true);
+}
+
+bool CPPageFormats::IsRegistered(CString ext)
+{
+ CString path, fn, extfile, cmd;
+ if(!MakeRegParams(ext, path, fn, extfile, cmd))
+ return(false);
+
+ TCHAR buff[256];
+ ULONG len = sizeof(buff);
+ memset(buff, 0, len);
+
+ CRegKey key;
+
+ CString ExplExt = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\") + ext;
+ if(ERROR_SUCCESS == key.Open(HKEY_CURRENT_USER, ExplExt, KEY_READ))
+ {
+ len = sizeof(buff);
+ memset(buff, 0, len);
+ if(ERROR_SUCCESS == key.QueryStringValue(_T("Application"), buff, &len))
+ return(CString(buff).Trim() == cmd);
+ }
+
+ if(ERROR_SUCCESS != key.Open(HKEY_CLASSES_ROOT, ext, KEY_READ))
+ return(false);
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+ if(ERROR_SUCCESS != key.QueryStringValue(NULL, buff, &len) || (extfile = buff).Trim().IsEmpty())
+ return(false);
+
+ if(ERROR_SUCCESS != key.Open(HKEY_CLASSES_ROOT, extfile + _T("\\shell\\open\\command"), KEY_READ))
+ return(false);
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+
+ CRegKey key2;
+ if(ERROR_SUCCESS == key2.Open(HKEY_CLASSES_ROOT, extfile + _T("\\shell\\open"), KEY_READ)
+ && ERROR_SUCCESS == key2.QueryStringValue(_T("LegacyDisable"), buff, &len))
+ return(false);
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+
+ if(ERROR_SUCCESS == key2.Open(HKEY_CLASSES_ROOT, extfile + _T("\\shell\\open\\DropTarget"), KEY_READ))
+ return(false);
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+
+ return(ERROR_SUCCESS == key.QueryStringValue(NULL, buff, &len)
+ && !CString(buff).CompareNoCase(cmd));
+}
+
+bool CPPageFormats::RegisterExt(CString ext, bool fRegister)
+{
+ if(fRegister == IsRegistered(ext))
+ return(true);
+
+ CString path, fn, extfile, cmd;
+ if(!MakeRegParams(ext, path, fn, extfile, cmd))
+ return(false);
+
+ TCHAR buff[256];
+ ULONG len = sizeof(buff);
+ memset(buff, 0, len);
+
+ CRegKey key;
+
+ if(ERROR_SUCCESS != key.Create(HKEY_CLASSES_ROOT, ext))
+ return(false);
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+
+ if(ERROR_SUCCESS == key.QueryStringValue(NULL, buff, &len) && !CString(buff).Trim().IsEmpty())
+ {
+ extfile = buff;
+ }
+ else
+ {
+ if(!fRegister) return(true);
+ else if(ERROR_SUCCESS != key.SetStringValue(NULL, extfile)) return(false);
+ }
+
+ if(fRegister)
+ {
+ if(ERROR_SUCCESS != key.Create(HKEY_CLASSES_ROOT, extfile + _T("\\shell")))
+ return(false);
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+
+ key.QueryStringValue(NULL, buff, &len);
+
+ if(ERROR_SUCCESS != key.SetStringValue(fn + _T(".bak"), buff))
+ return(false);
+
+ if(ERROR_SUCCESS != key.SetStringValue(NULL, _T("open")))
+ {
+ key.SetStringValue(NULL, buff);
+ key.DeleteValue(fn + _T(".bak"));
+ return(false);
+ }
+
+ if(ERROR_SUCCESS != key.Create(HKEY_CLASSES_ROOT, extfile + _T("\\shell\\open")))
+ return(false);
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+
+ if(ERROR_SUCCESS != key.SetStringValue(NULL, _T("&Open")))
+ return(false);
+
+ if(ERROR_SUCCESS != key.Create(HKEY_CLASSES_ROOT, extfile + _T("\\shell\\open\\command")))
+ return(false);
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+
+ key.QueryStringValue(NULL, buff, &len);
+
+ if(CString(buff).MakeLower() == cmd)
+ return(true);
+
+ if(ERROR_SUCCESS != key.SetStringValue(fn + _T(".bak"), buff))
+ return(false);
+
+ if(ERROR_SUCCESS != key.SetStringValue(NULL, cmd))
+ {
+ key.SetStringValue(NULL, buff);
+ key.DeleteValue(fn + _T(".bak"));
+ return(false);
+ }
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, extfile + _T("\\shell\\open")))
+ {
+ if(ERROR_SUCCESS == key.QueryStringValue(_T("LegacyDisable"), buff, &len))
+ {
+ key.DeleteValue(_T("LegacyDisable"));
+ key.SetStringValue(_T("LegacyDisable.bak"), _T(""));
+ }
+
+ key.RecurseDeleteKey(_T("ddeexec"));
+ key.RecurseDeleteKey(_T("DropTarget"));
+ }
+
+ if(ERROR_SUCCESS == key.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\") + ext))
+ {
+ key.DeleteValue(_T("Application"));
+ }
+ }
+ else
+ {
+ if(ERROR_SUCCESS != key.Open(HKEY_CLASSES_ROOT, extfile + _T("\\shell\\open\\command")))
+ return(true);
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+
+ if(ERROR_SUCCESS != key.QueryStringValue(fn + _T(".bak"), buff, &len))
+ buff[0] = 0; //return(true);
+
+ if(CString(buff).Trim().IsEmpty())
+ {
+ if(ERROR_SUCCESS != key.Open(HKEY_CLASSES_ROOT, extfile + _T("\\shell\\open"))
+ || ERROR_SUCCESS != key.RecurseDeleteKey(_T("command")))
+ return(false);
+ }
+ else
+ {
+ if(ERROR_SUCCESS != key.SetStringValue(NULL, buff)
+ || ERROR_SUCCESS != key.DeleteValue(fn + _T(".bak")))
+ return(false);
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, extfile + _T("\\shell\\open"))
+ && ERROR_SUCCESS == key.QueryStringValue(_T("LegacyDisable.bak"), buff, &len))
+ {
+ key.DeleteValue(_T("LegacyDisable.bak"));
+ key.SetStringValue(_T("LegacyDisable"), _T(""));
+ }
+ }
+
+ if(ERROR_SUCCESS != key.Open(HKEY_CLASSES_ROOT, extfile + _T("\\shell")))
+ return(true);
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+
+ if(ERROR_SUCCESS != key.QueryStringValue(fn + _T(".bak"), buff, &len))
+ return(true);
+
+ if(CString(buff).Trim().IsEmpty())
+ {
+ if(ERROR_SUCCESS != key.Open(HKEY_CLASSES_ROOT, extfile)
+ || ERROR_SUCCESS != key.RecurseDeleteKey(_T("shell")))
+ return(false);
+ }
+ else
+ {
+ if(ERROR_SUCCESS != key.SetStringValue(NULL, buff)
+ || ERROR_SUCCESS != key.DeleteValue(fn + _T(".bak")))
+ return(false);
+ }
+ }
+
+ return(true);
+}
+
+static struct {TCHAR verb[20], cmd[20], action[100];} handlers[] =
+{
+ {_T("VideoFiles"), _T(" %1"), _T("")},
+ {_T("MusicFiles"), _T(" %1"), _T("")},
+ {_T("CDAudio"), _T(" %1 /cd"), _T("")},
+ {_T("DVDMovie"), _T(" %1 /dvd"), _T("")},
+};
+
+void CPPageFormats::AddAutoPlayToRegistry(autoplay_t ap, bool fRegister)
+{
+ if(!AfxGetAppSettings().fXpOrBetter) return;
+
+ TCHAR buff[MAX_PATH];
+ if(::GetModuleFileName(AfxGetInstanceHandle(), buff, MAX_PATH) == 0) return;
+ CString exe = buff;
+
+ int i = (int)ap;
+ if(i < 0 || i >= countof(handlers)) return;
+
+ CRegKey key;
+
+ if(fRegister)
+ {
+ if(ERROR_SUCCESS != key.Create(HKEY_CLASSES_ROOT, _T("MediaPlayerClassic.Autorun"))) return;
+ key.Close();
+
+ if(ERROR_SUCCESS != key.Create(HKEY_CLASSES_ROOT,
+ CString(_T("MediaPlayerClassic.Autorun\\Shell\\Play")) + handlers[i].verb + _T("\\Command"))) return;
+ key.SetStringValue(NULL, exe + handlers[i].cmd);
+ key.Close();
+
+ if(ERROR_SUCCESS != key.Create(HKEY_LOCAL_MACHINE,
+ CString(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoplayHandlers\\Handlers\\MPCPlay")) + handlers[i].verb + _T("OnArrival"))) return;
+ key.SetStringValue(_T("Action"), handlers[i].action);
+ key.SetStringValue(_T("Provider"), _T("Media Player Classic"));
+ key.SetStringValue(_T("InvokeProgID"), _T("MediaPlayerClassic.Autorun"));
+ key.SetStringValue(_T("InvokeVerb"), CString(_T("Play")) + handlers[i].verb);
+ key.SetStringValue(_T("DefaultIcon"), exe + _T(",0"));
+ key.Close();
+
+ if(ERROR_SUCCESS != key.Create(HKEY_LOCAL_MACHINE,
+ CString(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoplayHandlers\\EventHandlers\\Play")) + handlers[i].verb + _T("OnArrival"))) return;
+ key.SetStringValue(CString(_T("MPCPlay")) + handlers[i].verb + _T("OnArrival"), _T(""));
+ key.Close();
+ }
+ else
+ {
+ if(ERROR_SUCCESS != key.Create(HKEY_LOCAL_MACHINE,
+ CString(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoplayHandlers\\EventHandlers\\Play")) + handlers[i].verb + _T("OnArrival"))) return;
+ key.DeleteValue(CString(_T("MPCPlay")) + handlers[i].verb + _T("OnArrival"));
+ key.Close();
+ }
+}
+
+bool CPPageFormats::IsAutoPlayRegistered(autoplay_t ap)
+{
+ ULONG len;
+ TCHAR buff[MAX_PATH];
+ if(::GetModuleFileName(AfxGetInstanceHandle(), buff, MAX_PATH) == 0) return(false);
+ CString exe = buff;
+
+ int i = (int)ap;
+ if(i < 0 || i >= countof(handlers)) return(false);
+
+ CRegKey key;
+
+ if(ERROR_SUCCESS != key.Open(HKEY_LOCAL_MACHINE,
+ CString(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoplayHandlers\\EventHandlers\\Play")) + handlers[i].verb + _T("OnArrival"),
+ KEY_READ)) return(false);
+ len = countof(buff);
+ if(ERROR_SUCCESS != key.QueryStringValue(
+ CString(_T("MPCPlay")) + handlers[i].verb + _T("OnArrival"),
+ buff, &len)) return(false);
+ key.Close();
+
+ if(ERROR_SUCCESS != key.Open(HKEY_CLASSES_ROOT,
+ CString(_T("MediaPlayerClassic.Autorun\\Shell\\Play")) + handlers[i].verb + _T("\\Command"),
+ KEY_READ)) return(false);
+ len = countof(buff);
+ if(ERROR_SUCCESS != key.QueryStringValue(NULL, buff, &len))
+ return(false);
+ if(_tcsnicmp(exe, buff, exe.GetLength()))
+ return(false);
+ key.Close();
+
+ return(true);
+}
+
+void CPPageFormats::SetListItemState(int nItem)
+{
+ if(nItem < 0) return;
+
+ CString str = AfxGetAppSettings().Formats[(int)m_list.GetItemData(nItem)].GetExtsWithPeriod();
+
+ CAtlList<CString> exts;
+ ExplodeMin(str, exts, ' ');
+
+ int cnt = 0;
+
+ POSITION pos = exts.GetHeadPosition();
+ while(pos) if(IsRegistered(exts.GetNext(pos))) cnt++;
+
+ SetChecked(nItem, cnt == 0 ? 0 : cnt == exts.GetCount() ? 1 : 2);
+}
+
+BEGIN_MESSAGE_MAP(CPPageFormats, CPPageBase)
+ ON_NOTIFY(NM_CLICK, IDC_LIST1, OnNMClickList1)
+ ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, OnLvnItemchangedList1)
+ ON_NOTIFY(LVN_BEGINLABELEDIT, IDC_LIST1, OnBeginlabeleditList)
+ ON_NOTIFY(LVN_DOLABELEDIT, IDC_LIST1, OnDolabeleditList)
+ ON_NOTIFY(LVN_ENDLABELEDIT, IDC_LIST1, OnEndlabeleditList)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+ ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton12)
+ ON_BN_CLICKED(IDC_BUTTON_EXT_SET, OnBnClickedButton11)
+ ON_BN_CLICKED(IDC_BUTTON4, OnBnClickedButton14)
+ ON_BN_CLICKED(IDC_BUTTON3, OnBnClickedButton13)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateButtonDefault)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON_EXT_SET, OnUpdateButtonSet)
+END_MESSAGE_MAP()
+
+// CPPageFormats message handlers
+
+BOOL CPPageFormats::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ _tcscpy(handlers[0].action, ResStr(IDS_AUTOPLAY_PLAYVIDEO));
+ _tcscpy(handlers[1].action, ResStr(IDS_AUTOPLAY_PLAYMUSIC));
+ _tcscpy(handlers[2].action, ResStr(IDS_AUTOPLAY_PLAYAUDIOCD));
+ _tcscpy(handlers[3].action, ResStr(IDS_AUTOPLAY_PLAYDVDMOVIE));
+
+ m_list.SetExtendedStyle(m_list.GetExtendedStyle()|LVS_EX_FULLROWSELECT);
+
+ m_list.InsertColumn(COL_CATEGORY, _T("Category"), LVCFMT_LEFT, 300);
+ m_list.InsertColumn(COL_ENGINE, _T("Engine"), LVCFMT_RIGHT, 60);
+
+ m_onoff.Create(IDB_ONOFF, 12, 3, 0xffffff);
+ m_list.SetImageList(&m_onoff, LVSIL_SMALL);
+
+ CMediaFormats& mf = AfxGetAppSettings().Formats;
+ for(int i = 0; i < mf.GetCount(); i++)
+ {
+ CString label = mf[i].GetLabel();
+ // HACK: sorry, mpc is just not an image viewer :)
+ if(!label.CompareNoCase(_T("Image file"))) continue;
+ int iItem = m_list.InsertItem(i, label);
+ m_list.SetItemData(iItem, i);
+ engine_t e = mf[i].GetEngineType();
+ m_list.SetItemText(iItem, COL_ENGINE,
+ e == DirectShow ? _T("DirectShow") :
+ e == RealMedia ? _T("RealMedia") :
+ e == QuickTime ? _T("QuickTime") :
+ e == ShockWave ? _T("ShockWave") : _T("-"));
+ }
+
+// m_list.SetColumnWidth(COL_CATEGORY, LVSCW_AUTOSIZE);
+ m_list.SetColumnWidth(COL_ENGINE, LVSCW_AUTOSIZE_USEHEADER);
+
+ m_list.SetSelectionMark(0);
+ m_list.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);
+ m_exts = mf[(int)m_list.GetItemData(0)].GetExtsWithPeriod();
+
+ AppSettings& s = AfxGetAppSettings();
+ bool fRtspFileExtFirst;
+ engine_t e = s.Formats.GetRtspHandler(fRtspFileExtFirst);
+ m_iRtspHandler = (e==RealMedia?0:e==QuickTime?1:2);
+ m_fRtspFileExtFirst = fRtspFileExtFirst;
+
+ UpdateData(FALSE);
+
+ for(int i = 0; i < m_list.GetItemCount(); i++)
+ {
+ SetListItemState(i);
+ }
+
+ if(AfxGetAppSettings().fXpOrBetter)
+ {
+ m_apvideo.SetCheck(IsAutoPlayRegistered(AP_VIDEO));
+ m_apmusic.SetCheck(IsAutoPlayRegistered(AP_MUSIC));
+ m_apaudiocd.SetCheck(IsAutoPlayRegistered(AP_AUDIOCD));
+ m_apdvd.SetCheck(IsAutoPlayRegistered(AP_DVDMOVIE));
+ }
+ else
+ {
+ m_autoplay.ShowWindow(SW_HIDE);
+ m_apvideo.ShowWindow(SW_HIDE);
+ m_apmusic.ShowWindow(SW_HIDE);
+ m_apaudiocd.ShowWindow(SW_HIDE);
+ m_apdvd.ShowWindow(SW_HIDE);
+ }
+
+ CreateToolTip();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageFormats::OnApply()
+{
+ UpdateData();
+
+ {
+ int i = m_list.GetSelectionMark();
+ if(i >= 0) i = (int)m_list.GetItemData(i);
+ if(i >= 0)
+ {
+ CMediaFormats& mf = AfxGetAppSettings().Formats;
+ mf[i].SetExts(m_exts);
+ m_exts = mf[i].GetExtsWithPeriod();
+ UpdateData(FALSE);
+ }
+ }
+
+ CMediaFormats& mf = AfxGetAppSettings().Formats;
+
+ for(int i = 0; i < m_list.GetItemCount(); i++)
+ {
+ int iChecked = GetChecked(i);
+ if(iChecked == 2) continue;
+
+ CAtlList<CString> exts;
+ Explode(mf[(int)m_list.GetItemData(i)].GetExtsWithPeriod(), exts, ' ');
+
+ POSITION pos = exts.GetHeadPosition();
+ while(pos) RegisterExt(exts.GetNext(pos), !!iChecked);
+ }
+
+ {
+ SetListItemState(m_list.GetSelectionMark());
+ }
+
+ AddAutoPlayToRegistry(AP_VIDEO, !!m_apvideo.GetCheck());
+ AddAutoPlayToRegistry(AP_MUSIC, !!m_apmusic.GetCheck());
+ AddAutoPlayToRegistry(AP_AUDIOCD, !!m_apaudiocd.GetCheck());
+ AddAutoPlayToRegistry(AP_DVDMOVIE, !!m_apdvd.GetCheck());
+
+// SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
+
+ AppSettings& s = AfxGetAppSettings();
+ s.Formats.SetRtspHandler(m_iRtspHandler==0?RealMedia:m_iRtspHandler==1?QuickTime:DirectShow, !!m_fRtspFileExtFirst);
+
+ return __super::OnApply();
+}
+
+void CPPageFormats::OnNMClickList1(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)pNMHDR;
+
+ if(lpnmlv->iItem >= 0 && lpnmlv->iSubItem == COL_CATEGORY)
+ {
+ CRect r;
+ m_list.GetItemRect(lpnmlv->iItem, r, LVIR_ICON);
+ if(r.PtInRect(lpnmlv->ptAction))
+ {
+ SetChecked(lpnmlv->iItem, (GetChecked(lpnmlv->iItem)&1) == 0 ? 1 : 0);
+ SetModified();
+ }
+ }
+
+ *pResult = 0;
+}
+
+void CPPageFormats::OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
+
+ if(pNMLV->iItem >= 0 && pNMLV->iSubItem == COL_CATEGORY
+ && (pNMLV->uChanged&LVIF_STATE) && (pNMLV->uNewState&LVIS_SELECTED))
+ {
+ m_exts = AfxGetAppSettings().Formats[(int)m_list.GetItemData(pNMLV->iItem)].GetExtsWithPeriod();
+ UpdateData(FALSE);
+ }
+
+ *pResult = 0;
+}
+
+void CPPageFormats::OnBeginlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
+ LV_ITEM* pItem = &pDispInfo->item;
+
+ *pResult = FALSE;
+
+ if(pItem->iItem < 0)
+ return;
+
+ if(pItem->iSubItem == COL_ENGINE)
+ {
+ *pResult = TRUE;
+ }
+}
+
+void CPPageFormats::OnDolabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
+ LV_ITEM* pItem = &pDispInfo->item;
+
+ *pResult = FALSE;
+
+ if(pItem->iItem < 0)
+ return;
+
+ CMediaFormatCategory& mfc = AfxGetAppSettings().Formats[m_list.GetItemData(pItem->iItem)];
+
+ CAtlList<CString> sl;
+ int nSel = -1;
+
+ if(pItem->iSubItem == COL_ENGINE)
+ {
+ sl.AddTail(_T("DirectShow"));
+ sl.AddTail(_T("RealMedia"));
+ sl.AddTail(_T("QuickTime"));
+ sl.AddTail(_T("ShockWave"));
+
+ nSel = (int)mfc.GetEngineType();
+
+ m_list.ShowInPlaceComboBox(pItem->iItem, pItem->iSubItem, sl, nSel);
+
+ *pResult = TRUE;
+ }
+}
+
+void CPPageFormats::OnEndlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
+ LV_ITEM* pItem = &pDispInfo->item;
+
+ *pResult = FALSE;
+
+ if(!m_list.m_fInPlaceDirty)
+ return;
+
+ if(pItem->iItem < 0)
+ return;
+
+ CMediaFormatCategory& mfc = AfxGetAppSettings().Formats[m_list.GetItemData(pItem->iItem)];
+
+ if(pItem->iSubItem == COL_ENGINE && pItem->lParam >= 0)
+ {
+ mfc.SetEngineType((engine_t)pItem->lParam);
+ m_list.SetItemText(pItem->iItem, pItem->iSubItem, pItem->pszText);
+ *pResult = TRUE;
+ }
+
+ if(*pResult)
+ SetModified();
+}
+
+void CPPageFormats::OnBnClickedButton1()
+{
+ for(int i = 0, j = m_list.GetItemCount(); i < j; i++)
+ {
+ SetChecked(i, 1);
+ }
+
+ m_apvideo.SetCheck(1);
+ m_apmusic.SetCheck(1);
+ m_apaudiocd.SetCheck(1);
+ m_apdvd.SetCheck(1);
+
+ SetModified();
+}
+
+void CPPageFormats::OnBnClickedButton14()
+{
+ CMediaFormats& mf = AfxGetAppSettings().Formats;
+
+ for(int i = 0, j = m_list.GetItemCount(); i < j; i++)
+ {
+ SetChecked(i, mf[(int)m_list.GetItemData(i)].IsAudioOnly()?0:1);
+ }
+
+ m_apvideo.SetCheck(1);
+ m_apmusic.SetCheck(0);
+ m_apaudiocd.SetCheck(0);
+ m_apdvd.SetCheck(1);
+
+ SetModified();
+}
+
+void CPPageFormats::OnBnClickedButton13()
+{
+ CMediaFormats& mf = AfxGetAppSettings().Formats;
+
+ for(int i = 0, j = m_list.GetItemCount(); i < j; i++)
+ {
+ SetChecked(i, mf[(int)m_list.GetItemData(i)].IsAudioOnly()?1:0);
+ }
+
+ m_apvideo.SetCheck(0);
+ m_apmusic.SetCheck(1);
+ m_apaudiocd.SetCheck(1);
+ m_apdvd.SetCheck(0);
+
+ SetModified();
+}
+
+void CPPageFormats::OnBnClickedButton12()
+{
+ int i = m_list.GetSelectionMark();
+ if(i < 0) return;
+ i = (int)m_list.GetItemData(i);
+ CMediaFormats& mf = AfxGetAppSettings().Formats;
+ mf[i].RestoreDefaultExts();
+ m_exts = mf[i].GetExtsWithPeriod();
+ SetListItemState(m_list.GetSelectionMark());
+ UpdateData(FALSE);
+
+ SetModified();
+}
+
+void CPPageFormats::OnBnClickedButton11()
+{
+ UpdateData();
+ int i = m_list.GetSelectionMark();
+ if(i < 0) return;
+ i = (int)m_list.GetItemData(i);
+ CMediaFormats& mf = AfxGetAppSettings().Formats;
+ mf[i].SetExts(m_exts);
+ m_exts = mf[i].GetExtsWithPeriod();
+ SetListItemState(m_list.GetSelectionMark());
+ UpdateData(FALSE);
+
+ SetModified();
+}
+
+void CPPageFormats::OnUpdateButtonDefault(CCmdUI* pCmdUI)
+{
+ int i = m_list.GetSelectionMark();
+ if(i < 0) {pCmdUI->Enable(FALSE); return;}
+ i = (int)m_list.GetItemData(i);
+
+ CString orgexts, newexts;
+ GetDlgItem(IDC_EDIT1)->GetWindowText(newexts);
+ newexts.Trim();
+ orgexts = AfxGetAppSettings().Formats[i].GetBackupExtsWithPeriod();
+
+ pCmdUI->Enable(!!newexts.CompareNoCase(orgexts));
+}
+
+void CPPageFormats::OnUpdateButtonSet(CCmdUI* pCmdUI)
+{
+ int i = m_list.GetSelectionMark();
+ if(i < 0) {pCmdUI->Enable(FALSE); return;}
+ i = (int)m_list.GetItemData(i);
+
+ CString orgexts, newexts;
+ GetDlgItem(IDC_EDIT1)->GetWindowText(newexts);
+ newexts.Trim();
+ orgexts = AfxGetAppSettings().Formats[i].GetExtsWithPeriod();
+
+ pCmdUI->Enable(!!newexts.CompareNoCase(orgexts));
+}
diff --git a/src/apps/mplayerc/PPageFormats.h b/src/apps/mplayerc/PPageFormats.h
new file mode 100644
index 000000000..ce6698e65
--- /dev/null
+++ b/src/apps/mplayerc/PPageFormats.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "PPageBase.h"
+#include "PlayerListCtrl.h"
+
+// CPPageFormats dialog
+
+class CPPageFormats : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageFormats)
+
+private:
+ CImageList m_onoff;
+
+ int GetChecked(int iItem);
+ void SetChecked(int iItem, int fChecked);
+
+ typedef enum {AP_VIDEO=0,AP_MUSIC,AP_AUDIOCD,AP_DVDMOVIE} autoplay_t;
+ void AddAutoPlayToRegistry(autoplay_t ap, bool fRegister);
+ bool IsAutoPlayRegistered(autoplay_t ap);
+
+ void SetListItemState(int nItem);
+
+public:
+ CPPageFormats();
+ virtual ~CPPageFormats();
+
+ static bool IsRegistered(CString ext);
+ static bool RegisterExt(CString ext, bool fRegister);
+
+ enum {COL_CATEGORY, COL_ENGINE};
+ CPlayerListCtrl m_list;
+ CString m_exts;
+ CStatic m_autoplay;
+ CButton m_apvideo;
+ CButton m_apmusic;
+ CButton m_apaudiocd;
+ CButton m_apdvd;
+ int m_iRtspHandler;
+ BOOL m_fRtspFileExtFirst;
+
+// Dialog Data
+ enum { IDD = IDD_PPAGEFORMATS };
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnNMClickList1(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnBeginlabeleditList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnDolabeleditList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnEndlabeleditList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnBnClickedButton14();
+ afx_msg void OnBnClickedButton13();
+ afx_msg void OnBnClickedButton12();
+ afx_msg void OnBnClickedButton11();
+ afx_msg void OnUpdateButtonDefault(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateButtonSet(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/PPageInternalFilters.cpp b/src/apps/mplayerc/PPageInternalFilters.cpp
new file mode 100644
index 000000000..a65a59cd2
--- /dev/null
+++ b/src/apps/mplayerc/PPageInternalFilters.cpp
@@ -0,0 +1,292 @@
+
+
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageInternalFilters.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PPageInternalFilters.h"
+#include "ComPropertySheet.h"
+#include "..\..\filters\filters.h"
+
+static struct filter_t
+{
+ LPCTSTR label;
+ int type;
+ int flag;
+ UINT nHintID;
+ CUnknown* (WINAPI * CreateInstance)(LPUNKNOWN lpunk, HRESULT* phr);
+}
+s_filters[] =
+{
+ {_T("AVI"), 0, SRC_AVI, IDS_SRC_AVI, NULL},
+ {_T("CDDA (Audio CD)"), 0, SRC_CDDA, IDS_SRC_CDDA, NULL},
+ {_T("CDXA (VCD/SVCD/XCD)"), 0, SRC_CDXA, IDS_SRC_CDXA, NULL},
+ {_T("Dirac"), 0, SRC_DIRAC, IDS_SRC_DIRAC, NULL},
+ {_T("DirectShow Media"), 0, SRC_DSM, IDS_SRC_DSM, NULL},
+ {_T("DTS/AC3"), 0, SRC_DTSAC3, IDS_SRC_DTSAC3, NULL},
+ {_T("DVD Video Title Set"), 0, SRC_VTS, IDS_SRC_VTS, NULL},
+ {_T("DVD2AVI Project File"), 0, SRC_D2V, IDS_SRC_D2V, NULL},
+ {_T("FLI/FLC"), 0, SRC_FLIC, IDS_SRC_FLIC, NULL},
+ {_T("Matroska"), 0, SRC_MATROSKA, IDS_SRC_MATROSKA, NULL},
+ {_T("MP4/MOV"), 0, SRC_MP4, IDS_SRC_MP4, NULL},
+ {_T("MPEG Audio"), 0, SRC_MPA, IDS_SRC_MPA, NULL},
+ {_T("MPEG PS/TS/PVA"), 0, SRC_MPEG, 0, NULL},
+ {_T("Nut"), 0, SRC_NUT, IDS_SRC_NUT, NULL},
+ {_T("Ogg"), 0, SRC_OGG, IDS_SRC_OGG, NULL},
+ {_T("RealMedia"), 0, SRC_REALMEDIA, IDS_SRC_REALMEDIA, NULL},
+ {_T("RoQ"), 0, SRC_ROQ, IDS_SRC_ROQ, NULL},
+ {_T("SHOUTcast"), 0, SRC_SHOUTCAST, IDS_SRC_SHOUTCAST, NULL},
+ __if_exists(CRadGtSplitterFilter) {{_T("Smacker/Bink"), 0, SRC_RADGT, IDS_SRC_RADGT, NULL},}
+ {_T("AAC"), 1, TRA_AAC, IDS_TRA_AAC, CreateInstance<CMpaDecFilter>},
+ {_T("AC3"), 1, TRA_AC3, IDS_TRA_AC3, CreateInstance<CMpaDecFilter>},
+ {_T("DTS"), 1, TRA_DTS, IDS_TRA_DTS, CreateInstance<CMpaDecFilter>},
+ {_T("Dirac"), 1, TRA_DIRAC, IDS_TRA_DIRAC, NULL},
+ {_T("LPCM"), 1, TRA_LPCM, IDS_TRA_LPCM, CreateInstance<CMpaDecFilter>},
+ {_T("MPEG Audio"), 1, TRA_MPA, IDS_TRA_MPA, CreateInstance<CMpaDecFilter>},
+ {_T("MPEG-1 Video"), 1, TRA_MPEG1, IDS_TRA_MPEG1, CreateInstance<CMpeg2DecFilter>},
+ {_T("MPEG-2 Video"), 1, TRA_MPEG2, IDS_TRA_MPEG2, CreateInstance<CMpeg2DecFilter>},
+ {_T("PS2 Audio (PCM/ADPCM)"), 1, TRA_PS2AUD, IDS_TRA_PS2AUD, CreateInstance<CMpaDecFilter>},
+ {_T("RealVideo"), 1, TRA_RV, IDS_TRA_RV, NULL},
+ {_T("RealAudio"), 1, TRA_RA, IDS_TRA_RA, NULL},
+ {_T("Vorbis"), 1, TRA_VORBIS, 0, NULL /* TODO: CreateInstance<CMpaDecFilter>*/},
+};
+
+IMPLEMENT_DYNAMIC(CPPageInternalFiltersListBox, CCheckListBox)
+CPPageInternalFiltersListBox::CPPageInternalFiltersListBox()
+ : CCheckListBox()
+{
+}
+
+void CPPageInternalFiltersListBox::PreSubclassWindow()
+{
+ __super::PreSubclassWindow();
+ EnableToolTips(TRUE);
+}
+
+INT_PTR CPPageInternalFiltersListBox::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
+{
+ BOOL b = FALSE;
+ int row = ItemFromPoint(point, b);
+ if(row < 0) return -1;
+
+ CRect r;
+ GetItemRect(row, r);
+ pTI->rect = r;
+ pTI->hwnd = m_hWnd;
+ pTI->uId = (UINT)row;
+ pTI->lpszText = LPSTR_TEXTCALLBACK;
+ pTI->uFlags |= TTF_ALWAYSTIP;
+
+ return pTI->uId;
+}
+
+BEGIN_MESSAGE_MAP(CPPageInternalFiltersListBox, CCheckListBox)
+ ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify)
+ ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify)
+END_MESSAGE_MAP()
+
+BOOL CPPageInternalFiltersListBox::OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
+{
+ TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
+ TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
+
+ filter_t* f = (filter_t*)GetItemDataPtr(pNMHDR->idFrom);
+ if(f->nHintID == 0) return FALSE;
+
+ ::SendMessage(pNMHDR->hwndFrom, TTM_SETMAXTIPWIDTH, 0, (LPARAM)(INT)1000);
+
+ static CStringA m_strTipTextA;
+ static CStringW m_strTipTextW;
+
+ m_strTipTextA = CString(MAKEINTRESOURCE(f->nHintID));
+ m_strTipTextW = CString(MAKEINTRESOURCE(f->nHintID));
+
+ if(pNMHDR->code == TTN_NEEDTEXTA) pTTTA->lpszText = (LPSTR)(LPCSTR)m_strTipTextA;
+ else pTTTW->lpszText = (LPWSTR)(LPCWSTR)m_strTipTextW;
+
+ *pResult = 0;
+
+ return TRUE; // message was handled
+}
+
+void CPPageInternalFiltersListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
+{
+ CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
+
+ CFont* pOldFont = NULL;
+
+ if(((filter_t*)lpDrawItemStruct->itemData)->CreateInstance)
+ {
+ if(!(HFONT)m_bold)
+ {
+ CFont* pFont = pDC->GetCurrentFont();
+
+ LOGFONT lf;
+ pFont->GetLogFont(&lf);
+ lf.lfWeight = FW_BOLD;
+
+ m_bold.CreateFontIndirect(&lf);
+ }
+
+ if((HFONT)m_bold)
+ {
+ pOldFont = pDC->SelectObject(&m_bold);
+ }
+ }
+
+ __super::DrawItem(lpDrawItemStruct);
+
+ if(pOldFont)
+ {
+ pDC->SelectObject(pOldFont);
+ }
+}
+
+// CPPageInternalFilters dialog
+
+IMPLEMENT_DYNAMIC(CPPageInternalFilters, CPPageBase)
+CPPageInternalFilters::CPPageInternalFilters()
+ : CPPageBase(CPPageInternalFilters::IDD, CPPageInternalFilters::IDD)
+{
+}
+
+CPPageInternalFilters::~CPPageInternalFilters()
+{
+}
+
+
+void CPPageInternalFilters::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_LIST1, m_listSrc);
+ DDX_Control(pDX, IDC_LIST2, m_listTra);
+}
+
+BEGIN_MESSAGE_MAP(CPPageInternalFilters, CPPageBase)
+ ON_LBN_DBLCLK(IDC_LIST1, &CPPageInternalFilters::OnLbnDblclkList1)
+ ON_LBN_DBLCLK(IDC_LIST2, &CPPageInternalFilters::OnLbnDblclkList2)
+END_MESSAGE_MAP()
+
+// CPPageInternalFilters message handlers
+
+BOOL CPPageInternalFilters::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ for(int i = 0; i < countof(s_filters); i++)
+ {
+ CCheckListBox* l =
+ s_filters[i].type == 0 ? &m_listSrc :
+ s_filters[i].type == 1 ? &m_listTra :
+ NULL;
+
+ UINT* pflags =
+ s_filters[i].type == 0 ? &s.SrcFilters :
+ s_filters[i].type == 1 ? &s.TraFilters :
+ NULL;
+
+ if(l && pflags)
+ {
+ int Index = l->AddString(s_filters[i].label);
+ l->SetCheck(Index, !!(*pflags & s_filters[i].flag));
+ l->SetItemDataPtr(Index, &s_filters[i]);
+ }
+ }
+
+ UpdateData(FALSE);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageInternalFilters::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ s.SrcFilters = s.TraFilters = 0;
+
+ CList<filter_t*> fl;
+ for(int i = 0; i < m_listSrc.GetCount(); i++)
+ if(m_listSrc.GetCheck(i))
+ fl.AddTail((filter_t*)m_listSrc.GetItemDataPtr(i));
+ for(int i = 0; i < m_listTra.GetCount(); i++)
+ if(m_listTra.GetCheck(i))
+ fl.AddTail((filter_t*)m_listTra.GetItemDataPtr(i));
+
+ POSITION pos = fl.GetHeadPosition();
+ while(pos)
+ {
+ filter_t* f = fl.GetNext(pos);
+
+ UINT* pflags =
+ f->type == 0 ? &s.SrcFilters :
+ f->type == 1 ? &s.TraFilters :
+ NULL;
+
+ if(pflags)
+ *pflags |= f->flag;
+ }
+
+ return __super::OnApply();
+}
+
+void CPPageInternalFilters::ShowPPage(CPPageInternalFiltersListBox& l)
+{
+ int i = l.GetCurSel();
+ if(i < 0) return;
+
+ filter_t* f = (filter_t*)l.GetItemDataPtr(i);
+ if(!f || !f->CreateInstance) return;
+
+ HRESULT hr;
+ CUnknown* pObj = f->CreateInstance(NULL, &hr);
+ if(!pObj) return;
+
+ CComPtr<IUnknown> pUnk = (IUnknown*)(INonDelegatingUnknown*)pObj;
+
+ if(SUCCEEDED(hr))
+ {
+ if(CComQIPtr<ISpecifyPropertyPages> pSPP = pUnk)
+ {
+ CComPropertySheet ps(ResStr(IDS_PROPSHEET_PROPERTIES), this);
+ ps.AddPages(pSPP);
+ ps.DoModal();
+ }
+ }
+}
+
+void CPPageInternalFilters::OnLbnDblclkList1()
+{
+ ShowPPage(m_listSrc);
+}
+
+void CPPageInternalFilters::OnLbnDblclkList2()
+{
+ ShowPPage(m_listTra);
+}
diff --git a/src/apps/mplayerc/PPageInternalFilters.h b/src/apps/mplayerc/PPageInternalFilters.h
new file mode 100644
index 000000000..e1a24450f
--- /dev/null
+++ b/src/apps/mplayerc/PPageInternalFilters.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "PPageBase.h"
+#include "afxwin.h"
+
+class CPPageInternalFiltersListBox : public CCheckListBox
+{
+ DECLARE_DYNAMIC(CPPageInternalFiltersListBox)
+
+public:
+ CPPageInternalFiltersListBox();
+
+ CFont m_bold;
+
+protected:
+ virtual void PreSubclassWindow();
+ virtual INT_PTR OnToolHitTest(CPoint point, TOOLINFO* pTI) const;
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg BOOL OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult);
+
+public:
+ virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
+};
+
+// CPPageInternalFilters dialog
+
+class CPPageInternalFilters : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageInternalFilters)
+
+public:
+ CPPageInternalFilters();
+ virtual ~CPPageInternalFilters();
+
+// Dialog Data
+ enum { IDD = IDD_PPAGEINTERNALFILTERS };
+ CPPageInternalFiltersListBox m_listSrc;
+ CPPageInternalFiltersListBox m_listTra;
+
+ void ShowPPage(CPPageInternalFiltersListBox& l);
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnLbnDblclkList1();
+ afx_msg void OnLbnDblclkList2();
+};
diff --git a/src/apps/mplayerc/PPageLogo.cpp b/src/apps/mplayerc/PPageLogo.cpp
new file mode 100644
index 000000000..561ce08bf
--- /dev/null
+++ b/src/apps/mplayerc/PPageLogo.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// CPPageLogo.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "MainFrm.h"
+#include "PPageLogo.h"
+
+// CPPageLogo dialog
+
+IMPLEMENT_DYNAMIC(CPPageLogo, CPPageBase)
+CPPageLogo::CPPageLogo()
+ : CPPageBase(CPPageLogo::IDD, CPPageLogo::IDD)
+ , m_intext(0)
+ , m_logofn(_T(""))
+ , m_author(_T(""))
+{
+ m_logoids.AddTail(IDB_LOGO0);
+ m_logoids.AddTail(IDB_LOGO1);
+ m_logoids.AddTail(IDB_LOGO2);
+ m_logoids.AddTail(IDB_LOGO3);
+ m_logoids.AddTail(IDB_LOGO4);
+ m_logoids.AddTail(IDB_LOGO5);
+ m_logoids.AddTail(IDB_LOGO6);
+ m_logoids.AddTail(IDB_LOGO7);
+}
+
+CPPageLogo::~CPPageLogo()
+{
+}
+
+void CPPageLogo::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Radio(pDX, IDC_RADIO1, m_intext);
+ DDX_Text(pDX, IDC_LOGOFILENAME, m_logofn);
+ DDX_Control(pDX, IDC_LOGOPREVIEW, m_logopreview);
+ DDX_Text(pDX, IDC_AUTHOR, m_author);
+}
+
+
+BEGIN_MESSAGE_MAP(CPPageLogo, CPPageBase)
+ ON_BN_CLICKED(IDC_RADIO1, OnBnClickedRadio1)
+ ON_BN_CLICKED(IDC_RADIO2, OnBnClickedRadio2)
+ ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN1, OnDeltaposSpin1)
+ ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
+END_MESSAGE_MAP()
+
+
+// CPPageLogo message handlers
+
+BOOL CPPageLogo::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_intext = s.logoext?1:0;
+ m_logofn = s.logofn;
+ m_logoidpos = NULL;
+
+ UpdateData(FALSE);
+
+ for(POSITION pos = m_logoids.GetHeadPosition(); pos; m_logoids.GetNext(pos))
+ {
+ if(m_logoids.GetAt(pos) == s.logoid)
+ {
+ m_logoidpos = pos;
+ break;
+ }
+ }
+
+ if(!m_intext) OnBnClickedRadio1();
+ else OnBnClickedRadio2();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageLogo::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ s.logoext = !!m_intext;
+ s.logofn = m_logofn;
+ s.logoid = m_logoids.GetAt(m_logoidpos);
+
+ ((CMainFrame*)AfxGetMainWnd())->m_wndView.LoadLogo();
+
+ return __super::OnApply();
+}
+
+
+void CPPageLogo::OnBnClickedRadio1()
+{
+ ASSERT(m_logoidpos);
+
+ m_author.Empty();
+
+ m_logobm.Destroy();
+ UINT id = m_logoids.GetAt(m_logoidpos);
+ if(IDB_LOGO0 != id)
+ {
+ m_logobm.LoadFromResource(::AfxGetInstanceHandle(), id);
+ if(!m_author.LoadString(id))
+ m_author = _T("Author unknown. Contact me if you made this logo!");
+ }
+ m_logopreview.SetBitmap(m_logobm);
+ Invalidate();
+
+ m_intext = 0;
+ UpdateData(FALSE);
+
+ SetModified();
+}
+
+void CPPageLogo::OnBnClickedRadio2()
+{
+ UpdateData();
+
+ m_author.Empty();
+
+ m_logobm.Destroy();
+ if(AfxGetAppSettings().fXpOrBetter)
+ m_logobm.Load(m_logofn);
+ else if(HANDLE h = LoadImage(NULL, m_logofn, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE))
+ m_logobm.Attach((HBITMAP)h);
+ m_logopreview.SetBitmap(m_logobm);
+ Invalidate();
+
+ m_intext = 1;
+ UpdateData(FALSE);
+
+ SetModified();
+}
+
+void CPPageLogo::OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
+
+ if(pNMUpDown->iDelta < 0)
+ {
+ m_logoids.GetNext(m_logoidpos);
+ if(!m_logoidpos) m_logoidpos = m_logoids.GetHeadPosition();
+ }
+ else
+ {
+ m_logoids.GetPrev(m_logoidpos);
+ if(!m_logoidpos) m_logoidpos = m_logoids.GetTailPosition();
+ }
+
+ OnBnClickedRadio1();
+
+ *pResult = 0;
+}
+
+void CPPageLogo::OnBnClickedButton2()
+{
+ CFileDialog dlg(TRUE, NULL, m_logofn,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY,
+ AfxGetAppSettings().fXpOrBetter
+ ? _T("Images (*.bmp;*.jpg;*.gif;*.png)|*.bmp;*.jpg;*.gif;*.png|All files (*.*)|*.*||")
+ : _T("Images (*.bmp)|*.bmp|All files (*.*)|*.*||")
+ , this, 0);
+
+ if(dlg.DoModal() == IDOK)
+ {
+ m_logofn = dlg.GetPathName();
+ UpdateData(FALSE);
+ OnBnClickedRadio2();
+ }
+}
diff --git a/src/apps/mplayerc/PPageLogo.h b/src/apps/mplayerc/PPageLogo.h
new file mode 100644
index 000000000..cf354a932
--- /dev/null
+++ b/src/apps/mplayerc/PPageLogo.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <atlimage.h>
+
+// CPPageLogo dialog
+
+class CPPageLogo : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageLogo)
+
+private:
+ CList<UINT> m_logoids;
+ POSITION m_logoidpos;
+ CImage m_logobm;
+
+public:
+ CPPageLogo();
+ virtual ~CPPageLogo();
+
+// Dialog Data
+ enum { IDD = IDD_PPAGELOGO };
+ int m_intext;
+ CString m_logofn;
+ CStatic m_logopreview;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnBnClickedRadio1();
+ afx_msg void OnBnClickedRadio2();
+ afx_msg void OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnBnClickedButton2();
+ CString m_author;
+};
diff --git a/src/apps/mplayerc/PPageOutput.cpp b/src/apps/mplayerc/PPageOutput.cpp
new file mode 100644
index 000000000..50b61e413
--- /dev/null
+++ b/src/apps/mplayerc/PPageOutput.cpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// CPPageOutput.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "MainFrm.h"
+#include "PPageOutput.h"
+#include "../../../include/moreuuids.h"
+
+// CPPageOutput dialog
+
+IMPLEMENT_DYNAMIC(CPPageOutput, CPPageBase)
+CPPageOutput::CPPageOutput()
+ : CPPageBase(CPPageOutput::IDD, CPPageOutput::IDD)
+ , m_iDSVideoRendererType(0)
+ , m_iRMVideoRendererType(0)
+ , m_iQTVideoRendererType(0)
+ , m_iAPSurfaceUsage(0)
+ , m_iAudioRendererType(0)
+ , m_fVMRSyncFix(FALSE)
+ , m_iDX9Resizer(0)
+ , m_fVMR9MixerMode(FALSE)
+ , m_fVMR9MixerYUV(FALSE)
+{
+}
+
+CPPageOutput::~CPPageOutput()
+{
+}
+
+void CPPageOutput::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Radio(pDX, IDC_DSSYSDEF, m_iDSVideoRendererType);
+ DDX_Radio(pDX, IDC_RMSYSDEF, m_iRMVideoRendererType);
+ DDX_Radio(pDX, IDC_QTSYSDEF, m_iQTVideoRendererType);
+ DDX_Radio(pDX, IDC_REGULARSURF, m_iAPSurfaceUsage);
+ DDX_CBIndex(pDX, IDC_COMBO1, m_iAudioRendererType);
+ DDX_Control(pDX, IDC_COMBO1, m_iAudioRendererTypeCtrl);
+ DDX_Check(pDX, IDC_CHECK1, m_fVMRSyncFix);
+ DDX_CBIndex(pDX, IDC_DX9RESIZER_COMBO, m_iDX9Resizer);
+ DDX_Check(pDX, IDC_DSVMR9LOADMIXER, m_fVMR9MixerMode);
+ DDX_Check(pDX, IDC_DSVMR9YUVMIXER, m_fVMR9MixerYUV);
+}
+
+BEGIN_MESSAGE_MAP(CPPageOutput, CPPageBase)
+ ON_UPDATE_COMMAND_UI(IDC_DSVMR9YUVMIXER, OnUpdateMixerYUV)
+END_MESSAGE_MAP()
+
+void CPPageOutput::DisableRadioButton(UINT nID, UINT nDefID)
+{
+ if(IsDlgButtonChecked(nID))
+ {
+ CheckDlgButton(nID, BST_UNCHECKED);
+ CheckDlgButton(nDefID, BST_CHECKED);
+ }
+
+ GetDlgItem(nID)->EnableWindow(FALSE);
+}
+
+// CPPageOutput message handlers
+
+BOOL CPPageOutput::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_iDSVideoRendererType = s.iDSVideoRendererType;
+ m_iRMVideoRendererType = s.iRMVideoRendererType;
+ m_iQTVideoRendererType = s.iQTVideoRendererType;
+ m_iAPSurfaceUsage = s.iAPSurfaceUsage;
+ m_fVMRSyncFix = s.fVMRSyncFix;
+ m_iDX9Resizer = s.iDX9Resizer;
+ m_fVMR9MixerMode = s.fVMR9MixerMode;
+ m_fVMR9MixerYUV = s.fVMR9MixerYUV;
+
+ m_AudioRendererDisplayNames.Add(_T(""));
+ m_iAudioRendererTypeCtrl.AddString(_T("System Default"));
+ m_iAudioRendererType = 0;
+
+ BeginEnumSysDev(CLSID_AudioRendererCategory, pMoniker)
+ {
+ LPOLESTR olestr = NULL;
+ if(FAILED(pMoniker->GetDisplayName(0, 0, &olestr)))
+ continue;
+
+ CStringW str(olestr);
+ CoTaskMemFree(olestr);
+
+ m_AudioRendererDisplayNames.Add(CString(str));
+
+ CComPtr<IPropertyBag> pPB;
+ if(SUCCEEDED(pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB)))
+ {
+ CComVariant var;
+ pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL);
+
+ CString fstr(var.bstrVal);
+
+ var.Clear();
+ if(SUCCEEDED(pPB->Read(CComBSTR(_T("FilterData")), &var, NULL)))
+ {
+ BSTR* pbstr;
+ if(SUCCEEDED(SafeArrayAccessData(var.parray, (void**)&pbstr)))
+ {
+ fstr.Format(_T("%s (%08x)"), CString(fstr), *((DWORD*)pbstr + 1));
+ SafeArrayUnaccessData(var.parray);
+ }
+ }
+
+ m_iAudioRendererTypeCtrl.AddString(fstr);
+ }
+ else
+ {
+ m_iAudioRendererTypeCtrl.AddString(CString(str));
+ }
+
+ if(s.AudioRendererDisplayName == str && m_iAudioRendererType == 0)
+ {
+ m_iAudioRendererType = m_iAudioRendererTypeCtrl.GetCount()-1;
+ }
+ }
+ EndEnumSysDev
+
+ m_AudioRendererDisplayNames.Add(AUDRNDT_NULL_COMP);
+ m_iAudioRendererTypeCtrl.AddString(AUDRNDT_NULL_COMP);
+ if(s.AudioRendererDisplayName == AUDRNDT_NULL_COMP && m_iAudioRendererType == 0)
+ m_iAudioRendererType = m_iAudioRendererTypeCtrl.GetCount()-1;
+
+ m_AudioRendererDisplayNames.Add(AUDRNDT_NULL_UNCOMP);
+ m_iAudioRendererTypeCtrl.AddString(AUDRNDT_NULL_UNCOMP);
+ if(s.AudioRendererDisplayName == AUDRNDT_NULL_UNCOMP && m_iAudioRendererType == 0)
+ m_iAudioRendererType = m_iAudioRendererTypeCtrl.GetCount()-1;
+
+ CorrectComboListWidth(m_iAudioRendererTypeCtrl, GetFont());
+
+ UpdateData(FALSE);
+
+ if(!IsCLSIDRegistered(CLSID_VideoMixingRenderer))
+ {
+ DisableRadioButton(IDC_DSVMR7WIN, IDC_DSSYSDEF);
+ DisableRadioButton(IDC_DSVMR7REN, IDC_DSSYSDEF);
+ }
+
+ if(!IsCLSIDRegistered(CLSID_VideoMixingRenderer9))
+ {
+ DisableRadioButton(IDC_DSVMR9WIN, IDC_DSSYSDEF);
+ DisableRadioButton(IDC_DSVMR9REN, IDC_DSSYSDEF);
+ DisableRadioButton(IDC_RMDX9, IDC_RMSYSDEF);
+ DisableRadioButton(IDC_QTDX9, IDC_QTSYSDEF);
+ }
+
+ if(!IsCLSIDRegistered(CLSID_DXR))
+ {
+ DisableRadioButton(IDC_DSDXR, IDC_DSSYSDEF);
+ }
+
+ CreateToolTip();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageOutput::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ s.iDSVideoRendererType = m_iDSVideoRendererType;
+ s.iRMVideoRendererType = m_iRMVideoRendererType;
+ s.iQTVideoRendererType = m_iQTVideoRendererType;
+ s.iAPSurfaceUsage = m_iAPSurfaceUsage;
+ s.fVMRSyncFix = !!m_fVMRSyncFix;
+ s.AudioRendererDisplayName = m_AudioRendererDisplayNames[m_iAudioRendererType];
+ s.iDX9Resizer = m_iDX9Resizer;
+ s.fVMR9MixerMode = !!m_fVMR9MixerMode;
+ s.fVMR9MixerYUV = !!m_fVMR9MixerYUV;
+
+ return __super::OnApply();
+}
+
+void CPPageOutput::OnUpdateMixerYUV(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(!!IsDlgButtonChecked(IDC_DSVMR9LOADMIXER));
+} \ No newline at end of file
diff --git a/src/apps/mplayerc/PPageOutput.h b/src/apps/mplayerc/PPageOutput.h
new file mode 100644
index 000000000..a79f1be24
--- /dev/null
+++ b/src/apps/mplayerc/PPageOutput.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "PPageBase.h"
+
+// CPPageOutput dialog
+
+class CPPageOutput : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageOutput)
+
+private:
+ CStringArray m_AudioRendererDisplayNames;
+
+ void DisableRadioButton(UINT nID, UINT nDefID);
+
+public:
+ CPPageOutput();
+ virtual ~CPPageOutput();
+
+// Dialog Data
+ enum { IDD = IDD_PPAGEOUTPUT };
+ int m_iDSVideoRendererType;
+ int m_iRMVideoRendererType;
+ int m_iQTVideoRendererType;
+ int m_iAPSurfaceUsage;
+ int m_iAudioRendererType;
+ CComboBox m_iAudioRendererTypeCtrl;
+ BOOL m_fVMRSyncFix;
+ int m_iDX9Resizer;
+ BOOL m_fVMR9MixerMode;
+ BOOL m_fVMR9MixerYUV;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnUpdateMixerYUV(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/PPagePlayback.cpp b/src/apps/mplayerc/PPagePlayback.cpp
new file mode 100644
index 000000000..205020112
--- /dev/null
+++ b/src/apps/mplayerc/PPagePlayback.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPagePlayback.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "MainFrm.h"
+#include "PPagePlayback.h"
+
+// CPPagePlayback dialog
+
+IMPLEMENT_DYNAMIC(CPPagePlayback, CPPageBase)
+CPPagePlayback::CPPagePlayback()
+ : CPPageBase(CPPagePlayback::IDD, CPPagePlayback::IDD)
+ , m_iLoopForever(0)
+ , m_nLoops(0)
+ , m_fRewind(FALSE)
+ , m_iZoomLevel(0)
+ , m_iRememberZoomLevel(FALSE)
+ , m_fSetFullscreenRes(FALSE)
+ , m_nVolume(0)
+ , m_nBalance(0)
+ , m_fAutoloadAudio(FALSE)
+ , m_fAutoloadSubtitles(FALSE)
+ , m_fEnableWorkerThreadForOpening(FALSE)
+ , m_fReportFailedPins(FALSE)
+{
+}
+
+CPPagePlayback::~CPPagePlayback()
+{
+}
+
+void CPPagePlayback::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_SLIDER1, m_volumectrl);
+ DDX_Control(pDX, IDC_SLIDER2, m_balancectrl);
+ DDX_Slider(pDX, IDC_SLIDER1, m_nVolume);
+ DDX_Slider(pDX, IDC_SLIDER2, m_nBalance);
+ DDX_Radio(pDX, IDC_RADIO1, m_iLoopForever);
+ DDX_Control(pDX, IDC_EDIT1, m_loopnumctrl);
+ DDX_Text(pDX, IDC_EDIT1, m_nLoops);
+ DDX_Check(pDX, IDC_CHECK1, m_fRewind);
+ DDX_CBIndex(pDX, IDC_COMBO1, m_iZoomLevel);
+ DDX_Check(pDX, IDC_CHECK5, m_iRememberZoomLevel);
+ DDX_Check(pDX, IDC_CHECK4, m_fSetFullscreenRes);
+ DDX_Control(pDX, IDC_COMBO2, m_dispmodecombo);
+ DDX_Check(pDX, IDC_CHECK2, m_fAutoloadAudio);
+ DDX_Check(pDX, IDC_CHECK3, m_fAutoloadSubtitles);
+ DDX_Check(pDX, IDC_CHECK7, m_fEnableWorkerThreadForOpening);
+ DDX_Check(pDX, IDC_CHECK6, m_fReportFailedPins);
+}
+
+
+
+BEGIN_MESSAGE_MAP(CPPagePlayback, CPPageBase)
+ ON_WM_HSCROLL()
+ ON_CONTROL_RANGE(BN_CLICKED, IDC_RADIO1, IDC_RADIO2, OnBnClickedRadio12)
+ ON_UPDATE_COMMAND_UI(IDC_EDIT1, OnUpdateLoopNum)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC1, OnUpdateLoopNum)
+ ON_UPDATE_COMMAND_UI(IDC_COMBO1, OnUpdateAutoZoomCombo)
+ ON_UPDATE_COMMAND_UI(IDC_COMBO2, OnUpdateDispModeCombo)
+END_MESSAGE_MAP()
+
+
+// CPPagePlayback message handlers
+
+BOOL CPPagePlayback::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_volumectrl.SetRange(1, 100);
+ m_volumectrl.SetTicFreq(10);
+ m_balancectrl.SetRange(0, 200);
+ m_balancectrl.SetTicFreq(20);
+ m_nVolume = s.nVolume;
+ m_nBalance = s.nBalance+100;
+ m_iLoopForever = s.fLoopForever?1:0;
+ m_nLoops = s.nLoops;
+ m_fRewind = s.fRewind;
+ m_iZoomLevel = s.iZoomLevel;
+ m_iRememberZoomLevel = s.fRememberZoomLevel;
+
+ m_fSetFullscreenRes = s.dmFullscreenRes.fValid;
+ int iSel = -1;
+ dispmode dm, dmtoset = s.dmFullscreenRes;
+ if(!dmtoset.fValid) GetCurDispMode(dmtoset);
+ for(int i = 0, j = 0; GetDispMode(i, dm); i++)
+ {
+ if(dm.bpp <= 8) continue;
+
+ m_dms.Add(dm);
+
+ CString str;
+ str.Format(_T("%dx%d %dbpp %dHz"), dm.size.cx, dm.size.cy, dm.bpp, dm.freq);
+ m_dispmodecombo.AddString(str);
+
+ if(iSel < 0 && dmtoset.fValid && dm.size == dmtoset.size
+ && dm.bpp == dmtoset.bpp && dm.freq == dmtoset.freq)
+ iSel = j;
+
+ j++;
+ }
+ m_dispmodecombo.SetCurSel(iSel);
+
+ m_fAutoloadAudio = s.fAutoloadAudio;
+ m_fAutoloadSubtitles = s.fAutoloadSubtitles;
+ m_fEnableWorkerThreadForOpening = s.fEnableWorkerThreadForOpening;
+ m_fReportFailedPins = s.fReportFailedPins;
+
+ UpdateData(FALSE);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPagePlayback::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ s.nVolume = m_nVolume;
+ s.nBalance = m_nBalance-100;
+ s.fLoopForever = !!m_iLoopForever;
+ s.nLoops = m_nLoops;
+ s.fRewind = !!m_fRewind;
+ s.iZoomLevel = m_iZoomLevel;
+ s.fRememberZoomLevel = !!m_iRememberZoomLevel;
+ int iSel = m_dispmodecombo.GetCurSel();
+ if((s.dmFullscreenRes.fValid = !!m_fSetFullscreenRes) && iSel >= 0 && iSel < m_dms.GetCount())
+ s.dmFullscreenRes = m_dms[m_dispmodecombo.GetCurSel()];
+ s.fAutoloadAudio = !!m_fAutoloadAudio;
+ s.fAutoloadSubtitles = !!m_fAutoloadSubtitles;
+ s.fEnableWorkerThreadForOpening = !!m_fEnableWorkerThreadForOpening;
+ s.fReportFailedPins = !!m_fReportFailedPins;
+
+ return __super::OnApply();
+}
+
+LRESULT CPPagePlayback::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if(message == WM_HSCROLL || message == WM_VSCROLL)
+ {
+ SetModified();
+ }
+
+ return __super::DefWindowProc(message, wParam, lParam);
+}
+
+void CPPagePlayback::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+ if(*pScrollBar == m_volumectrl)
+ {
+ UpdateData();
+ ((CMainFrame*)GetParentFrame())->m_wndToolBar.Volume = m_nVolume; // nice shortcut...
+ }
+ else if(*pScrollBar == m_balancectrl)
+ {
+ UpdateData();
+ ((CMainFrame*)GetParentFrame())->SetBalance(m_nBalance-100); // see prev note...
+ }
+
+ SetModified();
+
+ __super::OnHScroll(nSBCode, nPos, pScrollBar);
+}
+
+void CPPagePlayback::OnBnClickedRadio12(UINT nID)
+{
+ SetModified();
+}
+
+void CPPagePlayback::OnUpdateLoopNum(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(!!IsDlgButtonChecked(IDC_RADIO1));
+}
+
+void CPPagePlayback::OnUpdateAutoZoomCombo(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(!!IsDlgButtonChecked(IDC_CHECK5));
+}
+
+void CPPagePlayback::OnUpdateDispModeCombo(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(!!IsDlgButtonChecked(IDC_CHECK4));
+} \ No newline at end of file
diff --git a/src/apps/mplayerc/PPagePlayback.h b/src/apps/mplayerc/PPagePlayback.h
new file mode 100644
index 000000000..63b9d7024
--- /dev/null
+++ b/src/apps/mplayerc/PPagePlayback.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "PPageBase.h"
+
+// CPPagePlayback dialog
+
+class CPPagePlayback : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPagePlayback)
+
+private:
+ CAtlArray<dispmode> m_dms;
+
+public:
+ CPPagePlayback();
+ virtual ~CPPagePlayback();
+
+ CSliderCtrl m_volumectrl;
+ CSliderCtrl m_balancectrl;
+ int m_nVolume;
+ int m_nBalance;
+ int m_iLoopForever;
+ CEdit m_loopnumctrl;
+ int m_nLoops;
+ BOOL m_fRewind;
+ int m_iZoomLevel;
+ BOOL m_iRememberZoomLevel;
+ BOOL m_fSetFullscreenRes;
+ CComboBox m_dispmodecombo;
+ BOOL m_fAutoloadAudio;
+ BOOL m_fAutoloadSubtitles;
+ BOOL m_fEnableWorkerThreadForOpening;
+ BOOL m_fReportFailedPins;
+
+// Dialog Data
+ enum { IDD = IDD_PPAGEPLAYBACK };
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+ virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnBnClickedRadio12(UINT nID);
+ afx_msg void OnUpdateLoopNum(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateAutoZoomCombo(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateDispModeCombo(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/PPagePlayer.cpp b/src/apps/mplayerc/PPagePlayer.cpp
new file mode 100644
index 000000000..b401faa85
--- /dev/null
+++ b/src/apps/mplayerc/PPagePlayer.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+// PPagePlayer.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "MainFrm.h"
+#include "PPagePlayer.h"
+
+// CPPagePlayer dialog
+
+IMPLEMENT_DYNAMIC(CPPagePlayer, CPPageBase)
+CPPagePlayer::CPPagePlayer()
+ : CPPageBase(CPPagePlayer::IDD, CPPagePlayer::IDD)
+ , m_iAllowMultipleInst(0)
+ , m_iAlwaysOnTop(FALSE)
+ , m_fTrayIcon(FALSE)
+ , m_iShowBarsWhenFullScreen(FALSE)
+ , m_nShowBarsWhenFullScreenTimeOut(0)
+ , m_iTitleBarTextStyle(0)
+ , m_fExitFullScreenAtTheEnd(FALSE)
+ , m_fRememberWindowPos(FALSE)
+ , m_fRememberWindowSize(FALSE)
+ , m_fSnapToDesktopEdges(FALSE)
+ , m_fUseIni(FALSE)
+ , m_fKeepHistory(FALSE)
+ , m_fHideCDROMsSubMenu(FALSE)
+ , m_priority(FALSE)
+ , m_launchfullscreen(FALSE)
+{
+}
+
+CPPagePlayer::~CPPagePlayer()
+{
+}
+
+void CPPagePlayer::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Radio(pDX, IDC_RADIO1, m_iAllowMultipleInst);
+ DDX_Radio(pDX, IDC_RADIO3, m_iTitleBarTextStyle);
+ DDX_Check(pDX, IDC_CHECK13, m_bTitleBarTextTitle);
+ DDX_Check(pDX, IDC_CHECK2, m_iAlwaysOnTop);
+ DDX_Check(pDX, IDC_CHECK3, m_fTrayIcon);
+ DDX_Check(pDX, IDC_CHECK4, m_iShowBarsWhenFullScreen);
+ DDX_Text(pDX, IDC_EDIT1, m_nShowBarsWhenFullScreenTimeOut);
+ DDX_Check(pDX, IDC_CHECK5, m_fExitFullScreenAtTheEnd);
+ DDX_Check(pDX, IDC_CHECK6, m_fRememberWindowPos);
+ DDX_Check(pDX, IDC_CHECK7, m_fRememberWindowSize);
+ DDX_Check(pDX, IDC_CHECK12, m_fSnapToDesktopEdges);
+ DDX_Check(pDX, IDC_CHECK8, m_fUseIni);
+ DDX_Control(pDX, IDC_SPIN1, m_nTimeOutCtrl);
+ DDX_Check(pDX, IDC_CHECK1, m_fKeepHistory);
+ DDX_Check(pDX, IDC_CHECK10, m_fHideCDROMsSubMenu);
+ DDX_Check(pDX, IDC_CHECK9, m_priority);
+ DDX_Check(pDX, IDC_CHECK11, m_launchfullscreen);
+}
+
+BEGIN_MESSAGE_MAP(CPPagePlayer, CPPageBase)
+ ON_BN_CLICKED(IDC_CHECK8, OnBnClickedCheck8)
+ ON_UPDATE_COMMAND_UI(IDC_SPIN1, OnUpdateTimeout)
+ ON_UPDATE_COMMAND_UI(IDC_EDIT1, OnUpdateTimeout)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC1, OnUpdateTimeout)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC2, OnUpdateTimeout)
+ ON_UPDATE_COMMAND_UI(IDC_CHECK13, OnUpdateCheck13)
+END_MESSAGE_MAP()
+
+// CPPagePlayer message handlers
+
+BOOL CPPagePlayer::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_iAllowMultipleInst = s.fAllowMultipleInst;
+ m_iTitleBarTextStyle = s.iTitleBarTextStyle;
+ m_bTitleBarTextTitle = s.fTitleBarTextTitle;
+ m_iAlwaysOnTop = s.iOnTop;
+ m_fTrayIcon = s.fTrayIcon;
+ m_iShowBarsWhenFullScreen = s.fShowBarsWhenFullScreen;
+ m_nShowBarsWhenFullScreenTimeOut = s.nShowBarsWhenFullScreenTimeOut;
+ m_nTimeOutCtrl.SetRange(-1, 10);
+ m_fExitFullScreenAtTheEnd = s.fExitFullScreenAtTheEnd;
+ m_fRememberWindowPos = s.fRememberWindowPos;
+ m_fRememberWindowSize = s.fRememberWindowSize;
+ m_fSnapToDesktopEdges = s.fSnapToDesktopEdges;
+ m_fUseIni = ((CMPlayerCApp*)AfxGetApp())->IsIniValid();
+ m_fKeepHistory = s.fKeepHistory;
+ m_fHideCDROMsSubMenu = s.fHideCDROMsSubMenu;
+ m_priority = s.priority != NORMAL_PRIORITY_CLASS;
+ m_launchfullscreen = s.launchfullscreen;
+
+ UpdateData(FALSE);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPagePlayer::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ s.fAllowMultipleInst = !!m_iAllowMultipleInst;
+ s.iTitleBarTextStyle = m_iTitleBarTextStyle;
+ s.fTitleBarTextTitle = !!m_bTitleBarTextTitle;
+ s.iOnTop = m_iAlwaysOnTop;
+ s.fTrayIcon = !!m_fTrayIcon;
+ s.fShowBarsWhenFullScreen = !!m_iShowBarsWhenFullScreen;
+ s.nShowBarsWhenFullScreenTimeOut = m_nShowBarsWhenFullScreenTimeOut;
+ s.fExitFullScreenAtTheEnd = !!m_fExitFullScreenAtTheEnd;
+ s.fRememberWindowPos = !!m_fRememberWindowPos;
+ s.fRememberWindowSize = !!m_fRememberWindowSize;
+ s.fSnapToDesktopEdges = !!m_fSnapToDesktopEdges;
+ s.fKeepHistory = !!m_fKeepHistory;
+ s.fHideCDROMsSubMenu = !!m_fHideCDROMsSubMenu;
+ s.priority = !m_priority ? NORMAL_PRIORITY_CLASS : GetVersion() < 0 ? HIGH_PRIORITY_CLASS : ABOVE_NORMAL_PRIORITY_CLASS;
+ s.launchfullscreen = !!m_launchfullscreen;
+
+ if(!m_fKeepHistory)
+ {
+ for(int i = 0; i < s.MRU.GetSize(); i++) s.MRU.Remove(i);
+ for(int i = 0; i < s.MRUDub.GetSize(); i++) s.MRUDub.Remove(i);
+ s.MRU.WriteList();
+ s.MRUDub.WriteList();
+ }
+
+ ((CMainFrame*)AfxGetMainWnd())->ShowTrayIcon(s.fTrayIcon);
+
+ ::SetPriorityClass(::GetCurrentProcess(), s.priority);
+
+ return __super::OnApply();
+}
+
+void CPPagePlayer::OnBnClickedCheck8()
+{
+ UpdateData();
+
+ if(m_fUseIni) ((CMPlayerCApp*)AfxGetApp())->StoreSettingsToIni();
+ else ((CMPlayerCApp*)AfxGetApp())->StoreSettingsToRegistry();
+
+ SetModified();
+}
+
+void CPPagePlayer::OnUpdateTimeout(CCmdUI* pCmdUI)
+{
+ UpdateData();
+
+ pCmdUI->Enable(m_iShowBarsWhenFullScreen);
+}
+
+void CPPagePlayer::OnUpdateCheck13(CCmdUI* pCmdUI)
+{
+ UpdateData();
+
+ pCmdUI->Enable(m_iTitleBarTextStyle == 1);
+}
diff --git a/src/apps/mplayerc/PPagePlayer.h b/src/apps/mplayerc/PPagePlayer.h
new file mode 100644
index 000000000..e3980ff43
--- /dev/null
+++ b/src/apps/mplayerc/PPagePlayer.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "PPageBase.h"
+
+// CPPagePlayer dialog
+
+class CPPagePlayer : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPagePlayer)
+
+public:
+ CPPagePlayer();
+ virtual ~CPPagePlayer();
+
+ int m_iAllowMultipleInst;
+ int m_iTitleBarTextStyle;
+ BOOL m_bTitleBarTextTitle;
+ BOOL m_iAlwaysOnTop;
+ BOOL m_iShowBarsWhenFullScreen;
+ int m_nShowBarsWhenFullScreenTimeOut;
+ BOOL m_fExitFullScreenAtTheEnd;
+ BOOL m_fRememberWindowPos;
+ BOOL m_fRememberWindowSize;
+ BOOL m_fSnapToDesktopEdges;
+ BOOL m_fUseIni;
+ CSpinButtonCtrl m_nTimeOutCtrl;
+ BOOL m_fTrayIcon;
+ BOOL m_fKeepHistory;
+ BOOL m_fHideCDROMsSubMenu;
+ BOOL m_priority;
+ BOOL m_launchfullscreen;
+
+// Dialog Data
+ enum { IDD = IDD_PPAGEPLAYER };
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnBnClickedCheck8();
+ afx_msg void OnUpdateTimeout(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateCheck13(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/PPageSheet.cpp b/src/apps/mplayerc/PPageSheet.cpp
new file mode 100644
index 000000000..13bc4559b
--- /dev/null
+++ b/src/apps/mplayerc/PPageSheet.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageSheet.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PPageSheet.h"
+
+// CPPageSheet
+
+IMPLEMENT_DYNAMIC(CPPageSheet, CTreePropSheet)
+
+CPPageSheet::CPPageSheet(LPCTSTR pszCaption, IFilterGraph* pFG, CWnd* pParentWnd, UINT idPage)
+ : CTreePropSheet(pszCaption, pParentWnd, 0)
+ , m_audioswitcher(pFG)
+{
+ AddPage(&m_player);
+ AddPage(&m_formats);
+ AddPage(&m_acceltbl);
+ AddPage(&m_logo);
+ AddPage(&m_playback);
+ AddPage(&m_dvd);
+ AddPage(&m_output);
+ AddPage(&m_webserver);
+ AddPage(&m_internalfilters);
+ AddPage(&m_audioswitcher);
+ AddPage(&m_externalfilters);
+ AddPage(&m_subtitles);
+ AddPage(&m_substyle);
+ AddPage(&m_subdb);
+ AddPage(&m_tweaks);
+ AddPage(&m_casimir);
+
+ EnableStackedTabs(FALSE);
+
+ SetTreeViewMode(TRUE, TRUE, FALSE);
+
+ if(idPage || (idPage = AfxGetApp()->GetProfileInt(ResStr(IDS_R_SETTINGS), _T("LastUsedPage"), 0)))
+ {
+ for(int i = 0; i < GetPageCount(); i++)
+ {
+ if(GetPage(i)->m_pPSP->pszTemplate == MAKEINTRESOURCE(idPage))
+ {
+ SetActivePage(i);
+ break;
+ }
+ }
+ }
+}
+
+CPPageSheet::~CPPageSheet()
+{
+}
+
+CTreeCtrl* CPPageSheet::CreatePageTreeObject()
+{
+ return new CTreePropSheetTreeCtrl();
+}
+
+BEGIN_MESSAGE_MAP(CPPageSheet, CTreePropSheet)
+END_MESSAGE_MAP()
+
+BOOL CPPageSheet::OnInitDialog()
+{
+ BOOL bResult = __super::OnInitDialog();
+
+ if(CTreeCtrl* pTree = GetPageTreeControl())
+ {
+ for(HTREEITEM node = pTree->GetRootItem(); node; node = pTree->GetNextSiblingItem(node))
+ pTree->Expand(node, TVE_EXPAND);
+ }
+
+ return bResult;
+}
+
+// CTreePropSheetTreeCtrl
+
+IMPLEMENT_DYNAMIC(CTreePropSheetTreeCtrl, CTreeCtrl)
+CTreePropSheetTreeCtrl::CTreePropSheetTreeCtrl()
+{
+}
+
+CTreePropSheetTreeCtrl::~CTreePropSheetTreeCtrl()
+{
+}
+
+
+BEGIN_MESSAGE_MAP(CTreePropSheetTreeCtrl, CTreeCtrl)
+END_MESSAGE_MAP()
+
+// CTreePropSheetTreeCtrl message handlers
+
+
+BOOL CTreePropSheetTreeCtrl::PreCreateWindow(CREATESTRUCT& cs)
+{
+ cs.dwExStyle |= WS_EX_CLIENTEDGE;
+// cs.style &= ~TVS_LINESATROOT;
+
+ return __super::PreCreateWindow(cs);
+}
+
diff --git a/src/apps/mplayerc/PPageSheet.h b/src/apps/mplayerc/PPageSheet.h
new file mode 100644
index 000000000..15810239d
--- /dev/null
+++ b/src/apps/mplayerc/PPageSheet.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+using namespace TreePropSheet;
+
+#include "PPagePlayer.h"
+#include "PPageFormats.h"
+#include "PPageAccelTbl.h"
+#include "PPageLogo.h"
+#include "PPagePlayback.h"
+#include "PPageDVD.h"
+#include "PPageOutput.h"
+#include "PPageWebServer.h"
+#include "PPageInternalFilters.h"
+#include "PPageAudioSwitcher.h"
+#include "PPageExternalFilters.h"
+#include "PPageSubtitles.h"
+#include "PPageSubStyle.h"
+#include "PPageSubDB.h"
+#include "PPageTweaks.h"
+#include "PPageCasimir.h"
+
+// CTreePropSheetTreeCtrl
+
+class CTreePropSheetTreeCtrl : public CTreeCtrl
+{
+ DECLARE_DYNAMIC(CTreePropSheetTreeCtrl)
+
+public:
+ CTreePropSheetTreeCtrl();
+ virtual ~CTreePropSheetTreeCtrl();
+
+protected:
+ DECLARE_MESSAGE_MAP()
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+};
+
+// CPPageSheet
+
+class CPPageSheet : public CTreePropSheet
+{
+ DECLARE_DYNAMIC(CPPageSheet)
+
+private:
+ CPPagePlayer m_player;
+ CPPageFormats m_formats;
+ CPPageAccelTbl m_acceltbl;
+ CPPageLogo m_logo;
+ CPPagePlayback m_playback;
+ CPPageDVD m_dvd;
+ CPPageOutput m_output;
+ CPPageWebServer m_webserver;
+ CPPageSubtitles m_subtitles;
+ CPPageSubStyle m_substyle;
+ CPPageSubDB m_subdb;
+ CPPageInternalFilters m_internalfilters;
+ CPPageAudioSwitcher m_audioswitcher;
+ CPPageExternalFilters m_externalfilters;
+ CPPageTweaks m_tweaks;
+ CPPageCasimir m_casimir;
+
+ CTreeCtrl* CreatePageTreeObject();
+
+public:
+ CPPageSheet(LPCTSTR pszCaption, IFilterGraph* pFG, CWnd* pParentWnd, UINT idPage = 0);
+ virtual ~CPPageSheet();
+
+protected:
+ DECLARE_MESSAGE_MAP()
+public:
+ virtual BOOL OnInitDialog();
+};
diff --git a/src/apps/mplayerc/PPageSubDB.cpp b/src/apps/mplayerc/PPageSubDB.cpp
new file mode 100644
index 000000000..3a0aedaef
--- /dev/null
+++ b/src/apps/mplayerc/PPageSubDB.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageSubDB.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "MainFrm.h"
+#include "PPageSubDB.h"
+#include "ISDb.h"
+
+// CPPageSubDB dialog
+
+IMPLEMENT_DYNAMIC(CPPageSubDB, CPPageBase)
+CPPageSubDB::CPPageSubDB()
+ : CPPageBase(CPPageSubDB::IDD, CPPageSubDB::IDD)
+ , m_ISDb(_T(""))
+{
+}
+
+CPPageSubDB::~CPPageSubDB()
+{
+}
+
+void CPPageSubDB::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_COMBO1, m_ISDbCombo);
+ DDX_CBString(pDX, IDC_COMBO1, m_ISDb);
+}
+
+BEGIN_MESSAGE_MAP(CPPageSubDB, CPPageBase)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateButton1)
+END_MESSAGE_MAP()
+
+
+// CPPageSubDB message handlers
+
+BOOL CPPageSubDB::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_ISDb = s.ISDb;
+ m_ISDbCombo.AddString(m_ISDb);
+ if(m_ISDb.CompareNoCase(_T("sub.sytes.net")))
+ m_ISDbCombo.AddString(_T("sub.sytes.net"));
+
+ UpdateData(FALSE);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageSubDB::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ s.ISDb = m_ISDb;
+ s.ISDb.TrimRight('/');
+
+ return __super::OnApply();
+}
+
+void CPPageSubDB::OnBnClickedButton1()
+{
+ CString ISDb, ver, msg, str;
+
+ m_ISDbCombo.GetWindowText(ISDb);
+ ISDb.TrimRight('/');
+
+ ver.Format(_T("ISDb v%d"), ISDb_PROTOCOL_VERSION);
+
+ CWebTextFile wtf;
+ if(wtf.Open(_T("http://") + ISDb + _T("/test.php")) && wtf.ReadString(str) && str == ver)
+ {
+ msg = _T("The URL appears to be correct!");
+ }
+ else if(str.Find(_T("ISDb v")) == 0)
+ {
+ msg = _T("Protocol version mismatch, please upgrade your player or choose a different address!");
+ }
+ else
+ {
+ msg = _T("Bad URL, could not locate subtitle database there!");
+ }
+
+ AfxMessageBox(msg, MB_OK);
+}
+
+void CPPageSubDB::OnUpdateButton1(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_ISDbCombo.GetWindowTextLength() > 0);
+}
diff --git a/src/apps/mplayerc/PPageSubDB.h b/src/apps/mplayerc/PPageSubDB.h
new file mode 100644
index 000000000..8c537a719
--- /dev/null
+++ b/src/apps/mplayerc/PPageSubDB.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "afxwin.h"
+
+// CPPageSubDB dialog
+
+class CPPageSubDB : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageSubDB)
+
+public:
+ CPPageSubDB();
+ virtual ~CPPageSubDB();
+
+// Dialog Data
+ enum { IDD = IDD_PPAGESUBDB };
+ CComboBox m_ISDbCombo;
+ CString m_ISDb;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnUpdateButton1(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/PPageSubStyle.cpp b/src/apps/mplayerc/PPageSubStyle.cpp
new file mode 100644
index 000000000..e68be0a39
--- /dev/null
+++ b/src/apps/mplayerc/PPageSubStyle.cpp
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageSubStyle.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include <math.h>
+#include "mplayerc.h"
+#include "MainFrm.h"
+#include "PPageSubStyle.h"
+
+// CColorStatic
+
+//IMPLEMENT_DYNAMIC(CColorStatic, CStatic)
+
+//BEGIN_MESSAGE_MAP(CColorStatic, CStatic)
+//END_MESSAGE_MAP()
+
+// CPPageSubStyle dialog
+
+IMPLEMENT_DYNAMIC(CPPageSubStyle, CPPageBase)
+CPPageSubStyle::CPPageSubStyle()
+ : CPPageBase(CPPageSubStyle::IDD, CPPageSubStyle::IDD)
+ , m_iCharset(0)
+ , m_spacing(0)
+ , m_angle(0)
+ , m_scalex(0)
+ , m_scaley(0)
+ , m_borderstyle(0)
+ , m_borderwidth(0)
+ , m_shadowdepth(0)
+ , m_screenalignment(0)
+ , m_margin(0,0,0,0)
+ , m_linkalphasliders(FALSE)
+ , m_relativeTo(FALSE)
+{
+ m_stss = AfxGetAppSettings().subdefstyle;
+ m_fUseDefaultStyle = true;
+}
+
+CPPageSubStyle::~CPPageSubStyle()
+{
+}
+
+void CPPageSubStyle::InitStyle(CString title, STSStyle& stss)
+{
+ m_pPSP->pszTitle = (m_title = title);
+ m_psp.dwFlags |= PSP_USETITLE;
+
+ m_stss = stss;
+ m_fUseDefaultStyle = false;
+}
+
+void CPPageSubStyle::AskColor(int i)
+{
+ CColorDialog dlg(m_stss.colors[i]);
+ dlg.m_cc.Flags |= CC_FULLOPEN;
+ if(dlg.DoModal() == IDOK)
+ {
+ m_stss.colors[i] = dlg.m_cc.rgbResult;
+ m_color[i].Invalidate();
+ }
+}
+
+void CPPageSubStyle::DoDataExchange(CDataExchange* pDX)
+{
+ CPPageBase::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_BUTTON1, m_font);
+ DDX_CBIndex(pDX, IDC_COMBO1, m_iCharset);
+ DDX_Control(pDX, IDC_COMBO1, m_charset);
+ DDX_Text(pDX, IDC_EDIT3, m_spacing);
+ DDX_Control(pDX, IDC_SPIN3, m_spacingspin);
+ DDX_Text(pDX, IDC_EDIT4, m_angle);
+ DDX_Control(pDX, IDC_SPIN10, m_anglespin);
+ DDX_Text(pDX, IDC_EDIT5, m_scalex);
+ DDX_Control(pDX, IDC_SPIN4, m_scalexspin);
+ DDX_Text(pDX, IDC_EDIT6, m_scaley);
+ DDX_Control(pDX, IDC_SPIN5, m_scaleyspin);
+ DDX_Radio(pDX, IDC_RADIO1, m_borderstyle);
+ DDX_Text(pDX, IDC_EDIT1, m_borderwidth);
+ DDX_Control(pDX, IDC_SPIN1, m_borderwidthspin);
+ DDX_Text(pDX, IDC_EDIT2, m_shadowdepth);
+ DDX_Control(pDX, IDC_SPIN2, m_shadowdepthspin);
+ DDX_Radio(pDX, IDC_RADIO3, m_screenalignment);
+ DDX_Text(pDX, IDC_EDIT7, m_margin.left);
+ DDX_Control(pDX, IDC_SPIN6, m_marginleftspin);
+ DDX_Text(pDX, IDC_EDIT8, m_margin.right);
+ DDX_Control(pDX, IDC_SPIN7, m_marginrightspin);
+ DDX_Text(pDX, IDC_EDIT9, m_margin.top);
+ DDX_Control(pDX, IDC_SPIN8, m_margintopspin);
+ DDX_Text(pDX, IDC_EDIT10, m_margin.bottom);
+ DDX_Control(pDX, IDC_SPIN9, m_marginbottomspin);
+ DDX_Control(pDX, IDC_COLORPRI, m_color[0]);
+ DDX_Control(pDX, IDC_COLORSEC, m_color[1]);
+ DDX_Control(pDX, IDC_COLOROUTL, m_color[2]);
+ DDX_Control(pDX, IDC_COLORSHAD, m_color[3]);
+ DDX_Slider(pDX, IDC_SLIDER1, m_alpha[0]);
+ DDX_Slider(pDX, IDC_SLIDER2, m_alpha[1]);
+ DDX_Slider(pDX, IDC_SLIDER3, m_alpha[2]);
+ DDX_Slider(pDX, IDC_SLIDER4, m_alpha[3]);
+ DDX_Control(pDX, IDC_SLIDER1, m_alphasliders[0]);
+ DDX_Control(pDX, IDC_SLIDER2, m_alphasliders[1]);
+ DDX_Control(pDX, IDC_SLIDER3, m_alphasliders[2]);
+ DDX_Control(pDX, IDC_SLIDER4, m_alphasliders[3]);
+ DDX_Check(pDX, IDC_CHECK1, m_linkalphasliders);
+ DDX_Check(pDX, IDC_CHECK_RELATIVETO, m_relativeTo);
+}
+
+
+BEGIN_MESSAGE_MAP(CPPageSubStyle, CPPageBase)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+ ON_STN_CLICKED(IDC_COLORPRI, OnStnClickedColorpri)
+ ON_STN_CLICKED(IDC_COLORSEC, OnStnClickedColorsec)
+ ON_STN_CLICKED(IDC_COLOROUTL, OnStnClickedColoroutl)
+ ON_STN_CLICKED(IDC_COLORSHAD, OnStnClickedColorshad)
+ ON_BN_CLICKED(IDC_CHECK1, OnBnClickedCheck1)
+ ON_WM_HSCROLL()
+END_MESSAGE_MAP()
+
+
+// CPPageSubStyle message handlers
+
+BOOL CPPageSubStyle::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ m_font.SetWindowText(m_stss.fontName);
+ m_iCharset = -1;
+ for(int i = 0; i < CharSetLen; i++)
+ {
+ CString str;
+ str.Format(_T("%s (%d)"), CharSetNames[i], CharSetList[i]);
+ m_charset.AddString(str);
+ m_charset.SetItemData(i, CharSetList[i]);
+ if(m_stss.charSet == CharSetList[i]) m_iCharset = i;
+ }
+
+ // TODO: allow floats in these edit boxes
+ m_spacing = (int)m_stss.fontSpacing;
+ m_spacingspin.SetRange32(-10000, 10000);
+ while(m_stss.fontAngleZ < 0) m_stss.fontAngleZ += 360;
+ m_angle = (int)fmod(m_stss.fontAngleZ, 360);
+ m_anglespin.SetRange32(0, 359);
+ m_scalex = (int)m_stss.fontScaleX;
+ m_scalexspin.SetRange32(-10000, 10000);
+ m_scaley = (int)m_stss.fontScaleY;
+ m_scaleyspin.SetRange32(-10000, 10000);
+
+ m_borderstyle = m_stss.borderStyle;
+ m_borderwidth = (int)m_stss.outlineWidth;
+ m_borderwidthspin.SetRange32(0, 10000);
+ m_shadowdepth = (int)m_stss.shadowDepth;
+ m_shadowdepthspin.SetRange32(0, 10000);
+
+ m_screenalignment = m_stss.scrAlignment-1;
+ m_margin = m_stss.marginRect;
+ m_marginleftspin.SetRange32(-10000, 10000);
+ m_marginrightspin.SetRange32(-10000, 10000);
+ m_margintopspin.SetRange32(-10000, 10000);
+ m_marginbottomspin.SetRange32(-10000, 10000);
+ m_relativeTo = m_stss.relativeTo;
+
+ for(int i = 0; i < 4; i++)
+ {
+ m_color[i].SetColorPtr(&m_stss.colors[i]);
+ m_alpha[i] = 255-m_stss.alpha[i];
+ m_alphasliders[i].SetRange(0, 255);
+ }
+
+ m_linkalphasliders = FALSE;
+
+ UpdateData(FALSE);
+
+ CreateToolTip();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageSubStyle::OnApply()
+{
+ UpdateData();
+
+ if(m_iCharset >= 0) m_stss.charSet = m_charset.GetItemData(m_iCharset);
+ m_stss.fontSpacing = m_spacing;
+ m_stss.fontAngleZ = m_angle;
+ m_stss.fontScaleX = m_scalex;
+ m_stss.fontScaleY = m_scaley;
+
+ m_stss.borderStyle = m_borderstyle;
+ m_stss.outlineWidth = m_borderwidth;
+ m_stss.shadowDepth = m_shadowdepth;
+
+ m_stss.scrAlignment = m_screenalignment+1;
+ m_stss.marginRect = m_margin;
+ m_stss.relativeTo = m_relativeTo;
+
+ for(int i = 0; i < 4; i++) m_stss.alpha[i] = 255-m_alpha[i];
+
+ if(m_fUseDefaultStyle)
+ {
+ STSStyle& stss = AfxGetAppSettings().subdefstyle;
+ if(!(stss == m_stss))
+ {
+ stss = m_stss;
+ if(CMainFrame* pFrame = dynamic_cast<CMainFrame*>(AfxGetMainWnd()))
+ pFrame->UpdateSubtitle(true);
+ }
+ }
+
+ return __super::OnApply();
+}
+
+void CPPageSubStyle::OnBnClickedButton1()
+{
+ LOGFONT lf;
+ lf <<= m_stss;
+
+ CFontDialog dlg(&lf, CF_SCREENFONTS|CF_INITTOLOGFONTSTRUCT|CF_FORCEFONTEXIST|CF_SCALABLEONLY|CF_EFFECTS);
+ if(dlg.DoModal() == IDOK)
+ {
+ CString str(lf.lfFaceName);
+ if(str.GetLength() > 16) str = str.Left(14) + _T("...");
+ m_font.SetWindowText(str);
+
+ for(int i = 0, j = m_charset.GetCount(); i < j; i++)
+ {
+ if(m_charset.GetItemData(i) == lf.lfCharSet)
+ {
+ m_charset.SetCurSel(i);
+ break;
+ }
+ }
+
+ m_stss = lf;
+
+ SetModified();
+ }
+}
+
+void CPPageSubStyle::OnStnClickedColorpri()
+{
+ AskColor(0);
+}
+
+void CPPageSubStyle::OnStnClickedColorsec()
+{
+ AskColor(1);
+}
+
+void CPPageSubStyle::OnStnClickedColoroutl()
+{
+ AskColor(2);
+}
+
+void CPPageSubStyle::OnStnClickedColorshad()
+{
+ AskColor(3);
+}
+
+void CPPageSubStyle::OnBnClickedCheck1()
+{
+ UpdateData();
+
+ int avg = 0;
+ for(int i = 0; i < 4; i++) avg += m_alphasliders[i].GetPos();
+ avg /= 4;
+ for(int i = 0; i < 4; i++) m_alphasliders[i].SetPos(avg);
+
+ SetModified();
+}
+
+void CPPageSubStyle::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+ if(m_linkalphasliders && pScrollBar)
+ {
+ int pos = ((CSliderCtrl*)pScrollBar)->GetPos();
+ for(int i = 0; i < 4; i++) m_alphasliders[i].SetPos(pos);
+ }
+
+ SetModified();
+
+ __super::OnHScroll(nSBCode, nPos, pScrollBar);
+}
diff --git a/src/apps/mplayerc/PPageSubStyle.h b/src/apps/mplayerc/PPageSubStyle.h
new file mode 100644
index 000000000..ccf852e29
--- /dev/null
+++ b/src/apps/mplayerc/PPageSubStyle.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "PPageBase.h"
+#include "..\..\subtitles\STS.h"
+
+class CColorStatic : public CStatic
+{
+// DECLARE_DYNAMIC(CColorStatic)
+
+ COLORREF* m_pColor;
+
+public:
+ CColorStatic(CWnd* pParent = NULL) : m_pColor(NULL) {}
+ virtual ~CColorStatic() {}
+
+ void SetColorPtr(COLORREF* pColor) {m_pColor = pColor;}
+
+// DECLARE_MESSAGE_MAP()
+
+protected:
+ virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
+ {
+ CRect r;
+ GetClientRect(r);
+ CDC::FromHandle(lpDrawItemStruct->hDC)->FillSolidRect(r, m_pColor ? *m_pColor : ::GetSysColor(COLOR_BTNFACE));
+ }
+};
+
+// CPPageSubStyle dialog
+
+class CPPageSubStyle : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageSubStyle)
+
+private:
+ CString m_title;
+ STSStyle m_stss;
+ bool m_fUseDefaultStyle;
+
+ void AskColor(int i);
+
+public:
+ CPPageSubStyle();
+ virtual ~CPPageSubStyle();
+
+ void InitStyle(CString title, STSStyle& stss);
+ void GetStyle(STSStyle& stss) {stss = m_stss;}
+
+// Dialog Data
+ enum { IDD = IDD_PPAGESUBSTYLE };
+ CButton m_font;
+ int m_iCharset;
+ CComboBox m_charset;
+ int m_spacing;
+ CSpinButtonCtrl m_spacingspin;
+ int m_angle;
+ CSpinButtonCtrl m_anglespin;
+ int m_scalex;
+ CSpinButtonCtrl m_scalexspin;
+ int m_scaley;
+ CSpinButtonCtrl m_scaleyspin;
+ int m_borderstyle;
+ int m_borderwidth;
+ CSpinButtonCtrl m_borderwidthspin;
+ int m_shadowdepth;
+ CSpinButtonCtrl m_shadowdepthspin;
+ int m_screenalignment;
+ CRect m_margin;
+ CSpinButtonCtrl m_marginleftspin;
+ CSpinButtonCtrl m_marginrightspin;
+ CSpinButtonCtrl m_margintopspin;
+ CSpinButtonCtrl m_marginbottomspin;
+ CColorStatic m_color[4];
+ int m_alpha[4];
+ CSliderCtrl m_alphasliders[4];
+ BOOL m_linkalphasliders;
+ BOOL m_relativeTo;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnStnClickedColorpri();
+ afx_msg void OnStnClickedColorsec();
+ afx_msg void OnStnClickedColoroutl();
+ afx_msg void OnStnClickedColorshad();
+ afx_msg void OnBnClickedCheck1();
+ afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+public:
+};
diff --git a/src/apps/mplayerc/PPageSubtitles.cpp b/src/apps/mplayerc/PPageSubtitles.cpp
new file mode 100644
index 000000000..b19db1896
--- /dev/null
+++ b/src/apps/mplayerc/PPageSubtitles.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageSubtitles.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "MainFrm.h"
+#include "PPageSubtitles.h"
+
+// CPPageSubtitles dialog
+
+IMPLEMENT_DYNAMIC(CPPageSubtitles, CPPageBase)
+CPPageSubtitles::CPPageSubtitles()
+ : CPPageBase(CPPageSubtitles::IDD, CPPageSubtitles::IDD)
+ , m_fOverridePlacement(FALSE)
+ , m_nHorPos(0)
+ , m_nVerPos(0)
+ , m_nSPCSize(0)
+ , m_fSPCPow2Tex(FALSE)
+{
+}
+
+CPPageSubtitles::~CPPageSubtitles()
+{
+}
+
+void CPPageSubtitles::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Check(pDX, IDC_CHECK3, m_fOverridePlacement);
+ DDX_Text(pDX, IDC_EDIT2, m_nHorPos);
+ DDX_Control(pDX, IDC_SPIN2, m_nHorPosCtrl);
+ DDX_Text(pDX, IDC_EDIT3, m_nVerPos);
+ DDX_Control(pDX, IDC_SPIN3, m_nVerPosCtrl);
+ DDX_Text(pDX, IDC_EDIT1, m_nSPCSize);
+ DDX_Control(pDX, IDC_SPIN1, m_nSPCSizeCtrl);
+ DDX_Control(pDX, IDC_COMBO1, m_spmaxres);
+ DDX_Control(pDX, IDC_EDIT2, m_nHorPosEdit);
+ DDX_Control(pDX, IDC_EDIT3, m_nVerPosEdit);
+ DDX_Check(pDX, IDC_CHECK_SPCPOW2TEX, m_fSPCPow2Tex);
+}
+
+
+BEGIN_MESSAGE_MAP(CPPageSubtitles, CPPageBase)
+ ON_UPDATE_COMMAND_UI(IDC_EDIT2, OnUpdatePosOverride)
+ ON_UPDATE_COMMAND_UI(IDC_SPIN2, OnUpdatePosOverride)
+ ON_UPDATE_COMMAND_UI(IDC_EDIT3, OnUpdatePosOverride)
+ ON_UPDATE_COMMAND_UI(IDC_SPIN3, OnUpdatePosOverride)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC1, OnUpdatePosOverride)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC2, OnUpdatePosOverride)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC3, OnUpdatePosOverride)
+ ON_UPDATE_COMMAND_UI(IDC_STATIC4, OnUpdatePosOverride)
+END_MESSAGE_MAP()
+
+
+// CPPageSubtitles message handlers
+
+BOOL CPPageSubtitles::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_fOverridePlacement = s.fOverridePlacement;
+ m_nHorPos = s.nHorPos;
+ m_nHorPosCtrl.SetRange(-10,110);
+ m_nVerPos = s.nVerPos;
+ m_nVerPosCtrl.SetRange(110,-10);
+ m_nSPCSize = s.nSPCSize;
+ m_nSPCSizeCtrl.SetRange(0, 10);
+ m_spmaxres.AddString(_T("Desktop"));
+ m_spmaxres.AddString(_T("1024x768"));
+ m_spmaxres.AddString(_T("800x600"));
+ m_spmaxres.AddString(_T("640x480"));
+ m_spmaxres.AddString(_T("512x384"));
+ m_spmaxres.AddString(_T("384x288"));
+ m_spmaxres.SetCurSel(s.nSPCMaxRes);
+ m_fSPCPow2Tex = s.fSPCPow2Tex;
+
+ UpdateData(FALSE);
+
+ CreateToolTip();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageSubtitles::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ if(s.fOverridePlacement != !!m_fOverridePlacement
+ || s.nHorPos != m_nHorPos
+ || s.nVerPos != m_nVerPos
+ || s.nSPCSize != m_nSPCSize
+ || s.nSPCMaxRes != m_spmaxres.GetCurSel()
+ || s.fSPCPow2Tex != !!m_fSPCPow2Tex)
+ {
+ s.fOverridePlacement = !!m_fOverridePlacement;
+ s.nHorPos = m_nHorPos;
+ s.nVerPos = m_nVerPos;
+ s.nSPCSize = m_nSPCSize;
+ s.nSPCMaxRes = m_spmaxres.GetCurSel();
+ s.fSPCPow2Tex = !!m_fSPCPow2Tex;
+
+ if(CMainFrame* pFrame = (CMainFrame*)GetParentFrame())
+ pFrame->UpdateSubtitle(true);
+ }
+
+ return __super::OnApply();
+}
+
+void CPPageSubtitles::OnUpdatePosOverride(CCmdUI* pCmdUI)
+{
+ UpdateData();
+ pCmdUI->Enable(m_fOverridePlacement);
+}
diff --git a/src/apps/mplayerc/PPageSubtitles.h b/src/apps/mplayerc/PPageSubtitles.h
new file mode 100644
index 000000000..54c8d012c
--- /dev/null
+++ b/src/apps/mplayerc/PPageSubtitles.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "..\..\subtitles\STS.h"
+
+// CPPageSubtitles dialog
+
+class CPPageSubtitles : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageSubtitles)
+
+public:
+ CPPageSubtitles();
+ virtual ~CPPageSubtitles();
+
+ BOOL m_fOverridePlacement;
+ int m_nHorPos;
+ CEdit m_nHorPosEdit;
+ CSpinButtonCtrl m_nHorPosCtrl;
+ int m_nVerPos;
+ CEdit m_nVerPosEdit;
+ CSpinButtonCtrl m_nVerPosCtrl;
+ int m_nSPCSize;
+ CSpinButtonCtrl m_nSPCSizeCtrl;
+ CComboBox m_spmaxres;
+ BOOL m_fSPCPow2Tex;
+
+// Dialog Data
+ enum { IDD = IDD_PPAGESUBTITLES };
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnUpdatePosOverride(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/PPageTweaks.cpp b/src/apps/mplayerc/PPageTweaks.cpp
new file mode 100644
index 000000000..9bad729c6
--- /dev/null
+++ b/src/apps/mplayerc/PPageTweaks.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageTweaks.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PPageTweaks.h"
+
+// CPPageTweaks dialog
+
+IMPLEMENT_DYNAMIC(CPPageTweaks, CPPageBase)
+CPPageTweaks::CPPageTweaks()
+ : CPPageBase(CPPageTweaks::IDD, CPPageTweaks::IDD)
+ , m_fDisabeXPToolbars(FALSE)
+ , m_fUseWMASFReader(FALSE)
+ , m_nJumpDistS(0)
+ , m_nJumpDistM(0)
+ , m_nJumpDistL(0)
+ , m_fFreeWindowResizing(TRUE)
+ , m_fNotifyMSN(TRUE)
+ , m_fNotifyGTSdll(FALSE)
+ , m_GTSdllLink(_T("https://sourceforge.net/project/showfiles.php?group_id=82303&package_id=169521&release_id=371114"))
+{
+ m_fWMASFReader = SUCCEEDED(CComPtr<IBaseFilter>().CoCreateInstance(
+ GUIDFromCString(_T("{187463A0-5BB7-11D3-ACBE-0080C75E246E}")))); // WM ASF Reader
+}
+
+CPPageTweaks::~CPPageTweaks()
+{
+}
+
+void CPPageTweaks::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Check(pDX, IDC_CHECK3, m_fDisabeXPToolbars);
+ DDX_Control(pDX, IDC_CHECK3, m_fDisabeXPToolbarsCtrl);
+ DDX_Check(pDX, IDC_CHECK2, m_fUseWMASFReader);
+ DDX_Control(pDX, IDC_CHECK2, m_fUseWMASFReaderCtrl);
+ DDX_Text(pDX, IDC_EDIT1, m_nJumpDistS);
+ DDX_Text(pDX, IDC_EDIT2, m_nJumpDistM);
+ DDX_Text(pDX, IDC_EDIT3, m_nJumpDistL);
+ DDX_Check(pDX, IDC_CHECK1, m_fFreeWindowResizing);
+ DDX_Check(pDX, IDC_CHECK4, m_fNotifyMSN);
+ DDX_Check(pDX, IDC_CHECK5, m_fNotifyGTSdll);
+ DDX_Control(pDX, IDC_STATICLINKGTS, m_GTSdllLink);
+}
+
+BOOL CPPageTweaks::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_fDisabeXPToolbars = s.fDisabeXPToolbars;
+ m_fUseWMASFReader = s.fUseWMASFReader;
+ m_nJumpDistS = s.nJumpDistS;
+ m_nJumpDistM = s.nJumpDistM;
+ m_nJumpDistL = s.nJumpDistL;
+ m_fFreeWindowResizing = s.fFreeWindowResizing;
+ m_fNotifyMSN = s.fNotifyMSN;
+ m_fNotifyGTSdll = s.fNotifyGTSdll;
+
+ UpdateData(FALSE);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageTweaks::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ s.fDisabeXPToolbars = !!m_fDisabeXPToolbars;
+ s.fUseWMASFReader = !!m_fUseWMASFReader;
+ s.nJumpDistS = m_nJumpDistS;
+ s.nJumpDistM = m_nJumpDistM;
+ s.nJumpDistL = m_nJumpDistL;
+ s.fFreeWindowResizing = !!m_fFreeWindowResizing;
+ s.fNotifyMSN = !!m_fNotifyMSN;
+ s.fNotifyGTSdll = !!m_fNotifyGTSdll;
+
+ return __super::OnApply();
+}
+
+BEGIN_MESSAGE_MAP(CPPageTweaks, CPPageBase)
+ ON_UPDATE_COMMAND_UI(IDC_CHECK3, OnUpdateCheck3)
+ ON_UPDATE_COMMAND_UI(IDC_CHECK2, OnUpdateCheck2)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+END_MESSAGE_MAP()
+
+
+// CPPageTweaks message handlers
+
+void CPPageTweaks::OnUpdateCheck3(CCmdUI* pCmdUI)
+{
+ if(!AfxGetAppSettings().fXpOrBetter)
+ {
+ pCmdUI->Enable(FALSE);
+ pCmdUI->SetCheck(TRUE);
+ }
+}
+
+void CPPageTweaks::OnUpdateCheck2(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_fWMASFReader);
+}
+
+void CPPageTweaks::OnBnClickedButton1()
+{
+ m_nJumpDistS = 1000;
+ m_nJumpDistM = 5000;
+ m_nJumpDistL = 20000;
+
+ UpdateData(FALSE);
+}
+
+
diff --git a/src/apps/mplayerc/PPageTweaks.h b/src/apps/mplayerc/PPageTweaks.h
new file mode 100644
index 000000000..be24cea90
--- /dev/null
+++ b/src/apps/mplayerc/PPageTweaks.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "PPageBase.h"
+#include "StaticLink.h"
+
+// CPPageTweaks dialog
+
+class CPPageTweaks : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageTweaks)
+
+private:
+ bool m_fWMASFReader;
+
+public:
+ CPPageTweaks();
+ virtual ~CPPageTweaks();
+
+ BOOL m_fDisabeXPToolbars;
+ CButton m_fDisabeXPToolbarsCtrl;
+ BOOL m_fUseWMASFReader;
+ CButton m_fUseWMASFReaderCtrl;
+
+// Dialog Data
+ enum { IDD = IDD_PPAGETWEAKS };
+ int m_nJumpDistS;
+ int m_nJumpDistM;
+ int m_nJumpDistL;
+ BOOL m_fFreeWindowResizing;
+ BOOL m_fNotifyMSN;
+ BOOL m_fNotifyGTSdll;
+ CStaticLink m_GTSdllLink;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnUpdateCheck3(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateCheck2(CCmdUI* pCmdUI);
+ afx_msg void OnBnClickedButton1();
+};
diff --git a/src/apps/mplayerc/PPageWebServer.cpp b/src/apps/mplayerc/PPageWebServer.cpp
new file mode 100644
index 000000000..650d578a7
--- /dev/null
+++ b/src/apps/mplayerc/PPageWebServer.cpp
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PPageWebServer.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "MainFrm.h"
+#include "PPageWebServer.h"
+
+// CPPageWebServer dialog
+
+IMPLEMENT_DYNAMIC(CPPageWebServer, CPPageBase)
+CPPageWebServer::CPPageWebServer()
+ : CPPageBase(CPPageWebServer::IDD, CPPageWebServer::IDD)
+ , m_fEnableWebServer(FALSE)
+ , m_nWebServerPort(0)
+ , m_launch(_T("http://localhost:13579/"))
+ , m_fWebServerPrintDebugInfo(FALSE)
+ , m_fWebServerUseCompression(FALSE)
+ , m_fWebRoot(FALSE)
+ , m_WebRoot(_T(""))
+ , m_fWebServerLocalhostOnly(FALSE)
+ , m_WebServerCGI(_T(""))
+ , m_WebDefIndex(_T(""))
+{
+}
+
+CPPageWebServer::~CPPageWebServer()
+{
+}
+
+void CPPageWebServer::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Check(pDX, IDC_CHECK1, m_fEnableWebServer);
+ DDX_Text(pDX, IDC_EDIT1, m_nWebServerPort);
+ DDX_Control(pDX, IDC_EDIT1, m_nWebServerPortCtrl);
+ DDX_Control(pDX, IDC_STATIC1, m_launch);
+ DDX_Check(pDX, IDC_CHECK2, m_fWebServerPrintDebugInfo);
+ DDX_Check(pDX, IDC_CHECK3, m_fWebServerUseCompression);
+ DDX_Check(pDX, IDC_CHECK4, m_fWebRoot);
+ DDX_Text(pDX, IDC_EDIT2, m_WebRoot);
+ DDX_Check(pDX, IDC_CHECK5, m_fWebServerLocalhostOnly);
+ DDX_Text(pDX, IDC_EDIT3, m_WebServerCGI);
+ DDX_Text(pDX, IDC_EDIT9, m_WebDefIndex);
+}
+
+BOOL CPPageWebServer::PreTranslateMessage(MSG* pMsg)
+{
+ if(pMsg->message == WM_LBUTTONDOWN && pMsg->hwnd == m_launch.m_hWnd)
+ {
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ if(CMainFrame* pWnd = (CMainFrame*)AfxGetMainWnd())
+ {
+ if(m_fEnableWebServer)
+ {
+ if(s.nWebServerPort != m_nWebServerPort)
+ {
+ AfxMessageBox(_T("Press apply first, before testing the new settings!"), MB_OK);
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return CPPageBase::PreTranslateMessage(pMsg);
+}
+
+BOOL CPPageWebServer::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ m_fEnableWebServer = s.fEnableWebServer;
+ m_nWebServerPort = s.nWebServerPort;
+ m_fWebServerPrintDebugInfo = s.fWebServerPrintDebugInfo;
+ m_fWebServerLocalhostOnly = s.fWebServerLocalhostOnly;
+ m_fWebServerUseCompression = s.fWebServerUseCompression;
+ m_fWebRoot = s.WebRoot.Find('*') < 0;
+ m_WebRoot = s.WebRoot;
+ m_WebRoot.TrimLeft(_T("*"));
+ m_WebDefIndex = s.WebDefIndex;
+ m_WebServerCGI = s.WebServerCGI;
+
+ UpdateData(FALSE);
+
+ OnEnChangeEdit1();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BOOL CPPageWebServer::OnApply()
+{
+ UpdateData();
+
+ AppSettings& s = AfxGetAppSettings();
+
+ CString NewWebRoot = m_WebRoot;
+ if(!m_fWebRoot) NewWebRoot = _T("*") + NewWebRoot;
+
+ bool fRestart = s.nWebServerPort != m_nWebServerPort
+ || s.WebRoot != NewWebRoot || s.WebServerCGI != m_WebServerCGI;
+
+ s.fEnableWebServer = !!m_fEnableWebServer;
+ s.nWebServerPort = m_nWebServerPort;
+ s.fWebServerPrintDebugInfo = !!m_fWebServerPrintDebugInfo;
+ s.fWebServerLocalhostOnly = !!m_fWebServerLocalhostOnly;
+ s.fWebServerUseCompression = !!m_fWebServerUseCompression;
+ s.WebRoot = NewWebRoot;
+ s.WebDefIndex = m_WebDefIndex;
+ s.WebServerCGI = m_WebServerCGI;
+
+ if(CMainFrame* pWnd = (CMainFrame*)AfxGetMainWnd())
+ {
+ if(m_fEnableWebServer)
+ {
+ if(fRestart) pWnd->StopWebServer();
+ pWnd->StartWebServer(m_nWebServerPort);
+ }
+ else
+ {
+ pWnd->StopWebServer();
+ }
+ }
+
+ return __super::OnApply();
+}
+
+CString CPPageWebServer::GetMPCDir()
+{
+ CString dir;
+ GetModuleFileName(AfxGetInstanceHandle(), dir.GetBuffer(MAX_PATH), MAX_PATH);
+ dir.ReleaseBuffer();
+ CPath path(dir);
+ path.RemoveFileSpec();
+ return (LPCTSTR)path;
+}
+
+CString CPPageWebServer::GetCurWebRoot()
+{
+ CString WebRoot;
+ GetDlgItem(IDC_EDIT2)->GetWindowText(WebRoot);
+ WebRoot.Replace('/', '\\');
+
+ CPath path;
+ path.Combine(GetMPCDir(), WebRoot);
+ return path.IsDirectory() ? (LPCTSTR)path : _T("");
+}
+
+static int __stdcall BrowseCtrlCallback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
+{
+ if(uMsg == BFFM_INITIALIZED && lpData)
+ ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
+ return 0;
+}
+
+bool CPPageWebServer::PickDir(CString& dir)
+{
+ TCHAR buff[MAX_PATH];
+
+ BROWSEINFO bi;
+ bi.hwndOwner = m_hWnd;
+ bi.pidlRoot = NULL;
+ bi.pszDisplayName = buff;
+ bi.lpszTitle = _T("Select the directory");
+ bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_VALIDATE | BIF_USENEWUI;
+ bi.lpfn = BrowseCtrlCallback;
+ bi.lParam = (LPARAM)(LPCTSTR)dir;
+ bi.iImage = 0;
+
+ LPITEMIDLIST iil;
+ if(iil = SHBrowseForFolder(&bi))
+ {
+ SHGetPathFromIDList(iil, buff);
+ dir = buff;
+ return true;
+ }
+
+ return false;
+}
+
+BEGIN_MESSAGE_MAP(CPPageWebServer, CPPageBase)
+ ON_EN_CHANGE(IDC_EDIT1, OnEnChangeEdit1)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+ ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateButton2)
+END_MESSAGE_MAP()
+
+
+// CPPageWebServer message handlers
+
+
+void CPPageWebServer::OnEnChangeEdit1()
+{
+ UpdateData();
+
+ CString link;
+ link.Format(_T("http://localhost:%d/"), m_nWebServerPort);
+ m_launch.m_link = link;
+
+ SetModified();
+}
+
+void CPPageWebServer::OnBnClickedButton1()
+{
+ CString dir = GetCurWebRoot();
+ if(PickDir(dir))
+ {
+ CPath path;
+ if(path.RelativePathTo(GetMPCDir(), FILE_ATTRIBUTE_DIRECTORY, dir, FILE_ATTRIBUTE_DIRECTORY))
+ dir = (LPCTSTR)path;
+ m_WebRoot = dir;
+ UpdateData(FALSE);
+ }
+}
+
+void CPPageWebServer::OnBnClickedButton2()
+{
+ CString dir;
+ if(PickDir(dir))
+ {
+ dir += _T("\\");
+ CWebServer::Deploy(dir);
+ }
+}
+
+void CPPageWebServer::OnUpdateButton2(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(GetDlgItem(IDC_EDIT2)->GetWindowTextLength() > 0);
+}
diff --git a/src/apps/mplayerc/PPageWebServer.h b/src/apps/mplayerc/PPageWebServer.h
new file mode 100644
index 000000000..c89c74417
--- /dev/null
+++ b/src/apps/mplayerc/PPageWebServer.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "PPageBase.h"
+#include "FloatEdit.h"
+#include "StaticLink.h"
+
+// CPPageWebServer dialog
+
+class CPPageWebServer : public CPPageBase
+{
+ DECLARE_DYNAMIC(CPPageWebServer)
+
+private:
+ CString GetMPCDir();
+ CString GetCurWebRoot();
+ bool PickDir(CString& dir);
+
+public:
+ CPPageWebServer();
+ virtual ~CPPageWebServer();
+
+// Dialog Data
+ enum { IDD = IDD_PPAGEWEBSERVER };
+ BOOL m_fEnableWebServer;
+ int m_nWebServerPort;
+ CIntEdit m_nWebServerPortCtrl;
+ CStaticLink m_launch;
+ BOOL m_fWebServerPrintDebugInfo;
+ BOOL m_fWebServerUseCompression;
+ BOOL m_fWebServerLocalhostOnly;
+ BOOL m_fWebRoot;
+ CString m_WebRoot;
+ CString m_WebServerCGI;
+ CString m_WebDefIndex;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnApply();
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnEnChangeEdit1();
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnBnClickedButton2();
+ afx_msg void OnUpdateButton2(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/PixelShaderCompiler.cpp b/src/apps/mplayerc/PixelShaderCompiler.cpp
new file mode 100644
index 000000000..ffab33d6c
--- /dev/null
+++ b/src/apps/mplayerc/PixelShaderCompiler.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "PixelShaderCompiler.h"
+
+CPixelShaderCompiler::CPixelShaderCompiler(IDirect3DDevice9* pD3DDev, bool fStaySilent)
+ : m_pD3DDev(pD3DDev)
+ , m_hDll(NULL)
+ , m_pD3DXCompileShader(NULL)
+ , m_pD3DXDisassembleShader(NULL)
+{
+ CString d3dx9_dll;
+
+ // CASIMIR666 TODO : voir comment detecter la bonne Dll a charger ???
+ d3dx9_dll.Format(_T("d3dx9_%d.dll"), D3DX_SDK_VERSION);
+ m_hDll = LoadLibrary(d3dx9_dll);
+
+
+ if(m_hDll)
+ {
+ m_pD3DXCompileShader = (D3DXCompileShaderPtr)GetProcAddress(m_hDll, "D3DXCompileShader");
+ m_pD3DXDisassembleShader = (D3DXDisassembleShaderPtr)GetProcAddress(m_hDll, "D3DXDisassembleShader");
+ }
+
+ if(!fStaySilent)
+ {
+ if(!m_hDll)
+ {
+ AfxMessageBox(_T("Cannot load ") + d3dx9_dll + _T(", pixel shaders will not work."), MB_OK);
+ }
+ else if(!m_pD3DXCompileShader || !m_pD3DXDisassembleShader)
+ {
+ AfxMessageBox(_T("Cannot find necessary function entry points in ") + d3dx9_dll + _T(", pixel shaders will not work."), MB_OK);
+ }
+ }
+}
+
+CPixelShaderCompiler::~CPixelShaderCompiler()
+{
+ if(m_hDll) FreeLibrary(m_hDll);
+}
+
+HRESULT CPixelShaderCompiler::CompileShader(
+ LPCSTR pSrcData,
+ LPCSTR pFunctionName,
+ LPCSTR pProfile,
+ DWORD Flags,
+ IDirect3DPixelShader9** ppPixelShader,
+ CString* disasm,
+ CString* errmsg)
+{
+ if(!m_pD3DXCompileShader || !m_pD3DXDisassembleShader)
+ return E_FAIL;
+
+ HRESULT hr;
+
+ CComPtr<ID3DXBuffer> pShader, pDisAsm, pErrorMsgs;
+ hr = m_pD3DXCompileShader(pSrcData, strlen(pSrcData), NULL, NULL, pFunctionName, pProfile, Flags, &pShader, &pErrorMsgs, NULL);
+
+ if(FAILED(hr))
+ {
+ if(errmsg)
+ {
+ CStringA msg = "Unexpected compiler error";
+
+ if(pErrorMsgs)
+ {
+ int len = pErrorMsgs->GetBufferSize();
+ memcpy(msg.GetBufferSetLength(len), pErrorMsgs->GetBufferPointer(), len);
+ }
+
+ *errmsg = msg;
+ }
+
+ return hr;
+ }
+
+ if(ppPixelShader)
+ {
+ if(!m_pD3DDev) return E_FAIL;
+ hr = m_pD3DDev->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), ppPixelShader);
+ if(FAILED(hr)) return hr;
+ }
+
+ if(disasm)
+ {
+ hr = m_pD3DXDisassembleShader((DWORD*)pShader->GetBufferPointer(), FALSE, NULL, &pDisAsm);
+ if(SUCCEEDED(hr) && pDisAsm) *disasm = CStringA((const char*)pDisAsm->GetBufferPointer());
+ }
+
+ return S_OK;
+}
diff --git a/src/apps/mplayerc/PixelShaderCompiler.h b/src/apps/mplayerc/PixelShaderCompiler.h
new file mode 100644
index 000000000..e9061d920
--- /dev/null
+++ b/src/apps/mplayerc/PixelShaderCompiler.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <d3dx9shader.h>
+
+class CPixelShaderCompiler
+{
+ typedef HRESULT (WINAPI * D3DXCompileShaderPtr) (
+ LPCSTR pSrcData,
+ UINT SrcDataLen,
+ CONST D3DXMACRO* pDefines,
+ LPD3DXINCLUDE pInclude,
+ LPCSTR pFunctionName,
+ LPCSTR pProfile,
+ DWORD Flags,
+ LPD3DXBUFFER* ppShader,
+ LPD3DXBUFFER* ppErrorMsgs,
+ LPD3DXCONSTANTTABLE* ppConstantTable);
+
+ typedef HRESULT (WINAPI * D3DXDisassembleShaderPtr) (
+ CONST DWORD* pShader,
+ BOOL EnableColorCode,
+ LPCSTR pComments,
+ LPD3DXBUFFER* ppDisassembly);
+
+ HMODULE m_hDll;
+ D3DXCompileShaderPtr m_pD3DXCompileShader;
+ D3DXDisassembleShaderPtr m_pD3DXDisassembleShader;
+
+ CComPtr<IDirect3DDevice9> m_pD3DDev;
+
+public:
+ CPixelShaderCompiler(IDirect3DDevice9* pD3DDev, bool fStaySilent = false);
+ virtual ~CPixelShaderCompiler();
+
+ HRESULT CompileShader(
+ LPCSTR pSrcData,
+ LPCSTR pFunctionName,
+ LPCSTR pProfile,
+ DWORD Flags,
+ IDirect3DPixelShader9** ppPixelShader,
+ CString* disasm = NULL,
+ CString* errmsg = NULL);
+};
diff --git a/src/apps/mplayerc/PlayerCaptureBar.cpp b/src/apps/mplayerc/PlayerCaptureBar.cpp
new file mode 100644
index 000000000..ae43355a2
--- /dev/null
+++ b/src/apps/mplayerc/PlayerCaptureBar.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PlayerCaptureBar.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "mainfrm.h"
+#include "PlayerCaptureBar.h"
+
+
+// CPlayerCaptureBar
+
+IMPLEMENT_DYNAMIC(CPlayerCaptureBar, baseCPlayerCaptureBar)
+CPlayerCaptureBar::CPlayerCaptureBar()
+{
+}
+
+CPlayerCaptureBar::~CPlayerCaptureBar()
+{
+}
+
+BOOL CPlayerCaptureBar::Create(CWnd* pParentWnd)
+{
+ if(!baseCPlayerCaptureBar::Create(_T("Capture Settings"), pParentWnd, 0))
+ return FALSE;
+
+ m_capdlg.Create(this);
+ m_capdlg.ShowWindow(SW_SHOWNORMAL);
+
+ CRect r;
+ m_capdlg.GetWindowRect(r);
+ m_szMinVert = m_szVert = r.Size();
+ m_szMinHorz = m_szHorz = r.Size();
+ m_szMinFloat = m_szFloat = r.Size();
+ m_bFixedFloat = true;
+ m_szFixedFloat = r.Size();
+
+ return TRUE;
+}
+
+BOOL CPlayerCaptureBar::PreTranslateMessage(MSG* pMsg)
+{
+ if(IsWindow(pMsg->hwnd) && IsVisible() && pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
+ {
+ if(IsDialogMessage(pMsg))
+ return TRUE;
+ }
+
+ return __super::PreTranslateMessage(pMsg);
+}
+
+BEGIN_MESSAGE_MAP(CPlayerCaptureBar, baseCPlayerCaptureBar)
+END_MESSAGE_MAP()
+
+// CPlayerCaptureBar message handlers
diff --git a/src/apps/mplayerc/PlayerCaptureBar.h b/src/apps/mplayerc/PlayerCaptureBar.h
new file mode 100644
index 000000000..33c4f66d1
--- /dev/null
+++ b/src/apps/mplayerc/PlayerCaptureBar.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "PlayerCaptureDialog.h"
+
+#ifndef baseCPlayerCaptureBar
+#define baseCPlayerCaptureBar CSizingControlBarG
+#endif
+
+// CPlayerCaptureBar
+
+class CPlayerCaptureBar : public baseCPlayerCaptureBar
+{
+ DECLARE_DYNAMIC(CPlayerCaptureBar)
+
+public:
+ CPlayerCaptureBar();
+ virtual ~CPlayerCaptureBar();
+
+ BOOL Create(CWnd* pParentWnd);
+
+public:
+ CPlayerCaptureDialog m_capdlg;
+
+protected:
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ DECLARE_MESSAGE_MAP()
+};
diff --git a/src/apps/mplayerc/PlayerCaptureDialog.cpp b/src/apps/mplayerc/PlayerCaptureDialog.cpp
new file mode 100644
index 000000000..16624aaf9
--- /dev/null
+++ b/src/apps/mplayerc/PlayerCaptureDialog.cpp
@@ -0,0 +1,1659 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PlayerCaptureDialog.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "mainfrm.h"
+#include "PlayerCaptureDialog.h"
+#include "..\..\DSUtil\DSUtil.h"
+#include "..\..\..\include\moreuuids.h"
+#include "..\..\filters\muxer\wavdest\wavdest.h"
+#include "..\..\filters\muxer\MatroskaMuxer\MatroskaMuxer.h"
+#include "..\..\filters\muxer\DSMMuxer\DSMMuxer.h"
+
+static bool LoadMediaType(CStringW DisplayName, AM_MEDIA_TYPE** ppmt)
+{
+ bool fRet = false;
+
+ if(!ppmt) return(fRet);
+
+ *ppmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
+ if(!*ppmt) return(fRet);
+
+ memset(*ppmt, 0, sizeof(AM_MEDIA_TYPE));
+
+ BYTE* pData;
+ UINT len;
+ if(AfxGetApp()->GetProfileBinary(_T("Capture\\") + CString(DisplayName), _T("MediaType"), &pData, &len))
+ {
+ if(len != sizeof(AM_MEDIA_TYPE)) return(fRet);
+ memcpy(*ppmt, pData, len);
+ delete [] pData;
+
+ (*ppmt)->cbFormat = 0;
+ (*ppmt)->pbFormat = NULL;
+
+ fRet = true;
+
+ if(AfxGetApp()->GetProfileBinary(_T("Capture\\") + CString(DisplayName), _T("Format"), &pData, &len))
+ {
+ if(!len) return(fRet);
+ (*ppmt)->cbFormat = len;
+ (*ppmt)->pbFormat = (BYTE*)CoTaskMemAlloc(len);
+ memcpy((*ppmt)->pbFormat, pData, len);
+ delete [] pData;
+
+ }
+ }
+
+ return(fRet);
+}
+
+static void SaveMediaType(CStringW DisplayName, AM_MEDIA_TYPE* pmt)
+{
+ if(DisplayName.IsEmpty() || !pmt) return;
+
+ AfxGetApp()->WriteProfileBinary(_T("Capture\\") + CString(DisplayName), _T("MediaType"), (BYTE*)pmt, sizeof(AM_MEDIA_TYPE));
+ AfxGetApp()->WriteProfileBinary(_T("Capture\\") + CString(DisplayName), _T("Format"), pmt->pbFormat, pmt->cbFormat);
+}
+
+static void LoadDefaultCodec(CAtlArray<Codec>& codecs, CComboBox& box, const GUID& cat)
+{
+ int len = box.GetCount();
+ if(len >= 0) box.SetCurSel(0);
+
+ if(cat == GUID_NULL) return;
+
+ CString DisplayName = AfxGetApp()->GetProfileString(_T("Capture\\") + CStringFromGUID(cat), _T("DisplayName"));
+
+ for(int i = 0; i < len; i++)
+ {
+ int iSel = box.GetItemData(i);
+ if(iSel < 0) continue;
+
+ Codec& c = codecs[iSel];
+ if(DisplayName == c.DisplayName)
+ {
+ box.SetCurSel(i);
+ if(!c.pBF)
+ c.pMoniker->BindToObject(NULL, NULL, __uuidof(IBaseFilter), (void**)&c.pBF);
+ break;
+ }
+ }
+}
+
+static void SaveDefaultCodec(CAtlArray<Codec>& codecs, CComboBox& box, const GUID& cat)
+{
+ if(cat == GUID_NULL) return;
+
+ CString guid = CStringFromGUID(cat);
+
+ AfxGetApp()->WriteProfileString(_T("Capture\\") + guid, NULL, NULL);
+
+ int iSel = box.GetCurSel();
+ if(iSel < 0) return;
+ iSel = box.GetItemData(iSel);
+ if(iSel < 0) return;
+
+ Codec& codec = codecs[iSel];
+
+ AfxGetApp()->WriteProfileString(_T("Capture\\") + guid, _T("DisplayName"), CString(codec.DisplayName));
+}
+
+static void SetupDefaultCaps(AM_MEDIA_TYPE* pmt, VIDEO_STREAM_CONFIG_CAPS& caps)
+{
+ memset(&caps, 0, sizeof(caps));
+
+ if(!pmt) return;
+
+ VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pmt->pbFormat;
+
+ BITMAPINFOHEADER* bih = (pmt->formattype == FORMAT_VideoInfo)
+ ? &((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader
+ : (pmt->formattype == FORMAT_VideoInfo2)
+ ? &((VIDEOINFOHEADER2*)pmt->pbFormat)->bmiHeader
+ : NULL;
+
+ caps.guid = GUID_NULL;
+ caps.VideoStandard = 0;
+ caps.InputSize.cx = bih->biWidth;
+ caps.InputSize.cy = abs(bih->biHeight);
+ caps.MinCroppingSize = caps.MaxCroppingSize = caps.InputSize;
+ caps.CropGranularityX = caps.CropGranularityY = 1;
+ caps.CropAlignX = caps.CropAlignY = 1;
+ caps.MinOutputSize = CSize(64, 64);
+ caps.MaxOutputSize = CSize(768, 576);
+ caps.OutputGranularityX = 16;
+ caps.OutputGranularityY = 1;
+ caps.StretchTapsX = caps.StretchTapsY = 0;
+ caps.ShrinkTapsX = caps.ShrinkTapsY = 0;
+ caps.MinFrameInterval = 100000i64;
+ caps.MaxFrameInterval = 100000000i64;
+ caps.MinBitsPerSecond = caps.MaxBitsPerSecond = 0;
+}
+
+static void SetupDefaultCaps(AM_MEDIA_TYPE* pmt, AUDIO_STREAM_CONFIG_CAPS& caps)
+{
+ memset(&caps, 0, sizeof(caps));
+
+ if(!pmt) return;
+
+ WAVEFORMATEX* wfe = (WAVEFORMATEX*)pmt->pbFormat;
+
+ caps.guid = GUID_NULL;
+ caps.MinimumChannels = caps.MaximumChannels = wfe->nChannels;
+ caps.ChannelsGranularity = 1;
+ caps.MinimumBitsPerSample = caps.MaximumBitsPerSample = wfe->wBitsPerSample;
+ caps.BitsPerSampleGranularity = 1;
+ caps.MinimumSampleFrequency = caps.MaximumSampleFrequency = wfe->nSamplesPerSec;
+ caps.SampleFrequencyGranularity = 1;
+}
+
+template<class T>
+static void SetupMediaTypes(CComPtr<IAMStreamConfig> pAMSC, CFormatArray<T>& tfa, CComboBox& type, CComboBox& dim, CMediaType& mt)
+{
+ tfa.RemoveAll();
+ type.ResetContent();
+ dim.ResetContent();
+ type.EnableWindow(FALSE);
+ dim.EnableWindow(FALSE);
+
+ if(!pAMSC) return;
+
+ AM_MEDIA_TYPE* pcurmt = NULL;
+ pAMSC->GetFormat(&pcurmt);
+
+ int iCount = 0, iSize;
+ if(SUCCEEDED(pAMSC->GetNumberOfCapabilities(&iCount, &iSize))
+ && iSize == sizeof(T) && iCount > 0)
+ {
+ for(int i = 0; i < iCount; i++)
+ {
+ T caps;
+ AM_MEDIA_TYPE* pmt = NULL;
+ if(SUCCEEDED(pAMSC->GetStreamCaps(i, &pmt, (BYTE*)&caps)))
+ {
+ tfa.AddFormat(pmt, caps);
+ }
+ }
+
+ if(iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
+ {
+ for(int i = 0, cnt = tfa.GetCount(); i < cnt; i++)
+ {
+ if(tfa[i]->GetCount() != 1) continue;
+
+ CFormatElem<T>* pfe = tfa[i]->GetAt(0);
+
+ if(pfe->mt.formattype != FORMAT_VideoInfo
+ && pfe->mt.formattype != FORMAT_VideoInfo2)
+ continue;
+
+ static SIZE presets[] =
+ {
+ {160, 120}, {192, 144},
+ {320, 240}, {384, 288},
+ {480, 240}, {512, 288},
+ {480, 360}, {512, 384},
+ {640, 240}, {768, 288},
+ {640, 480}, {768, 576},
+ {704, 240}, {704, 288},
+ {704, 480}, {704, 576},
+ {720, 240}, {720, 288},
+ {720, 480}, {720, 576},
+ {768, 240}, {768, 288},
+ {768, 480}, {768, 576},
+ };
+
+ VIDEO_STREAM_CONFIG_CAPS* pcaps = (VIDEO_STREAM_CONFIG_CAPS*)&pfe->caps;
+ BITMAPINFOHEADER bihCur;
+ ExtractBIH(&pfe->mt, &bihCur);
+
+ for(int j = 0; j < countof(presets); j++)
+ {
+ if(presets[j].cx == bihCur.biWidth
+ && presets[j].cy == abs(bihCur.biHeight)
+ || presets[j].cx < pcaps->MinOutputSize.cx
+ || presets[j].cx > pcaps->MaxOutputSize.cx
+ || presets[j].cy < pcaps->MinOutputSize.cy
+ || presets[j].cy > pcaps->MaxOutputSize.cy
+ || presets[j].cx % pcaps->OutputGranularityX
+ || presets[j].cy % pcaps->OutputGranularityY)
+ continue;
+
+ CMediaType mt = pfe->mt;
+
+ if(mt.formattype == FORMAT_VideoInfo)
+ {
+ VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)mt.pbFormat;
+ if(!vih->bmiHeader.biHeight) vih->bmiHeader.biHeight = 1;
+ vih->bmiHeader.biWidth = presets[j].cx;
+ vih->bmiHeader.biHeight = presets[j].cy*(vih->bmiHeader.biHeight/vih->bmiHeader.biHeight);
+ vih->bmiHeader.biSizeImage = presets[j].cx*presets[j].cy*vih->bmiHeader.biBitCount>>3;
+
+ AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
+ CopyMediaType(pmt, &mt);
+ tfa.AddFormat(pmt, pcaps, sizeof(*pcaps));
+
+ if(presets[j].cx*3 != presets[j].cy*4)
+ {
+ int extra = mt.cbFormat - sizeof(VIDEOINFOHEADER);
+ int bmiHeaderSize = sizeof(vih->bmiHeader) + extra;
+ BYTE* pbmiHeader = new BYTE[bmiHeaderSize];
+ memcpy(pbmiHeader, &vih->bmiHeader, bmiHeaderSize);
+ mt.ReallocFormatBuffer(FIELD_OFFSET(VIDEOINFOHEADER2, bmiHeader) + bmiHeaderSize);
+ VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)mt.pbFormat;
+ memcpy(&vih2->bmiHeader, pbmiHeader, bmiHeaderSize);
+ delete [] pbmiHeader;
+ vih2->dwInterlaceFlags = vih2->dwCopyProtectFlags = 0;
+ vih2->dwReserved1 = vih2->dwReserved2 = 0;
+ vih2->dwPictAspectRatioX = 4;
+ vih2->dwPictAspectRatioY = 3;
+
+ AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
+ CopyMediaType(pmt, &mt);
+ tfa.AddFormat(pmt, pcaps, sizeof(*pcaps));
+ }
+ }
+ else if(mt.formattype == FORMAT_VideoInfo2)
+ {
+ VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)mt.pbFormat;
+ if(!vih2->bmiHeader.biHeight) vih2->bmiHeader.biHeight = 1;
+ vih2->bmiHeader.biWidth = presets[j].cx;
+ vih2->bmiHeader.biHeight = presets[j].cy*(vih2->bmiHeader.biHeight/vih2->bmiHeader.biHeight);
+ vih2->bmiHeader.biSizeImage = presets[j].cx*presets[j].cy*vih2->bmiHeader.biBitCount>>3;
+ vih2->dwPictAspectRatioX = 4;
+ vih2->dwPictAspectRatioY = 3;
+
+ AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
+ CopyMediaType(pmt, &mt);
+ tfa.AddFormat(pmt, pcaps, sizeof(*pcaps));
+ }
+ }
+ }
+ }
+ }
+
+ if(tfa.GetCount() == 0)
+ {
+ if(pcurmt && (pcurmt->majortype == MEDIATYPE_Video || pcurmt->majortype == MEDIATYPE_Audio))
+ {
+ AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
+ CopyMediaType(pmt, pcurmt);
+ T caps;
+ SetupDefaultCaps(pmt, caps);
+ tfa.AddFormat(pmt, caps);
+ }
+ else
+ {
+ mt.majortype = GUID_NULL;
+ if(pcurmt) DeleteMediaType(pcurmt);
+ return;
+ }
+ }
+
+ for(int i = 0; i < (int)tfa.GetCount(); i++)
+ {
+ CFormat<T>* pf = tfa[i];
+ int j = type.AddString(pf->name);
+ type.SetItemData(j, (DWORD_PTR)pf);
+ }
+
+ CFormat<T>* pf = NULL;
+ CFormatElem<T>* pfe = NULL;
+
+ if(!pcurmt)
+ {
+ pf = tfa[0];
+ pfe = pf->GetAt(0);
+ }
+ else if(!tfa.FindFormat(pcurmt, NULL, &pf, &pfe) && !tfa.FindFormat(pcurmt, &pf))
+ {
+ if(pcurmt) DeleteMediaType(pcurmt);
+ return;
+ }
+
+ for(int i = 0; i < (int)pf->GetCount(); i++)
+ {
+ CFormatElem<T>* pfe = pf->GetAt(i);
+ int j = dim.AddString(tfa.MakeDimensionName(pfe));
+ dim.SetItemData(j, (DWORD_PTR)pfe);
+ }
+
+ int iType = type.SetCurSel(type.FindStringExact(0, pf->name));
+ if(iType < 0 && type.GetCount()) type.SetCurSel(0);
+ int iDim = dim.SetCurSel(dim.FindStringExact(0, tfa.MakeDimensionName(pfe)));
+// if(iDim < 0 && dim.GetCount()) dim.SetCurSel(iDim = 0);
+
+ CorrectComboListWidth(type, type.GetParent()->GetFont());
+ CorrectComboListWidth(dim, dim.GetParent()->GetFont());
+
+ if(iDim >= 0) mt = ((CFormatElem<T>*)dim.GetItemData(iDim))->mt;
+ else if(pcurmt) mt = *pcurmt;
+
+ type.EnableWindow(type.GetCount() > 0);
+ dim.EnableWindow(dim.GetCount() > 0);
+
+ if(pcurmt) DeleteMediaType(pcurmt);
+}
+
+template<class T>
+static bool SetupDimension(CFormatArray<T>& tfa, CComboBox& type, CComboBox& dim)
+{
+ CString str;
+ dim.GetWindowText(str);
+
+ dim.ResetContent();
+ dim.EnableWindow(FALSE);
+
+ int iSel = type.GetCurSel();
+ if(iSel < 0) return(false);
+
+ CFormat<T>* pf = (CFormat<T>*)type.GetItemData(iSel);
+
+ for(int i = 0; i < (int)pf->GetCount(); i++)
+ {
+ CFormatElem<T>* pfe = pf->GetAt(i);
+ dim.SetItemData(dim.AddString(tfa.MakeDimensionName(pfe)), (DWORD_PTR)pfe);
+ }
+
+ CorrectComboListWidth(dim, dim.GetParent()->GetFont());
+
+ dim.SetCurSel(dim.FindStringExact(0, str));
+ dim.EnableWindow(dim.GetCount() > 0);
+
+ return(dim.GetCurSel() >= 0);
+}
+
+static void InitCodecList(CAtlArray<Codec>& codecs, CComboBox& box, const GUID& cat)
+{
+ codecs.RemoveAll();
+ box.ResetContent();
+ box.EnableWindow(FALSE);
+
+ box.SetItemData(box.AddString(_T("Uncompressed")), (DWORD_PTR)-1);
+
+ BeginEnumSysDev(cat, pMoniker)
+ {
+ Codec c;
+
+ c.pMoniker = pMoniker;
+/*
+ CComPtr<IBaseFilter> pBF;
+ if(FAILED(pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pBF)) || !pBF)
+ continue;
+
+ c.pBF = pBF;
+*/
+ LPOLESTR strName = NULL;
+ if(FAILED(pMoniker->GetDisplayName(NULL, NULL, &strName)))
+ continue;
+
+ c.DisplayName = strName;
+ CoTaskMemFree(strName);
+
+ CComPtr<IPropertyBag> pPB;
+ pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB);
+
+ CComVariant var;
+ if(FAILED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL)))
+ continue;
+
+ c.FriendlyName = var.bstrVal;
+
+ CStringW str = CStringW(c.DisplayName).MakeLower();
+ if(str.Find(L"@device:dmo:") == 0)
+ c.FriendlyName = _T("(DMO) ") + c.FriendlyName;
+ else if(str.Find(L"@device:sw:") == 0)
+ c.FriendlyName = _T("(DS) ") + c.FriendlyName;
+ else if(str.Find(L"@device:cm:") == 0)
+ c.FriendlyName = _T("(VfW) ") + c.FriendlyName;
+
+ box.SetItemData(
+ box.AddString(c.FriendlyName),
+ (DWORD_PTR)codecs.Add(c));
+ }
+ EndEnumSysDev
+
+ box.EnableWindow(box.GetCount() > 1);
+
+ CorrectComboListWidth(box, box.GetParent()->GetFont());
+
+ LoadDefaultCodec(codecs, box, cat);
+}
+
+static int ShowPPage(CAtlArray<Codec>& codecs, CComboBox& box, HWND hWnd = NULL)
+{
+ int iSel = box.GetCurSel();
+ if(iSel < 0) return(-1);
+
+ iSel = box.GetItemData(iSel);
+ if(iSel < 0) return(-1);
+
+ Codec& c = codecs[iSel];
+
+ if(!c.pBF)
+ {
+ c.pMoniker->BindToObject(NULL, NULL, __uuidof(IBaseFilter), (void**)&c.pBF);
+ }
+
+ if(CComQIPtr<ISpecifyPropertyPages> pSPP = c.pBF)
+ {
+ CAUUID caGUID;
+ caGUID.pElems = NULL;
+ if(SUCCEEDED(pSPP->GetPages(&caGUID)))
+ {
+ IUnknown* lpUnk = NULL;
+ pSPP.QueryInterface(&lpUnk);
+ OleCreatePropertyFrame(
+ hWnd, 0, 0, CStringW(c.FriendlyName),
+ 1, (IUnknown**)&lpUnk,
+ caGUID.cElems, caGUID.pElems,
+ 0, 0, NULL);
+ lpUnk->Release();
+
+ if(caGUID.pElems) CoTaskMemFree(caGUID.pElems);
+ }
+ }
+ else if(CComQIPtr<IAMVfwCompressDialogs> pAMVfWCD = c.pBF)
+ {
+ if(pAMVfWCD->ShowDialog(VfwCompressDialog_QueryConfig, NULL) == S_OK)
+ pAMVfWCD->ShowDialog(VfwCompressDialog_Config, hWnd);
+ }
+
+ return(iSel);
+}
+
+// CPlayerCaptureDialog dialog
+
+//IMPLEMENT_DYNAMIC(CPlayerCaptureDialog, CResizableDialog)
+CPlayerCaptureDialog::CPlayerCaptureDialog()
+ : CResizableDialog(CPlayerCaptureDialog::IDD, NULL)
+ , m_vidfps(0)
+ , m_file(_T(""))
+ , m_fVidOutput(TRUE)
+ , m_fAudOutput(TRUE)
+ , m_fVidPreview(FALSE)
+ , m_fAudPreview(FALSE)
+ , m_nVidBuffers(0)
+ , m_nAudBuffers(0)
+ , m_pVidBuffer(NULL)
+ , m_pAudBuffer(NULL)
+ , m_fSepAudio(FALSE)
+ , m_muxtype(0)
+{
+}
+
+CPlayerCaptureDialog::~CPlayerCaptureDialog()
+{
+ EmptyVideo();
+ EmptyAudio();
+}
+
+BOOL CPlayerCaptureDialog::Create(CWnd* pParent)
+{
+ if(!__super::Create(IDD, pParent))
+ return FALSE;
+
+ EmptyVideo();
+ EmptyAudio();
+
+ return TRUE;
+}
+
+void CPlayerCaptureDialog::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_COMBO4, m_vidinput);
+ DDX_Control(pDX, IDC_COMBO1, m_vidtype);
+ DDX_Control(pDX, IDC_COMBO5, m_viddimension);
+ DDX_Control(pDX, IDC_SPIN1, m_vidhor);
+ DDX_Control(pDX, IDC_SPIN2, m_vidver);
+ DDX_Control(pDX, IDC_EDIT1, m_vidhoredit);
+ DDX_Control(pDX, IDC_EDIT2, m_vidveredit);
+ DDX_Control(pDX, IDC_EDIT3, m_vidfpsedit);
+ DDX_Control(pDX, IDC_BUTTON1, m_vidsetres);
+ DDX_Control(pDX, IDC_COMBO3, m_audinput);
+ DDX_Control(pDX, IDC_COMBO2, m_audtype);
+ DDX_Control(pDX, IDC_COMBO6, m_auddimension);
+ DDX_Control(pDX, IDC_COMBO7, m_vidcodec);
+ DDX_Control(pDX, IDC_COMBO9, m_vidcodectype);
+ DDX_Control(pDX, IDC_COMBO10, m_vidcodecdimension);
+ DDX_Check(pDX, IDC_CHECK1, m_fVidOutput);
+ DDX_Control(pDX, IDC_CHECK1, m_vidoutput);
+ DDX_Check(pDX, IDC_CHECK2, m_fVidPreview);
+ DDX_Control(pDX, IDC_CHECK2, m_vidpreview);
+ DDX_Control(pDX, IDC_COMBO8, m_audcodec);
+ DDX_Control(pDX, IDC_COMBO12, m_audcodectype);
+ DDX_Control(pDX, IDC_COMBO11, m_audcodecdimension);
+ DDX_Check(pDX, IDC_CHECK3, m_fAudOutput);
+ DDX_Control(pDX, IDC_CHECK3, m_audoutput);
+ DDX_Check(pDX, IDC_CHECK4, m_fAudPreview);
+ DDX_Control(pDX, IDC_CHECK4, m_audpreview);
+ DDX_Text(pDX, IDC_EDIT4, m_file);
+ DDX_Control(pDX, IDC_BUTTON2, m_recordbtn);
+ DDX_Text(pDX, IDC_EDIT5, m_nVidBuffers);
+ DDX_Text(pDX, IDC_EDIT6, m_nAudBuffers);
+ DDX_Check(pDX, IDC_CHECK5, m_fSepAudio);
+ DDX_CBIndex(pDX, IDC_COMBO14, m_muxtype);
+ DDX_Control(pDX, IDC_COMBO14, m_muxctrl);
+}
+
+BOOL CPlayerCaptureDialog::PreTranslateMessage(MSG* pMsg)
+{
+ if(pMsg->message == WM_KEYDOWN)
+ {
+ if(pMsg->wParam == VK_RETURN)
+ {
+ CWnd* pFocused = GetFocus();
+ if(pFocused && pFocused->m_hWnd == m_vidfpsedit.m_hWnd)
+ {
+ UpdateGraph();
+ }
+ }
+ }
+
+ return __super::PreTranslateMessage(pMsg);
+}
+
+
+void CPlayerCaptureDialog::EmptyVideo()
+{
+ // first save channel from previous session
+
+ if(m_pAMTuner && !m_VidDisplayName.IsEmpty())
+ {
+ long lChannel = 0, lVivSub = 0, lAudSub = 0;
+ m_pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub);
+ AfxGetApp()->WriteProfileInt(_T("Capture\\") + CString(m_VidDisplayName), _T("Channel"), lChannel);
+ }
+
+ //
+
+ m_vfa.RemoveAll();
+
+ m_pAMXB = NULL;
+ m_pAMTuner = NULL;
+ m_pAMVSC = NULL;
+
+ if(IsWindow(m_hWnd))
+ {
+ m_vidinput.ResetContent();
+ m_vidinput.EnableWindow(FALSE);
+ m_vidtype.ResetContent();
+ m_vidtype.EnableWindow(FALSE);
+ m_viddimension.ResetContent();
+ m_viddimension.EnableWindow(FALSE);
+ m_vidhor.EnableWindow(FALSE);
+ m_vidver.EnableWindow(FALSE);
+ m_vidhoredit.EnableWindow(FALSE);
+ m_vidveredit.EnableWindow(FALSE);
+ m_vidfpsedit.EnableWindow(FALSE);
+ m_vidfps = 0;
+ m_vidsetres.EnableWindow(FALSE);
+ UpdateData(FALSE);
+ }
+}
+
+void CPlayerCaptureDialog::EmptyAudio()
+{
+ m_afa.RemoveAll();
+
+ m_pAMASC = NULL;
+ m_pAMAIM.RemoveAll();
+
+ if(IsWindow(m_hWnd))
+ {
+ m_audinput.ResetContent();
+ m_audinput.EnableWindow(FALSE);
+ m_audtype.ResetContent();
+ m_audtype.EnableWindow(FALSE);
+ m_auddimension.ResetContent();
+ m_auddimension.EnableWindow(FALSE);
+ UpdateData(FALSE);
+ }
+}
+
+void CPlayerCaptureDialog::UpdateMediaTypes()
+{
+ UpdateData();
+
+ // fps
+
+ CString fps;
+ m_vidfpsedit.GetWindowText(fps);
+ if(!fps.IsEmpty())
+ {
+ float ffps;
+ _stscanf(fps, _T("%f"), &ffps);
+ if(ffps > 0) m_vidfps = ffps;
+ }
+
+ // video
+
+ {
+ AM_MEDIA_TYPE* pmt = NULL;
+ VIDEO_STREAM_CONFIG_CAPS* pcaps = NULL;
+
+ int i = m_viddimension.GetCurSel();
+ if(i >= 0)
+ {
+ pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
+ CopyMediaType(pmt, &((CVidFormatElem*)m_viddimension.GetItemData(i))->mt);
+ pcaps = &((CVidFormatElem*)m_viddimension.GetItemData(i))->caps;
+ }
+ else if(m_pAMVSC)
+ {
+ m_pAMVSC->GetFormat(&pmt);
+ }
+
+ if(pmt)
+ {
+ if(m_vidfps > 0)
+ {
+ REFERENCE_TIME atpf = (REFERENCE_TIME)(10000000.0 / m_vidfps);
+
+ if(pcaps)
+ {
+ // FIXME: some drivers do not set the interval right and they still accept the preferable but unfortunately out-of-range fps
+// atpf = min(max(atpf, pcaps->MinFrameInterval), pcaps->MaxFrameInterval);
+ }
+
+ if(pmt->formattype == FORMAT_VideoInfo)
+ ((VIDEOINFOHEADER*)pmt->pbFormat)->AvgTimePerFrame = atpf;
+ else if(pmt->formattype == FORMAT_VideoInfo2)
+ ((VIDEOINFOHEADER2*)pmt->pbFormat)->AvgTimePerFrame = atpf;
+ }
+
+ BITMAPINFOHEADER* bih = (pmt->formattype == FORMAT_VideoInfo)
+ ? &((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader
+ : (pmt->formattype == FORMAT_VideoInfo2)
+ ? &((VIDEOINFOHEADER2*)pmt->pbFormat)->bmiHeader
+ : NULL;
+
+ bih->biWidth = m_vidhor.GetPos();
+ bih->biHeight = m_vidver.GetPos();
+ bih->biSizeImage = bih->biWidth*bih->biHeight*bih->biBitCount>>3;
+
+ SaveMediaType(m_VidDisplayName, pmt);
+
+ m_mtv = *pmt;
+ DeleteMediaType(pmt);
+ }
+ }
+
+ // audio
+
+ {
+ AM_MEDIA_TYPE* pmt = NULL;
+
+ int i = m_auddimension.GetCurSel();
+ if(i >= 0)
+ {
+ pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
+ CopyMediaType(pmt, &((CAudFormatElem*)m_auddimension.GetItemData(i))->mt);
+ }
+ else if(m_pAMASC)
+ {
+ m_pAMASC->GetFormat(&pmt);
+ }
+
+ if(pmt)
+ {
+ SaveMediaType(m_AudDisplayName, pmt);
+
+ m_mta = *pmt;
+ DeleteMediaType(pmt);
+ }
+ }
+}
+
+void CPlayerCaptureDialog::UpdateUserDefinableControls()
+{
+ int iSel = m_viddimension.GetCurSel();
+ if(iSel < 0) return;
+
+ CVidFormatElem* pvfe = (CVidFormatElem*)m_viddimension.GetItemData(iSel);
+ if(!pvfe) return;
+
+ if(!m_pAMVSC) return;
+
+ AM_MEDIA_TYPE* pmt = NULL;
+ m_pAMVSC->GetFormat(&pmt);
+ if(!pmt) return;
+
+ BITMAPINFOHEADER* bih = (pmt->formattype == FORMAT_VideoInfo)
+ ? &((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader
+ : (pmt->formattype == FORMAT_VideoInfo2)
+ ? &((VIDEOINFOHEADER2*)pmt->pbFormat)->bmiHeader
+ : NULL;
+
+ if(!bih) return;
+
+ UDACCEL ua[3] = {{0,0},{2,0},{4,0}};
+
+ int w = m_vidhor.GetPos(), h = m_vidver.GetPos();
+
+ m_vidhor.SetRange((short)pvfe->caps.MinOutputSize.cx, (short)pvfe->caps.MaxOutputSize.cx);
+/* if(bih->biCompression == mmioFOURCC('Y','U','Y','2')) // FIXME: bt8x8 drivers seem to crop the right side in yuv2 mode if the width is not divisable by 64
+ pvfe->caps.OutputGranularityX = 64;
+*/
+ ua[0].nInc = pvfe->caps.OutputGranularityX;
+ ua[1].nInc = pvfe->caps.OutputGranularityX*2;
+ ua[2].nInc = pvfe->caps.OutputGranularityX*4;
+ m_vidhor.SetAccel(3, ua);
+
+ m_vidver.SetRange((short)pvfe->caps.MinOutputSize.cy, (short)pvfe->caps.MaxOutputSize.cy);
+ ua[0].nInc = pvfe->caps.OutputGranularityY;
+ ua[1].nInc = pvfe->caps.OutputGranularityY*2;
+ ua[2].nInc = pvfe->caps.OutputGranularityY*4;
+ m_vidver.SetAccel(3, ua);
+
+ m_vidhor.SetPos(bih->biWidth);
+ m_vidver.SetPos(abs(bih->biHeight));
+
+ CString fps;
+ fps.Format(_T("%.4f"), (float)(10000000.0 / ((VIDEOINFOHEADER*)pmt->pbFormat)->AvgTimePerFrame));
+ m_vidfpsedit.SetWindowText(fps);
+
+ DeleteMediaType(pmt);
+}
+
+void CPlayerCaptureDialog::UpdateVideoCodec()
+{
+ int iSel = m_vidcodec.GetCurSel();
+ if(iSel >= 0) iSel = m_vidcodec.GetItemData(iSel);
+
+ m_pVidEnc = iSel < 0 ? NULL : m_pVidEncArray[iSel].pBF;
+ m_pVidEncMoniker = iSel < 0 ? NULL : m_pVidEncArray[iSel].pMoniker;
+
+// CString DisplayName = iSel < 0 ? _T("") : CString(m_pVidEncArray[iSel].DisplayName.m_str);
+ CComQIPtr<IAMStreamConfig> pAMSC = GetFirstPin(m_pVidEnc, PINDIR_OUTPUT);
+
+ SetupMediaTypes(pAMSC, m_vcfa, m_vidcodectype, m_vidcodecdimension, m_mtcv);
+
+ SaveDefaultCodec(m_pVidEncArray, m_vidcodec, CLSID_VideoCompressorCategory);
+
+// SaveMediaType(DisplayName, &m_mtcv);
+}
+
+void CPlayerCaptureDialog::UpdateAudioCodec()
+{
+ int iSel = m_audcodec.GetCurSel();
+ if(iSel >= 0) iSel = m_audcodec.GetItemData(iSel);
+
+ m_pAudEnc = iSel < 0 ? NULL : m_pAudEncArray[iSel].pBF;
+ m_pAudEncMoniker = iSel < 0 ? NULL : m_pAudEncArray[iSel].pMoniker;
+
+// CString DisplayName = iSel < 0 ? _T("") : CString(m_pAudEncArray[iSel].DisplayName.m_str);
+ CComQIPtr<IAMStreamConfig> pAMSC = GetFirstPin(m_pAudEnc, PINDIR_OUTPUT);
+
+ SetupMediaTypes(pAMSC, m_acfa, m_audcodectype, m_audcodecdimension, m_mtca);
+
+ SaveDefaultCodec(m_pAudEncArray, m_audcodec, CLSID_AudioCompressorCategory);
+
+// SaveMediaType(DisplayName, &m_mtca);
+}
+
+void CPlayerCaptureDialog::UpdateMuxer()
+{
+ m_pMux = NULL;
+ m_pAudMux = NULL;
+
+ UpdateData();
+
+ HRESULT hr;
+
+ if(m_muxtype == 0) m_pMux.CoCreateInstance(CLSID_AviDest);
+ else if(m_muxtype == 1) m_pMux.CoCreateInstance(CLSID_OggMux);
+ else if(m_muxtype == 2) m_pMux = new CMatroskaMuxerFilter(NULL, &hr);
+ else if(m_muxtype == 3) m_pMux = new CDSMMuxerFilter(NULL, &hr);
+ else return;
+
+ if(m_fSepAudio) m_pAudMux = new CWavDestFilter(NULL, &hr);
+}
+
+void CPlayerCaptureDialog::UpdateOutputControls()
+{
+ UpdateData();
+
+ m_recordbtn.EnableWindow(!m_file.IsEmpty() && (m_pAMVSC && m_fVidOutput || m_pAMASC && m_fAudOutput));
+ m_vidcodec.EnableWindow(TRUE);
+ m_audcodec.EnableWindow(TRUE);
+}
+
+void CPlayerCaptureDialog::UpdateGraph()
+{
+ UpdateMediaTypes();
+
+// UpdateMuxer();
+
+ ((CMainFrame*)AfxGetMainWnd())->BuildGraphVideoAudio(m_fVidPreview, false, m_fAudPreview, false);
+
+ UpdateUserDefinableControls();
+}
+
+void CPlayerCaptureDialog::EnableControls(CWnd* pWnd, bool fEnable)
+{
+ if(fEnable)
+ {
+ for(CWnd* pChild = pWnd->GetWindow(GW_CHILD); pChild; pChild = pChild->GetNextWindow())
+ {
+ BOOL fEnabled;
+ if(m_wndenabledmap.Lookup(pChild->m_hWnd, fEnabled))
+ pChild->EnableWindow(fEnabled);
+ EnableControls(pChild, fEnable);
+ }
+
+ if(pWnd->m_hWnd == m_hWnd)
+ m_wndenabledmap.RemoveAll();
+
+ m_recordbtn.SetWindowText(_T("Record"));
+ }
+ else
+ {
+ if(pWnd->m_hWnd == m_hWnd)
+ m_wndenabledmap.RemoveAll();
+
+ for(CWnd* pChild = pWnd->GetWindow(GW_CHILD); pChild; pChild = pChild->GetNextWindow())
+ {
+ m_wndenabledmap[pChild->m_hWnd] = pChild->IsWindowEnabled();
+ pChild->EnableWindow(FALSE);
+ EnableControls(pChild, fEnable);
+ }
+
+ m_recordbtn.EnableWindow(TRUE);
+ m_recordbtn.SetWindowText(_T("Stop"));
+ }
+}
+
+void CPlayerCaptureDialog::SetupVideoControls(
+ CStringW DisplayName,
+ CComPtr<IAMStreamConfig> pAMSC, CComPtr<IAMCrossbar> pAMXB, CComPtr<IAMTVTuner> pAMTuner)
+{
+ EmptyVideo();
+
+ // crossbar
+
+ if(m_pAMXB = pAMXB)
+ {
+ long OutputPinCount, InputPinCount;
+ if(SUCCEEDED(pAMXB->get_PinCounts(&OutputPinCount, &InputPinCount)))
+ {
+ for(int i = 0; i < InputPinCount; i++)
+ {
+ long PinIndexRelated, PhysicalType;
+ if(FAILED(pAMXB->get_CrossbarPinInfo(TRUE, i, &PinIndexRelated, &PhysicalType)))
+ continue;
+
+ if(PhysicalType >= PhysConn_Audio_Tuner)
+ continue;
+
+ CString str;
+ switch(PhysicalType)
+ {
+ case PhysConn_Video_Tuner: str = _T("Tuner"); break;
+ case PhysConn_Video_Composite: str = _T("Composite"); break;
+ case PhysConn_Video_SVideo: str = _T("SVideo"); break;
+ case PhysConn_Video_RGB: str = _T("RGB"); break;
+ case PhysConn_Video_YRYBY: str = _T("YRYBY"); break;
+ case PhysConn_Video_SerialDigital: str = _T("SerialDigital"); break;
+ case PhysConn_Video_ParallelDigital: str = _T("ParallelDigital"); break;
+ case PhysConn_Video_SCSI: str = _T("SCSI"); break;
+ case PhysConn_Video_AUX: str = _T("AUX"); break;
+ case PhysConn_Video_1394: str = _T("1394"); break;
+ case PhysConn_Video_USB: str = _T("USB"); break;
+ case PhysConn_Video_VideoDecoder: str = _T("VideoDecoder"); break;
+ case PhysConn_Video_VideoEncoder: str = _T("VideoEncoder"); break;
+ case PhysConn_Video_SCART: str = _T("SCART"); break;
+ default: str.Format(_T("PhysicalType %d"), PhysicalType); break;
+ }
+
+ m_vidinput.SetItemData(m_vidinput.AddString(str), i);
+ }
+ }
+ }
+
+ if(m_vidinput.GetCount() > 0)
+ {
+ m_vidinput.EnableWindow(TRUE);
+
+ long OutputPinCount, InputPinCount;
+ if(SUCCEEDED(pAMXB->get_PinCounts(&OutputPinCount, &InputPinCount)))
+ {
+ for(int i = 0; i < OutputPinCount; i++)
+ {
+ long InputPinIndex;
+ if(S_OK == pAMXB->get_IsRoutedTo(i, &InputPinIndex))
+ {
+ for(int j = 0; j < m_vidinput.GetCount(); j++)
+ {
+ if(m_vidinput.GetItemData(j) == InputPinIndex)
+ {
+ m_vidinput.SetCurSel(j);
+ i = OutputPinCount;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // tuner
+
+ if(m_pAMTuner = pAMTuner)
+ {
+ // TODO:...
+ }
+
+ // streamconfig
+
+ if(m_pAMVSC = pAMSC)
+ {
+ m_VidDisplayName = DisplayName;
+
+ AM_MEDIA_TYPE* pmt;
+ if(LoadMediaType(DisplayName, &pmt))
+ {
+ pAMSC->SetFormat(pmt);
+ DeleteMediaType(pmt);
+ }
+
+ SetupMediaTypes(pAMSC, m_vfa, m_vidtype, m_viddimension, m_mtv);
+ }
+
+ if(m_vidtype.GetCount() > 0)
+ {
+ m_vidfpsedit.EnableWindow(TRUE);
+ m_vidhor.EnableWindow(TRUE);
+ m_vidver.EnableWindow(TRUE);
+ m_vidhoredit.EnableWindow(TRUE);
+ m_vidveredit.EnableWindow(TRUE);
+ m_vidsetres.EnableWindow(TRUE);
+ }
+
+ {
+ m_vidoutput.EnableWindow(TRUE);
+ m_vidpreview.EnableWindow(TRUE);
+ }
+
+ UpdateMediaTypes();
+
+ UpdateUserDefinableControls();
+
+ UpdateOutputControls();
+}
+
+void CPlayerCaptureDialog::SetupVideoControls(
+ CStringW DisplayName,
+ CComPtr<IAMStreamConfig> pAMSC, CComPtr<IAMVfwCaptureDialogs> pAMVfwCD)
+{
+ EmptyVideo();
+
+ if(m_pAMVfwCD = pAMVfwCD)
+ {
+ if(S_OK == m_pAMVfwCD->HasDialog(VfwCaptureDialog_Source))
+ m_vidinput.SetItemData(m_vidinput.AddString(_T("Source")), (DWORD_PTR)VfwCaptureDialog_Source);
+ if(S_OK == m_pAMVfwCD->HasDialog(VfwCaptureDialog_Format))
+ m_vidinput.SetItemData(m_vidinput.AddString(_T("Format")), (DWORD_PTR)VfwCaptureDialog_Format);
+ if(S_OK == m_pAMVfwCD->HasDialog(VfwCaptureDialog_Display))
+ m_vidinput.SetItemData(m_vidinput.AddString(_T("Display")), (DWORD_PTR)VfwCaptureDialog_Display);
+
+ if(m_vidinput.GetCount() > 0)
+ {
+ m_vidinput.EnableWindow(TRUE);
+ m_vidinput.SetCurSel(0);
+ }
+ }
+
+ // streamconfig
+
+ if(m_pAMVSC = pAMSC)
+ {
+ m_VidDisplayName = DisplayName;
+
+ AM_MEDIA_TYPE* pmt;
+ if(LoadMediaType(DisplayName, &pmt))
+ {
+ pAMSC->SetFormat(pmt);
+ DeleteMediaType(pmt);
+ }
+
+ SetupMediaTypes(pAMSC, m_vfa, m_vidtype, m_viddimension, m_mtv);
+ }
+
+ if(m_vidtype.GetCount() > 0)
+ {
+ m_vidfpsedit.EnableWindow(TRUE);
+ m_vidhor.EnableWindow(TRUE);
+ m_vidver.EnableWindow(TRUE);
+ m_vidhoredit.EnableWindow(TRUE);
+ m_vidveredit.EnableWindow(TRUE);
+ m_vidsetres.EnableWindow(TRUE);
+ }
+
+ {
+ m_vidoutput.EnableWindow(TRUE);
+ m_vidpreview.EnableWindow(TRUE);
+ }
+
+ UpdateMediaTypes();
+
+ UpdateUserDefinableControls();
+
+ UpdateOutputControls();
+}
+
+void CPlayerCaptureDialog::SetupAudioControls(
+ CStringW DisplayName,
+ CComPtr<IAMStreamConfig> pAMSC, CInterfaceArray<IAMAudioInputMixer>& pAMAIM)
+{
+ EmptyAudio();
+
+ // input selection
+
+ if(pAMAIM.GetCount() > 0)
+ {
+ m_pAMAIM.Copy(pAMAIM);
+
+ int iSel = -1;
+
+ for(int i = 0; i < (int)m_pAMAIM.GetCount(); i++)
+ {
+ CComQIPtr<IPin> pPin = m_pAMAIM[i];
+ m_audinput.SetItemData(m_audinput.AddString(CString(GetPinName(pPin))), (DWORD_PTR)i);
+
+ BOOL fEnable;
+ if(SUCCEEDED(m_pAMAIM[i]->get_Enable(&fEnable)) && fEnable)
+ iSel = i;
+ }
+
+ if(m_audinput.GetCount() > 0)
+ {
+ for(int i = 0; i < m_audinput.GetCount(); i++)
+ {
+ if(m_audinput.GetItemData(i) == iSel)
+ {
+ m_audinput.SetCurSel(i);
+ break;
+ }
+ }
+
+ m_audinput.EnableWindow(TRUE);
+ }
+ }
+
+ // stream config
+
+ if(m_pAMASC = pAMSC)
+ {
+ m_AudDisplayName = DisplayName;
+
+ AM_MEDIA_TYPE* pmt;
+ if(LoadMediaType(DisplayName, &pmt))
+ {
+ pAMSC->SetFormat(pmt);
+ DeleteMediaType(pmt);
+ }
+
+ SetupMediaTypes(pAMSC, m_afa, m_audtype, m_auddimension, m_mta);
+ }
+
+// if(m_audtype.GetCount() > 0)
+ {
+ m_audoutput.EnableWindow(TRUE);
+ m_audpreview.EnableWindow(TRUE);
+ }
+
+ UpdateMediaTypes();
+
+ UpdateUserDefinableControls();
+
+ UpdateOutputControls();
+}
+
+bool CPlayerCaptureDialog::IsTunerActive()
+{
+ int iSel = m_vidinput.GetCurSel();
+ if(iSel < 0) return(false);
+ iSel = m_vidinput.GetItemData(iSel);
+ if(iSel < 0) return(false);
+
+ long PinIndexRelated, PhysicalType;
+ return(m_pAMXB
+ && SUCCEEDED(m_pAMXB->get_CrossbarPinInfo(TRUE, iSel, &PinIndexRelated, &PhysicalType))
+ && PhysicalType == PhysConn_Video_Tuner);
+}
+
+bool CPlayerCaptureDialog::SetVideoInput(int input)
+{
+ if(!m_pAMXB || input < 0) return false;
+
+ for(int i = 0; i < m_vidinput.GetCount(); i++)
+ {
+ if(m_vidinput.GetItemData(i) == input)
+ {
+ m_vidinput.SetCurSel(i);
+ OnVideoInput();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool CPlayerCaptureDialog::SetVideoChannel(int channel)
+{
+ if(!m_pAMTuner || channel < 0) return false;
+
+ return SUCCEEDED(m_pAMTuner->put_Channel(channel, AMTUNER_SUBCHAN_DEFAULT, AMTUNER_SUBCHAN_DEFAULT));
+}
+
+bool CPlayerCaptureDialog::SetAudioInput(int input)
+{
+ if(input < 0) return false;
+
+ for(int i = 0; i < m_audinput.GetCount(); i++)
+ {
+ if(m_audinput.GetItemData(i) == input)
+ {
+ m_audinput.SetCurSel(i);
+ OnAudioInput();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int CPlayerCaptureDialog::GetVideoInput()
+{
+ int i = m_vidinput.GetCurSel();
+ if(i < 0) return -1;
+ return m_vidinput.GetItemData(i);
+}
+
+int CPlayerCaptureDialog::GetVideoChannel()
+{
+ long lChannel, lVivSub, lAudSub;
+ return m_pAMTuner && SUCCEEDED(m_pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub)) ? lChannel : -1;
+}
+
+int CPlayerCaptureDialog::GetAudioInput()
+{
+ int i = m_audinput.GetCurSel();
+ if(i < 0) return -1;
+ return m_audinput.GetItemData(i);
+}
+
+BEGIN_MESSAGE_MAP(CPlayerCaptureDialog, CResizableDialog)
+ ON_WM_DESTROY()
+ ON_CBN_SELCHANGE(IDC_COMBO4, OnVideoInput)
+ ON_CBN_SELCHANGE(IDC_COMBO1, OnVideoType)
+ ON_CBN_SELCHANGE(IDC_COMBO5, OnVideoDimension)
+ ON_BN_CLICKED(IDC_BUTTON1, OnOverrideVideoDimension)
+ ON_CBN_SELCHANGE(IDC_COMBO3, OnAudioInput)
+ ON_CBN_SELCHANGE(IDC_COMBO2, OnAudioType)
+ ON_CBN_SELCHANGE(IDC_COMBO6, OnAudioDimension)
+ ON_BN_CLICKED(IDC_CHECK1, OnRecordVideo)
+ ON_CBN_SELCHANGE(IDC_COMBO7, OnVideoCodec)
+ ON_CBN_SELCHANGE(IDC_COMBO9, OnVideoCodecType)
+ ON_CBN_SELCHANGE(IDC_COMBO10, OnVideoCodecDimension)
+ ON_BN_CLICKED(IDC_CHECK3, OnRecordAudio)
+ ON_CBN_SELCHANGE(IDC_COMBO8, OnAudioCodec)
+ ON_CBN_SELCHANGE(IDC_COMBO12, OnAudioCodecType)
+ ON_CBN_SELCHANGE(IDC_COMBO11, OnAudioCodecDimension)
+ ON_BN_CLICKED(IDC_BUTTON3, OnOpenFile)
+ ON_BN_CLICKED(IDC_BUTTON2, OnRecord)
+ ON_EN_CHANGE(IDC_EDIT5, OnEnChangeEdit9)
+ ON_EN_CHANGE(IDC_EDIT6, OnEnChangeEdit12)
+ ON_WM_TIMER()
+ ON_BN_CLICKED(IDC_CHECK2, OnBnClickedVidAudPreview)
+ ON_BN_CLICKED(IDC_CHECK4, OnBnClickedVidAudPreview)
+ ON_BN_CLICKED(IDC_CHECK5, OnBnClickedCheck7)
+ ON_CBN_SELCHANGE(IDC_COMBO14, OnCbnSelchangeCombo14)
+END_MESSAGE_MAP()
+
+
+// CPlayerCaptureDialog message handlers
+
+BOOL CPlayerCaptureDialog::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ InitCodecList(m_pVidEncArray, m_vidcodec, CLSID_VideoCompressorCategory);
+ UpdateVideoCodec();
+
+ InitCodecList(m_pAudEncArray, m_audcodec, CLSID_AudioCompressorCategory);
+ UpdateAudioCodec();
+
+ m_fEnableOgm = IsCLSIDRegistered(_T("{8cae96b7-85b1-4605-b23c-17ff5262b296}"));
+
+ m_nVidBuffers = AfxGetApp()->GetProfileInt(_T("Capture"), _T("VidBuffers"), 50);
+ m_nAudBuffers = AfxGetApp()->GetProfileInt(_T("Capture"), _T("AudBuffers"), 50);
+ m_fVidOutput = !!AfxGetApp()->GetProfileInt(_T("Capture"), _T("VidOutput"), TRUE);
+ m_fAudOutput = !!AfxGetApp()->GetProfileInt(_T("Capture"), _T("AudOutput"), TRUE);
+ m_fVidPreview = AfxGetApp()->GetProfileInt(_T("Capture"), _T("VidPreview"), TRUE);
+ m_fAudPreview = AfxGetApp()->GetProfileInt(_T("Capture"), _T("AudPreview"), TRUE);
+ m_muxtype = AfxGetApp()->GetProfileInt(_T("Capture"), _T("FileFormat"), 0);
+ m_file = AfxGetApp()->GetProfileString(_T("Capture"), _T("FileName"), _T(""));
+ m_fSepAudio = AfxGetApp()->GetProfileInt(_T("Capture"), _T("SepAudio"), TRUE);
+
+ m_muxctrl.AddString(_T("AVI"));
+ m_muxctrl.AddString(_T("Ogg Media"));
+ m_muxctrl.AddString(_T("Matroska"));
+ m_muxctrl.AddString(_T("DirectShow Media"));
+
+// UpdateMuxer();
+
+ UpdateData(FALSE);
+
+ OnCbnSelchangeCombo14();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CPlayerCaptureDialog::OnDestroy()
+{
+ UpdateData();
+
+ AfxGetApp()->WriteProfileInt(_T("Capture"), _T("VidOutput"), m_fVidOutput);
+ AfxGetApp()->WriteProfileInt(_T("Capture"), _T("AudOutput"), m_fAudOutput);
+ AfxGetApp()->WriteProfileInt(_T("Capture"), _T("VidPreview"), m_fVidPreview);
+ AfxGetApp()->WriteProfileInt(_T("Capture"), _T("AudPreview"), m_fAudPreview);
+ AfxGetApp()->WriteProfileInt(_T("Capture"), _T("FileFormat"), m_muxtype);
+ AfxGetApp()->WriteProfileString(_T("Capture"), _T("FileName"), m_file);
+ AfxGetApp()->WriteProfileInt(_T("Capture"), _T("SepAudio"), m_fSepAudio);
+
+ __super::OnDestroy();
+}
+
+void CPlayerCaptureDialog::OnVideoInput()
+{
+ int iSel = m_vidinput.GetCurSel();
+ if(iSel < 0) return;
+ iSel = m_vidinput.GetItemData(iSel);
+ if(iSel < 0) return;
+
+ if(m_pAMXB)
+ {
+ long PinIndexRelated, PhysicalType;
+ if(FAILED(m_pAMXB->get_CrossbarPinInfo(TRUE, iSel, &PinIndexRelated, &PhysicalType)))
+ return;
+
+ long OutputPinCount, InputPinCount;
+ if(FAILED(m_pAMXB->get_PinCounts(&OutputPinCount, &InputPinCount)))
+ return;
+
+ for(int i = 0; i < OutputPinCount; i++)
+ {
+ if(S_OK == m_pAMXB->CanRoute(i, iSel))
+ {
+ m_pAMXB->Route(i, iSel);
+ break;
+ }
+ }
+
+ if(PinIndexRelated >= 0)
+ {
+ for(int i = 0; i < OutputPinCount; i++)
+ {
+ if(S_OK == m_pAMXB->CanRoute(i, PinIndexRelated))
+ {
+ m_pAMXB->Route(i, PinIndexRelated);
+ break;
+ }
+ }
+ }
+ }
+ else if(m_pAMVfwCD)
+ {
+ if(S_OK == m_pAMVfwCD->HasDialog(iSel))
+ {
+ HRESULT hr = m_pAMVfwCD->ShowDialog(iSel, m_hWnd);
+
+ if(VFW_E_NOT_STOPPED == hr)
+ {
+ ((CMainFrame*)AfxGetMainWnd())->SendMessage(WM_COMMAND, ID_PLAY_STOP);
+ hr = m_pAMVfwCD->ShowDialog(iSel, m_hWnd);
+ ((CMainFrame*)AfxGetMainWnd())->SendMessage(WM_COMMAND, ID_PLAY_PLAY);
+ }
+
+ if(VFW_E_CANNOT_CONNECT == hr)
+ UpdateGraph();
+ }
+ }
+}
+
+void CPlayerCaptureDialog::OnVideoType()
+{
+ if(SetupDimension(m_vfa, m_vidtype, m_viddimension))
+ OnVideoDimension();
+}
+
+void CPlayerCaptureDialog::OnVideoDimension()
+{
+ int iSel = m_viddimension.GetCurSel();
+ if(iSel < 0) return;
+
+ CVidFormatElem* pvfe = (CVidFormatElem*)m_viddimension.GetItemData(iSel);
+ if(!pvfe) return;
+
+ BITMAPINFOHEADER* bih = (pvfe->mt.formattype == FORMAT_VideoInfo)
+ ? &((VIDEOINFOHEADER*)pvfe->mt.pbFormat)->bmiHeader
+ : (pvfe->mt.formattype == FORMAT_VideoInfo2)
+ ? &((VIDEOINFOHEADER2*)pvfe->mt.pbFormat)->bmiHeader
+ : NULL;
+
+ m_vidhor.SetRange(0, 32767);
+ m_vidver.SetRange(0, 32767);
+ m_vidhor.SetPos(bih->biWidth);
+ m_vidver.SetPos(abs(bih->biHeight));
+ CString fps;
+ fps.Format(_T("%.4f"), (float)(10000000.0 / ((VIDEOINFOHEADER*)pvfe->mt.pbFormat)->AvgTimePerFrame));
+ m_vidfpsedit.SetWindowText(fps);
+
+ UpdateGraph();
+}
+
+void CPlayerCaptureDialog::OnOverrideVideoDimension()
+{
+ UpdateGraph();
+}
+
+void CPlayerCaptureDialog::OnAudioInput()
+{
+ int iSel = m_audinput.GetCurSel();
+
+ for(int i = 0; i < (int)m_pAMAIM.GetCount(); i++)
+ {
+ m_pAMAIM[m_audinput.GetItemData(i)]->put_Enable(i == iSel ? TRUE : FALSE);
+ }
+}
+
+void CPlayerCaptureDialog::OnAudioType()
+{
+ if(SetupDimension(m_afa, m_audtype, m_auddimension))
+ OnAudioDimension();
+}
+
+void CPlayerCaptureDialog::OnAudioDimension()
+{
+ UpdateGraph();
+}
+
+void CPlayerCaptureDialog::OnRecordVideo()
+{
+ UpdateOutputControls();
+}
+
+void CPlayerCaptureDialog::OnVideoCodec()
+{
+ ShowPPage(m_pVidEncArray, m_vidcodec, m_hWnd);
+ UpdateVideoCodec();
+}
+
+void CPlayerCaptureDialog::OnVideoCodecType()
+{
+ if(SetupDimension(m_vcfa, m_vidcodectype, m_vidcodecdimension))
+ OnVideoCodecDimension();
+}
+
+void CPlayerCaptureDialog::OnVideoCodecDimension()
+{
+ int i = m_vidcodecdimension.GetCurSel();
+ if(i >= 0)
+ {
+ m_mtcv = ((CVidFormatElem*)m_vidcodecdimension.GetItemData(i))->mt;
+
+ // we have to recreate the encoder, otherwise it will accept the new media type for only the first time
+ m_pVidEnc = NULL;
+ m_pVidEncMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&m_pVidEnc);
+ }
+}
+
+void CPlayerCaptureDialog::OnRecordAudio()
+{
+ UpdateOutputControls();
+}
+
+void CPlayerCaptureDialog::OnAudioCodec()
+{
+ ShowPPage(m_pAudEncArray, m_audcodec, m_hWnd);
+ UpdateAudioCodec();
+}
+
+void CPlayerCaptureDialog::OnAudioCodecType()
+{
+ if(SetupDimension(m_acfa, m_audcodectype, m_audcodecdimension))
+ OnAudioCodecDimension();
+}
+
+void CPlayerCaptureDialog::OnAudioCodecDimension()
+{
+ int i = m_audcodecdimension.GetCurSel();
+ if(i >= 0)
+ {
+ m_mtca = ((CAudFormatElem*)m_audcodecdimension.GetItemData(i))->mt;
+
+ // we have to recreate the encoder, otherwise it will accept the new media type for only the first time
+ m_pAudEnc = NULL;
+ m_pAudEncMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&m_pAudEnc);
+/*
+ SaveMediaType(
+ CString(m_pAudEncArray[m_audcodec.GetItemData(m_audcodec.GetCurSel())].DisplayName.m_str),
+ &m_mtca);
+*/ }
+}
+
+void CPlayerCaptureDialog::OnOpenFile()
+{
+ CFileDialog fd(FALSE, NULL, NULL,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
+ _T("Media files (*.avi,*.ogm,*.mkv,*.dsm)|*.avi;*.ogm;*.mkv;*.dsm|"), this, 0);
+
+ if(fd.DoModal() == IDOK)
+ {
+ CString str = fd.GetPathName();
+
+ CString ext = str.Mid(str.ReverseFind('.')+1).MakeLower();
+ if(ext == _T("avi")) m_muxtype = 0;
+ else if(ext == _T("ogm")) m_muxtype = 1;
+ else if(ext == _T("mkv")) m_muxtype = 2;
+ else if(ext == _T("dsm")) m_muxtype = 3;
+ else
+ {
+ if(m_muxtype == 0) str += _T(".avi");
+ else if(m_muxtype == 1) str += _T(".ogm");
+ else if(m_muxtype == 2) str += _T(".mkv");
+ else if(m_muxtype == 3) str += _T(".dsm");
+ }
+
+ m_file = str;
+
+ UpdateData(FALSE);
+ }
+
+ UpdateOutputControls();
+}
+
+void CPlayerCaptureDialog::OnRecord()
+{
+ UpdateData();
+
+ CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
+ if(!pFrame) return;
+
+ if(!pFrame->m_fCapturing)
+ {
+ UpdateMuxer();
+
+ CComQIPtr<IFileSinkFilter2> pFSF = m_pMux;
+ if(pFSF)
+ {
+ m_pDst = m_pMux;
+ }
+ else
+ {
+ m_pDst = NULL;
+ m_pDst.CoCreateInstance(CLSID_FileWriter);
+ pFSF = m_pDst;
+ }
+
+ if(!pFSF
+ || FAILED(pFSF->SetFileName(CStringW(m_file), NULL))
+ || FAILED(pFSF->SetMode(AM_FILE_OVERWRITE)))
+ {
+ AfxMessageBox(_T("Error initializing the output file"));
+ return;
+ }
+
+ CString audfn = m_file.Left(m_file.ReverseFind('.')+1);
+ if(m_fSepAudio && m_fAudOutput && m_pAudMux && !audfn.IsEmpty())
+ {
+ audfn += _T("wav");
+
+ CComQIPtr<IFileSinkFilter2> pFSF = m_pAudMux;
+ if(pFSF)
+ {
+ m_pAudDst = m_pAudMux;
+ }
+ else
+ {
+ m_pAudDst = NULL;
+ m_pAudDst.CoCreateInstance(CLSID_FileWriter);
+ pFSF = m_pAudDst;
+ }
+
+ if(!pFSF
+ || FAILED(pFSF->SetFileName(CStringW(audfn), NULL))
+ || FAILED(pFSF->SetMode(AM_FILE_OVERWRITE)))
+ {
+ AfxMessageBox(_T("Error initializing the audio output file"));
+ return;
+ }
+ }
+
+ m_pVidBuffer = m_fVidOutput && m_nVidBuffers > 0 && m_muxtype != 2 && m_muxtype != 3 ? new CBufferFilter(NULL, NULL) : NULL;
+ if(CComQIPtr<IBufferFilter> pVB = m_pVidBuffer)
+ {pVB->SetBuffers(m_nVidBuffers); pVB->SetPriority(THREAD_PRIORITY_NORMAL);}
+
+ m_pAudBuffer = m_fAudOutput && m_nAudBuffers > 0 && m_muxtype != 2 && m_muxtype != 3 ? new CBufferFilter(NULL, NULL) : NULL;
+ if(CComQIPtr<IBufferFilter> pAB = m_pAudBuffer)
+ {pAB->SetBuffers(m_nAudBuffers); pAB->SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);}
+
+ EnableControls(this, false);
+
+ pFrame->StartCapture();
+
+ SetTimer(1, 100, NULL);
+ }
+ else
+ {
+ KillTimer(1);
+
+ pFrame->StopCapture();
+/*
+ {
+ if(FILE* f = _tfopen(m_file, _T("rb+")))
+ {
+ fseek(f, 0x20, SEEK_SET);
+ unsigned short mspf = (unsigned short)(((VIDEOINFOHEADER*)m_mtv.pbFormat)->AvgTimePerFrame / 10);
+ fwrite(&mspf, 1, 2, f);
+ fclose(f);
+ }
+ }
+*/
+ EnableControls(this, true);
+
+ m_pVidBuffer = NULL;
+ m_pAudBuffer = NULL;
+ }
+}
+
+void CPlayerCaptureDialog::OnEnChangeEdit9()
+{
+ UpdateData();
+ AfxGetApp()->WriteProfileInt(_T("Capture"), _T("VidBuffers"), max(m_nVidBuffers, 0));
+}
+
+void CPlayerCaptureDialog::OnEnChangeEdit12()
+{
+ UpdateData();
+ AfxGetApp()->WriteProfileInt(_T("Capture"), _T("AudBuffers"), max(m_nAudBuffers, 0));
+}
+
+void CPlayerCaptureDialog::OnTimer(UINT nIDEvent)
+{
+ if(nIDEvent == 1)
+ {
+ if(((CMainFrame*)AfxGetMainWnd())->m_fCapturing)
+ {
+ ULARGE_INTEGER FreeBytesAvailable, TotalNumberOfBytes, TotalNumberOfFreeBytes;
+ if(GetDiskFreeSpaceEx(m_file.Left(m_file.ReverseFind('\\')+1), &FreeBytesAvailable, &TotalNumberOfBytes, &TotalNumberOfFreeBytes)
+ && FreeBytesAvailable.QuadPart < 1024i64*1024*10)
+ {
+ OnRecord();
+ }
+ }
+ }
+
+ __super::OnTimer(nIDEvent);
+}
+
+void CPlayerCaptureDialog::OnBnClickedVidAudPreview()
+{
+ UpdateData();
+ UpdateGraph();
+}
+
+void CPlayerCaptureDialog::OnBnClickedCheck7()
+{
+// UpdateMuxer();
+}
+
+void CPlayerCaptureDialog::OnCbnSelchangeCombo14()
+{
+ UpdateData();
+
+ CString ext = m_file.Mid(m_file.ReverseFind('.')+1).MakeLower();
+
+ if(m_muxtype == 0 && ext != _T("avi"))
+ m_file = m_file.Left(m_file.GetLength()-4) + _T(".avi");
+ else if(m_muxtype == 1 && ext != _T("ogm"))
+ m_file = m_file.Left(m_file.GetLength()-4) + _T(".ogm");
+ else if(m_muxtype == 2 && ext != _T("mkv"))
+ m_file = m_file.Left(m_file.GetLength()-4) + _T(".mkv");
+ else if(m_muxtype == 3 && ext != _T("dsm"))
+ m_file = m_file.Left(m_file.GetLength()-4) + _T(".dsm");
+
+ UpdateData(FALSE);
+
+ GetDlgItem(IDC_EDIT5)->EnableWindow(m_muxtype != 2 && m_muxtype != 3);
+ GetDlgItem(IDC_EDIT6)->EnableWindow(m_muxtype != 2 && m_muxtype != 3);
+
+ m_recordbtn.EnableWindow(m_muxtype != 1 || m_fEnableOgm);
+}
diff --git a/src/apps/mplayerc/PlayerCaptureDialog.h b/src/apps/mplayerc/PlayerCaptureDialog.h
new file mode 100644
index 000000000..ddde4d1fb
--- /dev/null
+++ b/src/apps/mplayerc/PlayerCaptureDialog.h
@@ -0,0 +1,452 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "afxwin.h"
+#include "afxcmn.h"
+#include "..\..\filters\transform\bufferfilter\bufferfilter.h"
+#include "FloatEdit.h"
+
+//
+
+template<class T>
+class CFormatElem
+{
+public:
+ CMediaType mt;
+ T caps;
+};
+
+template<class T>
+class CFormat : public CAutoPtrArray<CFormatElem<T> >
+{
+public:
+ CString name;
+ CFormat(CString name = _T("")) {this->name = name;}
+ virtual ~CFormat() {}
+};
+
+template<class T>
+class CFormatArray : public CAutoPtrArray<CFormat<T> >
+{
+public:
+ virtual ~CFormatArray() {}
+
+ CFormat<T>* Find(CString name, bool fCreate = false)
+ {
+ for(int i = 0; i < (int)GetCount(); i++)
+ {
+ if(GetAt(i)->name == name)
+ return(GetAt(i));
+ }
+
+ if(fCreate)
+ {
+ CAutoPtr<CFormat<T> > pf(new CFormat<T>(name));
+ CFormat<T>* tmp = pf;
+ Add(pf);
+ return(tmp);
+ }
+
+ return(NULL);
+ }
+
+ bool FindFormat(AM_MEDIA_TYPE* pmt, CFormat<T>** ppf)
+ {
+ if(!pmt) return(false);
+
+ for(int i = 0; i < (int)GetCount(); i++)
+ {
+ CFormat<T>* pf = GetAt(i);
+ for(int j = 0; j < (int)pf->GetCount(); j++)
+ {
+ CFormatElem<T>* pfe = pf->GetAt(j);
+ if(!pmt || (pfe->mt.majortype == pmt->majortype && pfe->mt.subtype == pmt->subtype))
+ {
+ if(ppf) *ppf = pf;
+ return(true);
+ }
+ }
+ }
+
+ return(false);
+ }
+
+ bool FindFormat(AM_MEDIA_TYPE* pmt, T* pcaps, CFormat<T>** ppf, CFormatElem<T>** ppfe)
+ {
+ if(!pmt && !pcaps) return(false);
+
+ for(int i = 0; i < (int)GetCount(); i++)
+ {
+ CFormat<T>* pf = GetAt(i);
+ for(int j = 0; j < (int)pf->GetCount(); j++)
+ {
+ CFormatElem<T>* pfe = pf->GetAt(j);
+ if((!pmt || pfe->mt == *pmt) && (!pcaps || !memcmp(pcaps, &pfe->caps, sizeof(T))))
+ {
+ if(ppf) *ppf = pf;
+ if(ppfe) *ppfe = pfe;
+ return(true);
+ }
+ }
+ }
+
+ return(false);
+ }
+
+ bool AddFormat(AM_MEDIA_TYPE* pmt, T caps)
+ {
+ if(!pmt) return(false);
+
+ if(FindFormat(pmt, NULL, NULL, NULL)) {DeleteMediaType(pmt); return(false);}
+// if(pmt->formattype == FORMAT_VideoInfo2) {DeleteMediaType(pmt); return(false);} // TODO
+
+ CFormat<T>* pf = Find(MakeFormatName(pmt), true);
+ if(!pf) {DeleteMediaType(pmt); return(false);}
+
+ CAutoPtr<CFormatElem<T> > pfe(new CFormatElem<T>());
+ pfe->mt = *pmt;
+ pfe->caps = caps;
+ pf->Add(pfe);
+
+ return(true);
+ }
+
+ bool AddFormat(AM_MEDIA_TYPE* pmt, void* pcaps, int size)
+ {
+ if(!pcaps) return false;
+ ASSERT(size == sizeof(T));
+ return AddFormat(pmt, *(T*)pcaps);
+ }
+
+ virtual CString MakeFormatName(AM_MEDIA_TYPE* pmt) = 0;
+ virtual CString MakeDimensionName(CFormatElem<T>* pfe) = 0;
+};
+
+typedef CFormatElem<VIDEO_STREAM_CONFIG_CAPS> CVidFormatElem;
+typedef CFormat<VIDEO_STREAM_CONFIG_CAPS> CVidFormat;
+
+class CVidFormatArray : public CFormatArray<VIDEO_STREAM_CONFIG_CAPS>
+{
+public:
+ CString MakeFormatName(AM_MEDIA_TYPE* pmt)
+ {
+ CString str(_T("Default"));
+
+ if(!pmt) return(str);
+
+ BITMAPINFOHEADER* bih = (pmt->formattype == FORMAT_VideoInfo)
+ ? &((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader
+ : (pmt->formattype == FORMAT_VideoInfo2)
+ ? &((VIDEOINFOHEADER2*)pmt->pbFormat)->bmiHeader
+ : NULL;
+
+ if(!bih)
+ {
+ // it may have a fourcc in the mediasubtype, let's check that
+
+ WCHAR guid[100];
+ memset(guid, 0, 100*sizeof(WCHAR));
+ StringFromGUID2(pmt->subtype, guid, 100);
+
+ if(CStringW(guid).MakeUpper().Find(L"0000-0010-8000-00AA00389B71") >= 0)
+ {
+ str.Format(_T("%c%c%c%c"),
+ (TCHAR)((pmt->subtype.Data1>>0)&0xff), (TCHAR)((pmt->subtype.Data1>>8)&0xff),
+ (TCHAR)((pmt->subtype.Data1>>16)&0xff), (TCHAR)((pmt->subtype.Data1>>24)&0xff));
+ }
+
+ return(str);
+ }
+
+ switch(bih->biCompression)
+ {
+ case BI_RGB: str.Format(_T("RGB%d"), bih->biBitCount); break;
+ case BI_RLE8: str = _T("RLE8"); break;
+ case BI_RLE4: str = _T("RLE4"); break;
+ case BI_BITFIELDS: str.Format(_T("BITF%d"), bih->biBitCount); break;
+ case BI_JPEG: str = _T("JPEG"); break;
+ case BI_PNG: str = _T("PNG"); break;
+ default:
+ str.Format(_T("%c%c%c%c"),
+ (TCHAR)((bih->biCompression>>0)&0xff), (TCHAR)((bih->biCompression>>8)&0xff),
+ (TCHAR)((bih->biCompression>>16)&0xff), (TCHAR)((bih->biCompression>>24)&0xff));
+ break;
+ }
+
+ return(str);
+ }
+
+ CString MakeDimensionName(CVidFormatElem* pfe)
+ {
+ CString str(_T("Default"));
+
+ if(!pfe) return(str);
+
+ BITMAPINFOHEADER* bih = (pfe->mt.formattype == FORMAT_VideoInfo)
+ ? &((VIDEOINFOHEADER*)pfe->mt.pbFormat)->bmiHeader
+ : (pfe->mt.formattype == FORMAT_VideoInfo2)
+ ? &((VIDEOINFOHEADER2*)pfe->mt.pbFormat)->bmiHeader
+ : NULL;
+
+ if(bih == NULL) return(str);
+
+ str.Format(_T("%dx%d %.2f"), bih->biWidth, bih->biHeight, (float)10000000/((VIDEOINFOHEADER*)pfe->mt.pbFormat)->AvgTimePerFrame);
+
+ if(pfe->mt.formattype == FORMAT_VideoInfo2)
+ {
+ VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)pfe->mt.pbFormat;
+ CString str2;
+ str2.Format(_T(" i%02x %d:%d"), vih2->dwInterlaceFlags, vih2->dwPictAspectRatioX, vih2->dwPictAspectRatioY);
+ str += str2;
+ }
+
+ return(str);
+ }
+};
+
+typedef CFormatElem<AUDIO_STREAM_CONFIG_CAPS> CAudFormatElem;
+typedef CFormat<AUDIO_STREAM_CONFIG_CAPS> CAudFormat;
+
+class CAudFormatArray : public CFormatArray<AUDIO_STREAM_CONFIG_CAPS>
+{
+public:
+ CString MakeFormatName(AM_MEDIA_TYPE* pmt)
+ {
+ CString str(_T("Unknown"));
+
+ if(!pmt) return(str);
+
+ WAVEFORMATEX* wfe = (pmt->formattype == FORMAT_WaveFormatEx)
+ ? (WAVEFORMATEX*)pmt->pbFormat
+ : NULL;
+
+ if(!wfe)
+ {
+ WCHAR guid[100];
+ memset(guid, 0, 100*sizeof(WCHAR));
+ StringFromGUID2(pmt->subtype, guid, 100);
+
+ if(CStringW(guid).MakeUpper().Find(L"0000-0010-8000-00AA00389B71") >= 0)
+ {
+ str.Format(_T("0x%04x"), pmt->subtype.Data1);
+ }
+
+ return(str);
+ }
+
+ switch(wfe->wFormatTag)
+ {
+ case 1: str = _T("PCM "); break;
+ default: str.Format(_T("0x%03x "), wfe->wFormatTag); break;
+ }
+
+ return(str);
+ }
+
+ CString MakeDimensionName(CAudFormatElem* pfe)
+ {
+ CString str(_T("Unknown"));
+
+ if(!pfe) return(str);
+
+ WAVEFORMATEX* wfe = (pfe->mt.formattype == FORMAT_WaveFormatEx)
+ ? (WAVEFORMATEX*)pfe->mt.pbFormat
+ : NULL;
+
+ if(!wfe) return(str);
+
+ str.Empty();
+ CString str2;
+
+ str2.Format(_T("%6dKHz "), wfe->nSamplesPerSec); str += str2;
+
+ str2.Format(_T("%dbps "), wfe->wBitsPerSample); str += str2;
+
+ switch(wfe->nChannels)
+ {
+ case 1: str += _T("mono "); break;
+ case 2: str += _T("stereo "); break;
+ default: str2.Format(_T("%d channels "), wfe->nChannels); str += str2; break;
+ }
+
+ str2.Format(_T("%3dkbps "), wfe->nAvgBytesPerSec*8/1000); str += str2;
+
+ return(str);
+ }
+};
+
+//
+
+typedef struct
+{
+ CComPtr<IMoniker> pMoniker;
+ CComPtr<IBaseFilter> pBF;
+ CString FriendlyName;
+ CComBSTR DisplayName;
+} Codec;
+
+typedef CAtlArray<Codec> CCodecArray;
+
+// CPlayerCaptureDialog dialog
+
+class CPlayerCaptureDialog : public CResizableDialog //CDialog
+{
+ //DECLARE_DYNAMIC(CPlayerCaptureDialog)
+
+ // video input
+ CStringW m_VidDisplayName;
+ CComPtr<IAMStreamConfig> m_pAMVSC;
+ CComPtr<IAMCrossbar> m_pAMXB;
+ CComPtr<IAMTVTuner> m_pAMTuner;
+ CComPtr<IAMVfwCaptureDialogs> m_pAMVfwCD;
+ CVidFormatArray m_vfa;
+
+ // audio input
+ CStringW m_AudDisplayName;
+ CComPtr<IAMStreamConfig> m_pAMASC;
+ CInterfaceArray<IAMAudioInputMixer> m_pAMAIM;
+ CAudFormatArray m_afa;
+
+ // video codec
+ CCodecArray m_pVidEncArray;
+ CVidFormatArray m_vcfa;
+
+ // audio codec
+ CCodecArray m_pAudEncArray;
+ CAudFormatArray m_acfa;
+
+ void EmptyVideo();
+ void EmptyAudio();
+
+ void UpdateMediaTypes();
+ void UpdateUserDefinableControls();
+ void UpdateVideoCodec();
+ void UpdateAudioCodec();
+ void UpdateMuxer();
+ void UpdateOutputControls();
+
+ void UpdateGraph();
+
+ CMap<HWND, HWND&, BOOL, BOOL&> m_wndenabledmap;
+ void EnableControls(CWnd* pWnd, bool fEnable);
+
+ bool m_fEnableOgm;
+
+public:
+ CPlayerCaptureDialog(); // standard constructor
+ virtual ~CPlayerCaptureDialog();
+
+ BOOL Create(CWnd* pParent = NULL);
+
+// Dialog Data
+ enum { IDD = IDD_CAPTURE_DLG };
+
+ CComboBox m_vidinput;
+ CComboBox m_vidtype;
+ CComboBox m_viddimension;
+ CSpinButtonCtrl m_vidhor;
+ CSpinButtonCtrl m_vidver;
+ CEdit m_vidhoredit;
+ CEdit m_vidveredit;
+ CFloatEdit m_vidfpsedit;
+ float m_vidfps;
+ CButton m_vidsetres;
+ CComboBox m_audinput;
+ CComboBox m_audtype;
+ CComboBox m_auddimension;
+ CComboBox m_vidcodec;
+ CComboBox m_vidcodectype;
+ CComboBox m_vidcodecdimension;
+ BOOL m_fVidOutput;
+ CButton m_vidoutput;
+ int m_fVidPreview;
+ CButton m_vidpreview;
+ CComboBox m_audcodec;
+ CComboBox m_audcodectype;
+ CComboBox m_audcodecdimension;
+ BOOL m_fAudOutput;
+ CButton m_audoutput;
+ int m_fAudPreview;
+ CButton m_audpreview;
+ int m_nVidBuffers;
+ int m_nAudBuffers;
+ CString m_file;
+ CButton m_recordbtn;
+ BOOL m_fSepAudio;
+ int m_muxtype;
+ CComboBox m_muxctrl;
+
+ CMediaType m_mtv, m_mta, m_mtcv, m_mtca;
+ CComPtr<IBaseFilter> m_pVidEnc, m_pAudEnc, m_pMux, m_pDst, m_pAudMux, m_pAudDst;
+ CComPtr<IMoniker> m_pVidEncMoniker, m_pAudEncMoniker;
+ CComPtr<IBaseFilter> m_pVidBuffer, m_pAudBuffer;
+
+public:
+ void SetupVideoControls(CStringW DisplayName, CComPtr<IAMStreamConfig> pAMSC, CComPtr<IAMCrossbar> pAMXB, CComPtr<IAMTVTuner> pAMTuner);
+ void SetupVideoControls(CStringW DisplayName, CComPtr<IAMStreamConfig> pAMSC, CComPtr<IAMVfwCaptureDialogs> pAMVfwCD);
+ void SetupAudioControls(CStringW DisplayName, CComPtr<IAMStreamConfig> pAMSC, CInterfaceArray<IAMAudioInputMixer>& pAMAIM);
+
+ bool IsTunerActive();
+
+ bool SetVideoInput(int input);
+ bool SetVideoChannel(int channel);
+ bool SetAudioInput(int input);
+
+ int GetVideoInput();
+ int GetVideoChannel();
+ int GetAudioInput();
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ virtual BOOL OnInitDialog();
+ virtual void OnOK() {}
+ virtual void OnCancel() {}
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnDestroy();
+ afx_msg void OnVideoInput();
+ afx_msg void OnVideoType();
+ afx_msg void OnVideoDimension();
+ afx_msg void OnOverrideVideoDimension();
+ afx_msg void OnAudioInput();
+ afx_msg void OnAudioType();
+ afx_msg void OnAudioDimension();
+ afx_msg void OnRecordVideo();
+ afx_msg void OnVideoCodec();
+ afx_msg void OnVideoCodecType();
+ afx_msg void OnVideoCodecDimension();
+ afx_msg void OnRecordAudio();
+ afx_msg void OnAudioCodec();
+ afx_msg void OnAudioCodecType();
+ afx_msg void OnAudioCodecDimension();
+ afx_msg void OnOpenFile();
+ afx_msg void OnRecord();
+ afx_msg void OnEnChangeEdit9();
+ afx_msg void OnEnChangeEdit12();
+ afx_msg void OnTimer(UINT nIDEvent);
+ afx_msg void OnBnClickedVidAudPreview();
+ afx_msg void OnBnClickedCheck7();
+ afx_msg void OnCbnSelchangeCombo14();
+};
diff --git a/src/apps/mplayerc/PlayerInfoBar.cpp b/src/apps/mplayerc/PlayerInfoBar.cpp
new file mode 100644
index 000000000..e1e47ec96
--- /dev/null
+++ b/src/apps/mplayerc/PlayerInfoBar.cpp
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PlayerInfoBar.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PlayerInfoBar.h"
+#include "MainFrm.h"
+
+
+// CPlayerInfoBar
+
+IMPLEMENT_DYNAMIC(CPlayerInfoBar, CDialogBar)
+CPlayerInfoBar::CPlayerInfoBar(int nFirstColWidth) : m_nFirstColWidth(nFirstColWidth)
+{
+}
+
+CPlayerInfoBar::~CPlayerInfoBar()
+{
+}
+
+void CPlayerInfoBar::SetLine(CString label, CString info)
+{
+ if(info.IsEmpty())
+ {
+ RemoveLine(label);
+ return;
+ }
+
+ for(size_t idx = 0; idx < m_label.GetCount(); idx++)
+ {
+ CString tmp;
+ m_label[idx]->GetWindowText(tmp);
+ if(label == tmp)
+ {
+ m_info[idx]->GetWindowText(tmp);
+ if(info != tmp) m_info[idx]->SetWindowText(info);
+ return;
+ }
+ }
+
+ CAutoPtr<CStatusLabel> l(new CStatusLabel(true, false));
+ l->Create(label, WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|SS_OWNERDRAW, CRect(0,0,0,0), this);
+ m_label.Add(l);
+
+ CAutoPtr<CStatusLabel> i(new CStatusLabel(false, true));
+ i->Create(info, WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|SS_OWNERDRAW, CRect(0,0,0,0), this);
+ m_info.Add(i);
+
+ Relayout();
+}
+
+void CPlayerInfoBar::GetLine(CString label, CString& info)
+{
+ info.Empty();
+
+ for(size_t idx = 0; idx < m_label.GetCount(); idx++)
+ {
+ CString tmp;
+ m_label[idx]->GetWindowText(tmp);
+ if(label == tmp)
+ {
+ m_info[idx]->GetWindowText(tmp);
+ info = tmp;
+ return;
+ }
+ }
+}
+
+void CPlayerInfoBar::RemoveLine(CString label)
+{
+ for(size_t i = 0; i < m_label.GetCount(); i++)
+ {
+ CString tmp;
+ m_label[i]->GetWindowText(tmp);
+ if(label == tmp)
+ {
+ m_label.RemoveAt(i);
+ m_info.RemoveAt(i);
+ break;
+ }
+ }
+
+ Relayout();
+}
+
+void CPlayerInfoBar::RemoveAllLines()
+{
+ m_label.RemoveAll();
+ m_info.RemoveAll();
+
+ Relayout();
+}
+
+BOOL CPlayerInfoBar::Create(CWnd* pParentWnd)
+{
+ return CDialogBar::Create(pParentWnd, IDD_PLAYERINFOBAR, WS_CHILD|WS_VISIBLE|CBRS_ALIGN_BOTTOM, IDD_PLAYERINFOBAR);
+}
+
+BOOL CPlayerInfoBar::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if(!CDialogBar::PreCreateWindow(cs))
+ return FALSE;
+
+ m_dwStyle &= ~CBRS_BORDER_TOP;
+ m_dwStyle &= ~CBRS_BORDER_BOTTOM;
+
+ return TRUE;
+}
+
+CSize CPlayerInfoBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
+{
+ CRect r;
+ GetParent()->GetClientRect(&r);
+ r.bottom = r.top + m_label.GetCount() * 17 + (m_label.GetCount() ? 4 : 0);
+ return r.Size();
+}
+
+void CPlayerInfoBar::Relayout()
+{
+ CRect r;
+ GetParent()->GetClientRect(&r);
+
+ int w = m_nFirstColWidth, h = 17, y = 2;
+
+ for(size_t i = 0; i < m_label.GetCount(); i++)
+ {
+ CDC* pDC = m_label[i]->GetDC();
+ CString str;
+ m_label[i]->GetWindowText(str);
+ w = max(w, pDC->GetTextExtent(str).cx);
+ m_label[i]->ReleaseDC(pDC);
+ }
+
+ for(size_t i = 0; i < m_label.GetCount(); i++, y += h)
+ {
+ m_label[i]->MoveWindow(1, y, w - 10, h);
+ m_info[i]->MoveWindow(w + 10, y, r.Width()-(w+10)-1, h);
+ }
+}
+
+BEGIN_MESSAGE_MAP(CPlayerInfoBar, CDialogBar)
+ ON_WM_ERASEBKGND()
+ ON_WM_SIZE()
+ ON_WM_LBUTTONDOWN()
+END_MESSAGE_MAP()
+
+
+
+// CPlayerInfoBar message handlers
+
+BOOL CPlayerInfoBar::OnEraseBkgnd(CDC* pDC)
+{
+ for(CWnd* pChild = GetWindow(GW_CHILD); pChild; pChild = pChild->GetNextWindow())
+ {
+ CRect r;
+ pChild->GetClientRect(&r);
+ pChild->MapWindowPoints(this, &r);
+ pDC->ExcludeClipRect(&r);
+ }
+
+ CRect r;
+ GetClientRect(&r);
+
+ CMainFrame* pFrame = ((CMainFrame*)GetParentFrame());
+
+ if(pFrame->m_pLastBar != this || pFrame->m_fFullScreen)
+ r.InflateRect(0, 0, 0, 1);
+
+ if(pFrame->m_fFullScreen)
+ r.InflateRect(1, 0, 1, 0);
+
+ pDC->Draw3dRect(&r, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
+
+ r.DeflateRect(1, 1);
+
+ pDC->FillSolidRect(&r, 0);
+
+ return TRUE;
+}
+
+void CPlayerInfoBar::OnSize(UINT nType, int cx, int cy)
+{
+ CDialogBar::OnSize(nType, cx, cy);
+
+ Relayout();
+
+ Invalidate();
+}
+
+void CPlayerInfoBar::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ CMainFrame* pFrame = ((CMainFrame*)GetParentFrame());
+ if(!pFrame->m_fFullScreen)
+ {
+ MapWindowPoints(pFrame, &point, 1);
+ pFrame->PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
+ }
+}
diff --git a/src/apps/mplayerc/PlayerInfoBar.h b/src/apps/mplayerc/PlayerInfoBar.h
new file mode 100644
index 000000000..2ead2e831
--- /dev/null
+++ b/src/apps/mplayerc/PlayerInfoBar.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <atlcoll.h>
+#include "StatusLabel.h"
+
+// CPlayerInfoBar
+
+class CPlayerInfoBar : public CDialogBar
+{
+ DECLARE_DYNAMIC(CPlayerInfoBar)
+
+private:
+ CAutoPtrArray<CStatusLabel> m_label;
+ CAutoPtrArray<CStatusLabel> m_info;
+
+ int m_nFirstColWidth;
+
+ void Relayout();
+
+public:
+ CPlayerInfoBar(int nFirstColWidth = 100);
+ virtual ~CPlayerInfoBar();
+
+ BOOL Create(CWnd* pParentWnd);
+
+ void SetLine(CString label, CString info);
+ void GetLine(CString label, CString& info);
+ void RemoveLine(CString label);
+ void RemoveAllLines();
+
+protected:
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ virtual CSize CalcFixedLayout(BOOL bStretch, BOOL bHorz);
+
+public:
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+};
diff --git a/src/apps/mplayerc/PlayerListCtrl.cpp b/src/apps/mplayerc/PlayerListCtrl.cpp
new file mode 100644
index 000000000..a2b7cd287
--- /dev/null
+++ b/src/apps/mplayerc/PlayerListCtrl.cpp
@@ -0,0 +1,871 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PlayerListCtrl.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PlayerListCtrl.h"
+#include ".\playerlistctrl.h"
+
+// CInPlaceEdit
+
+CInPlaceEdit::CInPlaceEdit(int iItem, int iSubItem, CString sInitText)
+ : m_sInitText( sInitText )
+{
+ m_iItem = iItem;
+ m_iSubItem = iSubItem;
+ m_bESC = FALSE;
+}
+
+CInPlaceEdit::~CInPlaceEdit()
+{
+}
+
+BEGIN_MESSAGE_MAP(CInPlaceEdit, CEdit)
+ //{{AFX_MSG_MAP(CInPlaceEdit)
+ ON_WM_KILLFOCUS()
+ ON_WM_NCDESTROY()
+ ON_WM_CHAR()
+ ON_WM_CREATE()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CInPlaceEdit message handlers
+
+BOOL CInPlaceEdit::PreTranslateMessage(MSG* pMsg)
+{
+ if(pMsg->message == WM_KEYDOWN)
+ {
+ if(pMsg->wParam == VK_RETURN
+ || pMsg->wParam == VK_DELETE
+ || pMsg->wParam == VK_ESCAPE
+ || GetKeyState(VK_CONTROL))
+ {
+ ::TranslateMessage(pMsg);
+ ::DispatchMessage(pMsg);
+ return TRUE; // DO NOT process further
+ }
+ }
+
+ return CEdit::PreTranslateMessage(pMsg);
+}
+
+void CInPlaceEdit::OnKillFocus(CWnd* pNewWnd)
+{
+ CEdit::OnKillFocus(pNewWnd);
+
+ CString str;
+ GetWindowText(str);
+
+ LV_DISPINFO dispinfo;
+ dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
+ dispinfo.hdr.idFrom = GetDlgCtrlID();
+ dispinfo.hdr.code = LVN_ENDLABELEDIT;
+ dispinfo.item.mask = LVIF_TEXT;
+ dispinfo.item.iItem = m_iItem;
+ dispinfo.item.iSubItem = m_iSubItem;
+ dispinfo.item.pszText = m_bESC ? NULL : LPTSTR((LPCTSTR)str);
+ dispinfo.item.cchTextMax = str.GetLength();
+ GetParent()->GetParent()->SendMessage(WM_NOTIFY, GetParent()->GetDlgCtrlID(), (LPARAM)&dispinfo);
+
+ DestroyWindow();
+}
+
+void CInPlaceEdit::OnNcDestroy()
+{
+ CEdit::OnNcDestroy();
+
+ delete this;
+}
+
+
+void CInPlaceEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ if(nChar == VK_ESCAPE || nChar == VK_RETURN)
+ {
+ if(nChar == VK_ESCAPE) m_bESC = TRUE;
+ GetParent()->SetFocus();
+ return;
+ }
+
+ CEdit::OnChar(nChar, nRepCnt, nFlags);
+}
+
+int CInPlaceEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if(CEdit::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ // Set the proper font
+ CFont* font = GetParent()->GetFont();
+ SetFont(font);
+
+ SetWindowText(m_sInitText);
+ SetFocus();
+ SetSel(0, -1);
+ return 0;
+}
+
+// CInPlaceComboBox
+
+CInPlaceComboBox::CInPlaceComboBox(int iItem, int iSubItem, CAtlList<CString>& lstItems, int nSel)
+{
+ m_iItem = iItem;
+ m_iSubItem = iSubItem;
+
+ m_lstItems.AddTailList(&lstItems);
+ m_nSel = nSel;
+ m_bESC = FALSE;
+}
+
+CInPlaceComboBox::~CInPlaceComboBox()
+{
+}
+
+BEGIN_MESSAGE_MAP(CInPlaceComboBox, CComboBox)
+ //{{AFX_MSG_MAP(CInPlaceComboBox)
+ ON_WM_CREATE()
+ ON_WM_KILLFOCUS()
+ ON_WM_CHAR()
+ ON_WM_NCDESTROY()
+ ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseup)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CInPlaceComboBox message handlers
+
+int CInPlaceComboBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CComboBox::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ // Set the proper font
+ CFont* font = GetParent()->GetFont();
+ SetFont(font);
+
+ for(POSITION pos = m_lstItems.GetHeadPosition(); pos != NULL;)
+ AddString((LPCTSTR)(m_lstItems.GetNext(pos)));
+
+ SetFocus();
+ SetCurSel(m_nSel);
+ return 0;
+}
+
+BOOL CInPlaceComboBox::PreTranslateMessage(MSG* pMsg)
+{
+ if(pMsg->message == WM_KEYDOWN)
+ {
+ if(pMsg->wParam == VK_RETURN
+ || pMsg->wParam == VK_ESCAPE)
+ {
+ ::TranslateMessage(pMsg);
+ ::DispatchMessage(pMsg);
+ return TRUE; // DO NOT process further
+ }
+ }
+
+ return CComboBox::PreTranslateMessage(pMsg);
+}
+
+void CInPlaceComboBox::OnKillFocus(CWnd* pNewWnd)
+{
+ CComboBox::OnKillFocus(pNewWnd);
+
+ CString str;
+ GetWindowText(str);
+
+ LV_DISPINFO dispinfo;
+ dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
+ dispinfo.hdr.idFrom = GetDlgCtrlID();
+ dispinfo.hdr.code = LVN_ENDLABELEDIT;
+ dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
+ dispinfo.item.iItem = m_iItem;
+ dispinfo.item.iSubItem = m_iSubItem;
+ dispinfo.item.pszText = m_bESC ? NULL : LPTSTR((LPCTSTR)str);
+ dispinfo.item.cchTextMax = str.GetLength();
+ dispinfo.item.lParam = GetCurSel();
+ GetParent()->GetParent()->SendMessage(WM_NOTIFY, GetParent()->GetDlgCtrlID(), (LPARAM)&dispinfo);
+
+ PostMessage(WM_CLOSE);
+}
+
+void CInPlaceComboBox::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ if(nChar == VK_ESCAPE || nChar == VK_RETURN)
+ {
+ if(nChar == VK_ESCAPE) m_bESC = TRUE;
+ GetParent()->SetFocus();
+ return;
+ }
+
+ CComboBox::OnChar(nChar, nRepCnt, nFlags);
+}
+
+void CInPlaceComboBox::OnNcDestroy()
+{
+ CComboBox::OnNcDestroy();
+
+ delete this;
+}
+
+void CInPlaceComboBox::OnCloseup()
+{
+ GetParent()->SetFocus();
+}
+
+// CInPlaceListBox
+
+CInPlaceListBox::CInPlaceListBox(int iItem, int iSubItem, CAtlList<CString>& lstItems, int nSel)
+{
+ m_iItem = iItem;
+ m_iSubItem = iSubItem;
+
+ m_lstItems.AddTailList(&lstItems);
+ m_nSel = nSel;
+ m_bESC = FALSE;
+}
+
+CInPlaceListBox::~CInPlaceListBox()
+{
+}
+
+BEGIN_MESSAGE_MAP(CInPlaceListBox, CListBox)
+ //{{AFX_MSG_MAP(CInPlaceListBox)
+ ON_WM_CREATE()
+ ON_WM_KILLFOCUS()
+ ON_WM_CHAR()
+ ON_WM_NCDESTROY()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CInPlaceListBox message handlers
+
+int CInPlaceListBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if(CListBox::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ // Set the proper font
+ CFont* font = GetParent()->GetFont();
+ SetFont(font);
+
+ for(POSITION pos = m_lstItems.GetHeadPosition(); pos != NULL;)
+ {
+ AddString( (LPCTSTR) (m_lstItems.GetNext( pos )) );
+ }
+ SetCurSel( m_nSel );
+ SetFocus();
+ return 0;
+}
+
+BOOL CInPlaceListBox::PreTranslateMessage(MSG* pMsg)
+{
+ if(pMsg->message == WM_KEYDOWN)
+ {
+ if(pMsg->wParam == VK_RETURN
+ || pMsg->wParam == VK_ESCAPE)
+ {
+ ::TranslateMessage(pMsg);
+ ::DispatchMessage(pMsg);
+ return TRUE; // DO NOT process further
+ }
+ }
+
+ return CListBox::PreTranslateMessage(pMsg);
+}
+
+void CInPlaceListBox::OnKillFocus(CWnd* pNewWnd)
+{
+ CListBox::OnKillFocus(pNewWnd);
+
+ CString str;
+ GetWindowText(str);
+
+ LV_DISPINFO dispinfo;
+ dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
+ dispinfo.hdr.idFrom = GetDlgCtrlID();
+ dispinfo.hdr.code = LVN_ENDLABELEDIT;
+ dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
+ dispinfo.item.iItem = m_iItem;
+ dispinfo.item.iSubItem = m_iSubItem;
+ dispinfo.item.pszText = m_bESC ? NULL : LPTSTR((LPCTSTR)str);
+ dispinfo.item.cchTextMax = str.GetLength();
+ dispinfo.item.lParam = GetCurSel();
+ GetParent()->GetParent()->SendMessage(WM_NOTIFY, GetParent()->GetDlgCtrlID(), (LPARAM)&dispinfo);
+
+ PostMessage(WM_CLOSE);
+}
+
+void CInPlaceListBox::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ if(nChar == VK_ESCAPE || nChar == VK_RETURN)
+ {
+ if(nChar == VK_ESCAPE) m_bESC = TRUE;
+ GetParent()->SetFocus();
+ return;
+ }
+
+ CListBox::OnChar(nChar, nRepCnt, nFlags);
+}
+
+void CInPlaceListBox::OnNcDestroy()
+{
+ CListBox::OnNcDestroy();
+
+ delete this;
+}
+
+
+
+// CPlayerListCtrl
+
+IMPLEMENT_DYNAMIC(CPlayerListCtrl, CListCtrl)
+CPlayerListCtrl::CPlayerListCtrl(int tStartEditingDelay)
+ : m_tStartEditingDelay(tStartEditingDelay)
+ , m_nItemClicked(-1)
+{
+}
+
+CPlayerListCtrl::~CPlayerListCtrl()
+{
+}
+
+void CPlayerListCtrl::PreSubclassWindow()
+{
+ EnableToolTips(TRUE);
+
+ CListCtrl::PreSubclassWindow();
+}
+
+int CPlayerListCtrl::HitTestEx(CPoint& point, int* col) const
+{
+ if(col) *col = 0;
+
+ int row = HitTest(CPoint(0, point.y), NULL);
+
+ if((GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT)
+ return row;
+
+ int nColumnCount = ((CHeaderCtrl*)GetDlgItem(0))->GetItemCount();
+
+ for(int top = GetTopIndex(), bottom = GetBottomIndex(); top <= bottom; top++)
+ {
+ CRect r;
+ GetItemRect(top, &r, LVIR_BOUNDS);
+
+ if(r.top <= point.y && point.y < r.bottom)
+ {
+ for(int colnum = 0; colnum < nColumnCount; colnum++)
+ {
+ int colwidth = GetColumnWidth(colnum);
+
+ if(point.x >= r.left && point.x <= (r.left + colwidth))
+ {
+ if(col) *col = colnum;
+ return top;
+ }
+
+ r.left += colwidth;
+ }
+ }
+ }
+
+ return -1;
+}
+
+int CPlayerListCtrl::GetBottomIndex() const
+{
+ CRect r;
+ GetClientRect(r);
+
+ int nBottomIndex = GetTopIndex() + GetCountPerPage() - 1;
+
+ if(nBottomIndex >= GetItemCount())
+ {
+ nBottomIndex = GetItemCount() - 1;
+ }
+ else if(nBottomIndex < GetItemCount())
+ {
+ CRect br;
+ GetItemRect(nBottomIndex, br, LVIR_BOUNDS);
+
+ if(br.bottom < r.bottom)
+ nBottomIndex++;
+ }
+
+ return(nBottomIndex);
+}
+
+CImageList* CPlayerListCtrl::CreateDragImageEx(LPPOINT lpPoint)
+{
+ if(GetSelectedCount() <= 0)
+ return NULL;
+
+ CRect cSingleRect, cCompleteRect(0, 0, 0, 0);
+ GetClientRect(cSingleRect);
+ int nWidth = cSingleRect.Width();
+
+ // Start and Stop index in view area
+ int nIndex = GetTopIndex() - 1;
+ int nBottomIndex = GetBottomIndex();
+
+ // Determine the size of the drag image (limite for
+ // rows visibled and Client width)
+ while((nIndex = GetNextItem(nIndex, LVNI_SELECTED)) != -1 && nIndex <= nBottomIndex)
+ {
+ GetItemRect(nIndex, cSingleRect, LVIR_BOUNDS);
+/*
+ CRect r;
+ GetItemRect(nIndex, r, LVIR_LABEL);
+ cSingleRect.left = r.left;
+*/
+ if(cSingleRect.left < 0) cSingleRect.left = 0;
+ if(cSingleRect.right > nWidth) cSingleRect.right = nWidth;
+
+ cCompleteRect |= cSingleRect;
+ }
+
+ //
+ // Create bitmap in memory DC
+ //
+ CClientDC cDc(this);
+ CDC cMemDC;
+ CBitmap cBitmap;
+
+ if(!cMemDC.CreateCompatibleDC(&cDc))
+ return NULL;
+
+ if(!cBitmap.CreateCompatibleBitmap(&cDc, cCompleteRect.Width(), cCompleteRect.Height()))
+ return NULL;
+
+ CBitmap* pOldMemDCBitmap = cMemDC.SelectObject(&cBitmap);
+ // Here green is used as mask color
+ cMemDC.FillSolidRect(0, 0, cCompleteRect.Width(), cCompleteRect.Height(), RGB(0, 255, 0));
+
+ // Paint each DragImage in the DC
+ nIndex = GetTopIndex() - 1;
+ while((nIndex = GetNextItem(nIndex, LVNI_SELECTED)) != -1 && nIndex <= nBottomIndex)
+ {
+ CPoint pt;
+ CImageList* pSingleImageList = CreateDragImage(nIndex, &pt);
+
+ if(pSingleImageList)
+ {
+ GetItemRect(nIndex, cSingleRect, LVIR_BOUNDS);
+
+ pSingleImageList->Draw(&cMemDC,
+ 0,
+ CPoint(cSingleRect.left - cCompleteRect.left, cSingleRect.top - cCompleteRect.top),
+ ILD_MASK);
+
+ pSingleImageList->DeleteImageList();
+ delete pSingleImageList;
+ }
+ }
+
+ cMemDC.SelectObject(pOldMemDCBitmap);
+
+ //
+ // Create the imagelist with the merged drag images
+ //
+ CImageList* pCompleteImageList = new CImageList;
+
+ pCompleteImageList->Create(cCompleteRect.Width(),
+ cCompleteRect.Height(),
+ ILC_COLOR | ILC_MASK, 0, 1);
+
+ // Here green is used as mask color
+ pCompleteImageList->Add(&cBitmap, RGB(0, 255, 0));
+
+ //
+ // as an optional service:
+ // Find the offset of the current mouse cursor to the imagelist
+ // this we can use in BeginDrag()
+ //
+ if(lpPoint)
+ {
+ lpPoint->x = cCompleteRect.left;
+ lpPoint->y = cCompleteRect.top;
+ }
+
+ return(pCompleteImageList);
+}
+
+bool CPlayerListCtrl::PrepareInPlaceControl(int nRow, int nCol, CRect& rect)
+{
+ if(!EnsureVisible(nRow, TRUE)) return(false);
+
+ int nColumnCount = ((CHeaderCtrl*)GetDlgItem(0))->GetItemCount();
+ if(nCol >= nColumnCount || GetColumnWidth(nCol) < 5) return(false);
+
+ int offset = 0;
+ for(int i = 0; i < nCol; i++) offset += GetColumnWidth(i);
+
+ GetItemRect(nRow, &rect, LVIR_BOUNDS);
+
+ CRect rcClient;
+ GetClientRect(&rcClient);
+ if(offset + rect.left < 0 || offset + rect.left > rcClient.right)
+ {
+ CSize size(offset + rect.left, 0);
+ Scroll(size);
+ rect.left -= size.cx;
+ }
+
+ rect.left += offset;
+ rect.right = rect.left + GetColumnWidth(nCol);
+ if(rect.right > rcClient.right) rect.right = rcClient.right;
+
+ rect.DeflateRect(1, 0, 0, 1);
+
+ if(nCol == 0)
+ {
+ CRect r;
+ GetItemRect(nRow, r, LVIR_LABEL);
+ rect.left = r.left-1;
+ }
+
+ return(true);
+}
+
+CEdit* CPlayerListCtrl::ShowInPlaceEdit(int nItem, int nCol)
+{
+ CRect rect;
+ if(!PrepareInPlaceControl(nItem, nCol, rect))
+ return(NULL);
+
+ DWORD dwStyle = /*WS_BORDER|*/WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL;
+
+ LV_COLUMN lvcol;
+ lvcol.mask = LVCF_FMT;
+ GetColumn(nCol, &lvcol);
+ dwStyle |= (lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT ? ES_LEFT
+ : (lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_RIGHT ? ES_RIGHT
+ : ES_CENTER;
+
+ CEdit* pEdit = new CInPlaceEdit(nItem, nCol, GetItemText(nItem, nCol));
+ pEdit->Create(dwStyle, rect, this, IDC_EDIT1);
+
+ m_fInPlaceDirty = false;
+
+ return pEdit;
+}
+
+CComboBox* CPlayerListCtrl::ShowInPlaceComboBox(int nItem, int nCol, CAtlList<CString>& lstItems, int nSel)
+{
+ CRect rect;
+ if(!PrepareInPlaceControl(nItem, nCol, rect))
+ return(NULL);
+
+ DWORD dwStyle = /*WS_BORDER|*/WS_CHILD|WS_VISIBLE|WS_VSCROLL/*|WS_HSCROLL*/
+ |CBS_DROPDOWNLIST|CBS_DISABLENOSCROLL/*|CBS_NOINTEGRALHEIGHT*/;
+ CComboBox* pComboBox = new CInPlaceComboBox(nItem, nCol, lstItems, nSel);
+ pComboBox->Create(dwStyle, rect, this, IDC_COMBO1);
+
+ CorrectComboListWidth(*pComboBox, GetFont());
+
+ int width = GetColumnWidth(nCol);
+ if(pComboBox->GetDroppedWidth() < width)
+ pComboBox->SetDroppedWidth(width);
+
+ m_fInPlaceDirty = false;
+
+ return pComboBox;
+}
+
+CListBox* CPlayerListCtrl::ShowInPlaceListBox(int nItem, int nCol, CAtlList<CString>& lstItems, int nSel)
+{
+ CRect rect;
+ if(!PrepareInPlaceControl(nItem, nCol, rect))
+ return(NULL);
+
+ DWORD dwStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|WS_VSCROLL/*|WS_HSCROLL*/|LBS_NOTIFY;
+ CListBox* pListBox = new CInPlaceListBox(nItem, nCol, lstItems, nSel);
+ pListBox->Create(dwStyle, rect, this, IDC_LIST1);
+
+ CRect ir;
+ GetItemRect(m_nItemClicked, &ir, LVIR_BOUNDS);
+
+ pListBox->SetItemHeight(-1, ir.Height());
+
+ CDC* pDC = pListBox->GetDC();
+ CFont* pWndFont = GetFont();
+ pDC->SelectObject(pWndFont);
+ int width = GetColumnWidth(nCol);
+ POSITION pos = lstItems.GetHeadPosition();
+ while(pos)
+ {
+ int w = pDC->GetTextExtent(lstItems.GetNext(pos)).cx + 16;
+ if(width < w) width = w;
+ }
+ ReleaseDC(pDC);
+
+ CRect r;
+ pListBox->GetWindowRect(r);
+ ScreenToClient(r);
+ r.top = ir.bottom;
+ r.bottom = r.top + pListBox->GetItemHeight(0) * (pListBox->GetCount() + 1);
+ r.right = r.left + width;
+ pListBox->MoveWindow(r);
+
+ m_fInPlaceDirty = false;
+
+ return pListBox;
+}
+
+BEGIN_MESSAGE_MAP(CPlayerListCtrl, CListCtrl)
+ ON_WM_VSCROLL()
+ ON_WM_HSCROLL()
+ ON_WM_MOUSEWHEEL()
+ ON_WM_LBUTTONDOWN()
+ ON_WM_TIMER()
+ ON_WM_LBUTTONDBLCLK()
+ ON_NOTIFY_REFLECT(LVN_MARQUEEBEGIN, OnLvnMarqueeBegin)
+ ON_NOTIFY_REFLECT(LVN_INSERTITEM, OnLvnInsertitem)
+ ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnLvnDeleteitem)
+ ON_EN_CHANGE(IDC_EDIT1, OnEnChangeEdit1)
+ ON_CBN_DROPDOWN(IDC_COMBO1, OnCbnDropdownCombo1)
+ ON_CBN_SELENDOK(IDC_COMBO1, OnCbnSelendokCombo1)
+ ON_LBN_SELCHANGE(IDC_LIST1, OnLbnSelChangeList1)
+ ON_NOTIFY_EX(HDN_ITEMCHANGINGA, 0, OnHdnItemchanging)
+ ON_NOTIFY_EX(HDN_ITEMCHANGINGW, 0, OnHdnItemchanging)
+ ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify)
+ ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify)
+END_MESSAGE_MAP()
+
+// CPlayerListCtrl message handlers
+
+void CPlayerListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+ if(GetFocus() != this) SetFocus();
+ CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
+}
+
+void CPlayerListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+ if(GetFocus() != this) SetFocus();
+ CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
+}
+
+BOOL CPlayerListCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
+{
+ if(GetFocus() != this) SetFocus();
+ return CListCtrl::OnMouseWheel(nFlags, zDelta, pt);
+}
+
+void CPlayerListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ CListCtrl::OnLButtonDown(nFlags, point);
+
+ if(GetFocus() != this) SetFocus();
+
+ KillTimer(1);
+
+ int m_nItemClickedNow, m_nSubItemClickedNow;
+
+ if((m_nItemClickedNow = HitTestEx(point, &m_nSubItemClickedNow)) < 0)
+ {
+ m_nItemClicked = -1;
+ }
+ else if(m_nItemClicked == m_nItemClickedNow /*&& m_nSubItemClicked == m_nSubItemClickedNow*/)
+ {
+ m_nSubItemClicked = m_nSubItemClickedNow;
+
+ LV_DISPINFO dispinfo;
+ dispinfo.hdr.hwndFrom = m_hWnd;
+ dispinfo.hdr.idFrom = GetDlgCtrlID();
+ dispinfo.hdr.code = LVN_BEGINLABELEDIT;
+ dispinfo.item.mask = 0;
+ dispinfo.item.iItem = m_nItemClicked;
+ dispinfo.item.iSubItem = m_nSubItemClicked;
+ if(GetParent()->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo))
+ {
+ if(m_tStartEditingDelay > 0)
+ {
+ SetTimer(1, m_tStartEditingDelay, NULL);
+ }
+ else
+ {
+ dispinfo.hdr.code = LVN_DOLABELEDIT;
+ GetParent()->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo);
+ }
+ }
+ }
+ else
+ {
+ m_nItemClicked = m_nItemClickedNow;
+ m_nSubItemClicked = m_nSubItemClickedNow;
+
+ SetItemState(m_nItemClicked, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
+ }
+}
+
+void CPlayerListCtrl::OnTimer(UINT nIDEvent)
+{
+ if(nIDEvent == 1)
+ {
+ KillTimer(1);
+
+ UINT flag = LVIS_FOCUSED;
+ if((GetItemState(m_nItemClicked, flag) & flag) == flag && m_nSubItemClicked >= 0)
+ {
+ LV_DISPINFO dispinfo;
+ dispinfo.hdr.hwndFrom = m_hWnd;
+ dispinfo.hdr.idFrom = GetDlgCtrlID();
+ dispinfo.hdr.code = LVN_DOLABELEDIT;
+ dispinfo.item.mask = 0;
+ dispinfo.item.iItem = m_nItemClicked;
+ dispinfo.item.iSubItem = m_nSubItemClicked;
+ GetParent()->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo);
+ }
+ }
+
+ CListCtrl::OnTimer(nIDEvent);
+}
+
+void CPlayerListCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
+{
+ KillTimer(1);
+
+ CListCtrl::OnLButtonDblClk(nFlags, point);
+}
+
+void CPlayerListCtrl::OnLvnMarqueeBegin(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
+ *pResult = 1;
+}
+
+void CPlayerListCtrl::OnLvnInsertitem(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
+ m_nItemClicked = -1;
+ *pResult = 0;
+}
+
+void CPlayerListCtrl::OnLvnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
+ m_nItemClicked = -1;
+ *pResult = 0;
+}
+
+void CPlayerListCtrl::OnEnChangeEdit1()
+{
+ m_fInPlaceDirty = true;
+}
+
+void CPlayerListCtrl::OnCbnDropdownCombo1()
+{
+ CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO1);
+
+ CRect ir;
+ GetItemRect(m_nItemClicked, &ir, LVIR_BOUNDS);
+
+ CRect r;
+ pCombo->GetWindowRect(r);
+ ScreenToClient(r);
+ r.bottom = r.top + ir.Height() + pCombo->GetItemHeight(0)*10;
+ pCombo->MoveWindow(r);
+}
+
+void CPlayerListCtrl::OnCbnSelendokCombo1()
+{
+ m_fInPlaceDirty = true;
+}
+
+void CPlayerListCtrl::OnLbnSelChangeList1()
+{
+ m_fInPlaceDirty = true;
+ SetFocus();
+}
+
+BOOL CPlayerListCtrl::OnHdnItemchanging(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
+// SetFocus();
+ *pResult = 0;
+ return FALSE;
+}
+
+int CPlayerListCtrl::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
+{
+ int col;
+ int row = HitTestEx(point, &col);
+ if(row == -1)
+ return -1;
+
+ CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
+ int nColumnCount = pHeader->GetItemCount();
+
+ CRect rect;
+ GetItemRect(row, &rect, LVIR_BOUNDS);
+
+ for(int colnum = 0; colnum < nColumnCount; colnum++)
+ {
+ int colwidth = GetColumnWidth(colnum);
+
+ if(colnum == col)
+ {
+ rect.right = rect.left + colwidth; break;
+ }
+
+ rect.left += colwidth;
+ }
+
+ pTI->hwnd = m_hWnd;
+ pTI->uId = (UINT)((row<<10)+(col&0x3ff)+1);
+ pTI->lpszText = LPSTR_TEXTCALLBACK;
+ pTI->rect = rect;
+
+ return pTI->uId;
+}
+
+BOOL CPlayerListCtrl::OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
+{
+ TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
+ TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
+
+ UINT nID = pNMHDR->idFrom;
+
+ if(pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND)
+ || pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
+ {
+ // idFrom is actually the HWND of the tool
+ nID = ::GetDlgCtrlID((HWND)nID);
+ }
+
+ if(nID == 0) // Notification in NT from automatically
+ return FALSE; // created tooltip
+
+ if(pNMHDR->code == TTN_NEEDTEXTA) pTTTA->lParam = (LPARAM)m_hWnd;
+ else if(pNMHDR->code == TTN_NEEDTEXTW) pTTTW->lParam = (LPARAM)m_hWnd;
+
+ *pResult = 0;
+
+ return GetParent()->SendMessage(WM_NOTIFY, id, (LPARAM)pNMHDR);
+}
+
diff --git a/src/apps/mplayerc/PlayerListCtrl.h b/src/apps/mplayerc/PlayerListCtrl.h
new file mode 100644
index 000000000..870470061
--- /dev/null
+++ b/src/apps/mplayerc/PlayerListCtrl.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#define LVN_DOLABELEDIT (LVN_FIRST+1)
+
+class CInPlaceEdit : public CEdit
+{
+private:
+ int m_iItem;
+ int m_iSubItem;
+ CString m_sInitText;
+ BOOL m_bESC; // To indicate whether ESC key was pressed
+
+public:
+ CInPlaceEdit(int iItem, int iSubItem, CString sInitText);
+ virtual ~CInPlaceEdit();
+
+protected:
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnKillFocus(CWnd* pNewWnd);
+ afx_msg void OnNcDestroy();
+ afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+};
+
+class CInPlaceComboBox : public CComboBox
+{
+private:
+ int m_iItem;
+ int m_iSubItem;
+ CAtlList<CString> m_lstItems;
+ int m_nSel;
+ BOOL m_bESC; // To indicate whether ESC key was pressed
+
+public:
+ CInPlaceComboBox(int iItem, int iSubItem, CAtlList<CString>& plstItems, int nSel);
+ virtual ~CInPlaceComboBox();
+
+protected:
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnKillFocus(CWnd* pNewWnd);
+ afx_msg void OnNcDestroy();
+ afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnCloseup();
+};
+
+class CInPlaceListBox : public CListBox
+{
+private:
+ int m_iItem;
+ int m_iSubItem;
+ CAtlList<CString> m_lstItems;
+ int m_nSel;
+ BOOL m_bESC; // To indicate whether ESC key was pressed
+
+public:
+ CInPlaceListBox(int iItem, int iSubItem, CAtlList<CString>& plstItems, int nSel);
+ virtual ~CInPlaceListBox();
+
+protected:
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnKillFocus(CWnd* pNewWnd);
+ afx_msg void OnNcDestroy();
+ afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+};
+
+// CPlayerListCtrl
+
+class CPlayerListCtrl : public CListCtrl
+{
+ DECLARE_DYNAMIC(CPlayerListCtrl)
+
+private:
+ int m_nItemClicked, m_nSubItemClicked;
+ int m_tStartEditingDelay;
+
+ bool PrepareInPlaceControl(int nRow, int nCol, CRect& rect);
+
+public:
+ CPlayerListCtrl(int tStartEditingDelay = 500);
+ virtual ~CPlayerListCtrl();
+
+ int HitTestEx(CPoint& point, int* col) const;
+ CImageList* CreateDragImageEx(LPPOINT lpPoint);
+
+ int GetBottomIndex() const;
+
+ CEdit* ShowInPlaceEdit(int nItem, int nCol);
+ CComboBox* ShowInPlaceComboBox(int nItem, int nCol, CAtlList<CString>& lstItems, int nSel);
+ CListBox* ShowInPlaceListBox(int nItem, int nCol, CAtlList<CString>& lstItems, int nSel);
+
+ bool m_fInPlaceDirty;
+
+protected:
+ virtual void PreSubclassWindow();
+ virtual int OnToolHitTest(CPoint point, TOOLINFO* pTI) const;
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
+ afx_msg void OnTimer(UINT nIDEvent);
+ afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
+ afx_msg void OnLvnMarqueeBegin(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnLvnInsertitem(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnLvnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnEnChangeEdit1();
+ afx_msg void OnCbnDropdownCombo1();
+ afx_msg void OnCbnSelendokCombo1();
+ afx_msg void OnLbnSelChangeList1();
+ afx_msg BOOL OnHdnItemchanging(UINT id, NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg BOOL OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult);
+};
diff --git a/src/apps/mplayerc/PlayerPlaylistBar.cpp b/src/apps/mplayerc/PlayerPlaylistBar.cpp
new file mode 100644
index 000000000..d116cc87a
--- /dev/null
+++ b/src/apps/mplayerc/PlayerPlaylistBar.cpp
@@ -0,0 +1,1405 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include <math.h>
+#include <afxinet.h>
+#include <atlrx.h>
+#include <atlutil.h>
+#include "mplayerc.h"
+#include "mainfrm.h"
+#include "..\..\DSUtil\DSUtil.h"
+#include "SaveTextFileDialog.h"
+#include ".\playerplaylistbar.h"
+
+IMPLEMENT_DYNAMIC(CPlayerPlaylistBar, CSizingControlBarG)
+CPlayerPlaylistBar::CPlayerPlaylistBar()
+ : m_list(0)
+ , m_nTimeColWidth(0)
+{
+ m_bDragging = FALSE;
+}
+
+CPlayerPlaylistBar::~CPlayerPlaylistBar()
+{
+}
+
+BOOL CPlayerPlaylistBar::Create(CWnd* pParentWnd)
+{
+ if(!CSizingControlBarG::Create(_T("Playlist"), pParentWnd, 0))
+ return FALSE;
+
+ m_list.CreateEx(
+ WS_EX_DLGMODALFRAME|WS_EX_CLIENTEDGE,
+ WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_TABSTOP
+ |LVS_OWNERDRAWFIXED
+ |LVS_NOCOLUMNHEADER
+ |LVS_EDITLABELS
+ |LVS_REPORT|LVS_SINGLESEL|LVS_AUTOARRANGE|LVS_NOSORTHEADER, // TODO: remove LVS_SINGLESEL and implement multiple item repositioning (dragging is ready)
+ CRect(0,0,100,100), this, IDC_PLAYLIST);
+
+ m_list.SetExtendedStyle(m_list.GetExtendedStyle()|LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER);
+
+ m_list.InsertColumn(COL_NAME, _T("Name"), LVCFMT_LEFT, 380);
+
+ CDC* pDC = m_list.GetDC();
+ CFont* old = pDC->SelectObject(GetFont());
+ m_nTimeColWidth = pDC->GetTextExtent(_T("000:00:00")).cx + 5;
+ pDC->SelectObject(old);
+ m_list.ReleaseDC(pDC);
+ m_list.InsertColumn(COL_TIME, _T("Time"), LVCFMT_RIGHT, m_nTimeColWidth);
+
+ m_fakeImageList.Create(1, 16, ILC_COLOR4, 10, 10);
+ m_list.SetImageList(&m_fakeImageList, LVSIL_SMALL);
+
+ return TRUE;
+}
+
+BOOL CPlayerPlaylistBar::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if(!CSizingControlBarG::PreCreateWindow(cs))
+ return FALSE;
+
+ cs.dwExStyle |= WS_EX_ACCEPTFILES;
+
+ return TRUE;
+}
+
+BOOL CPlayerPlaylistBar::PreTranslateMessage(MSG* pMsg)
+{
+ if(IsWindow(pMsg->hwnd) && IsVisible() && pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
+ {
+ if(IsDialogMessage(pMsg))
+ return TRUE;
+ }
+
+ return CSizingControlBarG::PreTranslateMessage(pMsg);
+}
+
+bool FindFileInList(CAtlList<CString>& sl, CString fn)
+{
+ bool fFound = false;
+ POSITION pos = sl.GetHeadPosition();
+ while(pos && !fFound) {if(!sl.GetNext(pos).CompareNoCase(fn)) fFound = true;}
+ return(fFound);
+}
+
+void CPlayerPlaylistBar::AddItem(CString fn, CAtlList<CString>* subs)
+{
+ CAtlList<CString> sl;
+ sl.AddTail(fn);
+ AddItem(sl, subs);
+}
+
+void CPlayerPlaylistBar::AddItem(CAtlList<CString>& fns, CAtlList<CString>* subs)
+{
+ CPlaylistItem pli;
+
+ POSITION pos = fns.GetHeadPosition();
+ while(pos)
+ {
+ CString fn = fns.GetNext(pos);
+ if(!fn.Trim().IsEmpty()) pli.m_fns.AddTail(fn);
+ }
+
+ if(subs)
+ {
+ POSITION pos = subs->GetHeadPosition();
+ while(pos)
+ {
+ CString fn = subs->GetNext(pos);
+ if(!fn.Trim().IsEmpty()) pli.m_subs.AddTail(fn);
+ }
+ }
+
+ if(pli.m_fns.IsEmpty()) return;
+
+ CString fn = pli.m_fns.GetHead();
+
+ if(AfxGetAppSettings().fAutoloadAudio && fn.Find(_T("://")) < 0)
+ {
+ int i = fn.ReverseFind('.');
+ if(i > 0)
+ {
+ CMediaFormats& mf = AfxGetAppSettings().Formats;
+
+ CString ext = fn.Mid(i+1).MakeLower();
+
+ if(!mf.FindExt(ext, true))
+ {
+ CString path = fn;
+ path.Replace('/', '\\');
+ path = path.Left(path.ReverseFind('\\')+1);
+
+ WIN32_FIND_DATA fd = {0};
+ HANDLE hFind = FindFirstFile(fn.Left(i) + _T("*.*"), &fd);
+ if(hFind != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) continue;
+
+ CString fullpath = path + fd.cFileName;
+ CString ext2 = fullpath.Mid(fullpath.ReverseFind('.')+1).MakeLower();
+ if(!FindFileInList(pli.m_fns, fullpath) && ext != ext2
+ && mf.FindExt(ext2, true) && mf.IsUsingEngine(fullpath, DirectShow))
+ {
+ pli.m_fns.AddTail(fullpath);
+ }
+ }
+ while(FindNextFile(hFind, &fd));
+
+ FindClose(hFind);
+ }
+ }
+ }
+ }
+
+ if(AfxGetAppSettings().fAutoloadSubtitles)
+ {
+ CAtlArray<CString> paths;
+ paths.Add(_T("."));
+ paths.Add(_T(".\\subtitles"));
+ paths.Add(_T("c:\\subtitles"));
+
+ CAtlArray<SubFile> ret;
+ GetSubFileNames(fn, paths, ret);
+
+ for(int i = 0; i < ret.GetCount(); i++)
+ {
+ if(!FindFileInList(pli.m_subs, ret[i].fn))
+ pli.m_subs.AddTail(ret[i].fn);
+ }
+ }
+
+ m_pl.AddTail(pli);
+}
+
+static bool SearchFiles(CString mask, CAtlList<CString>& sl)
+{
+ if(mask.Find(_T("://")) >= 0)
+ return(false);
+
+ mask.Trim();
+ sl.RemoveAll();
+
+ CMediaFormats& mf = AfxGetAppSettings().Formats;
+
+ bool fFilterKnownExts;
+ WIN32_FILE_ATTRIBUTE_DATA fad;
+ mask = (fFilterKnownExts = (GetFileAttributesEx(mask, GetFileExInfoStandard, &fad)
+ && (fad.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)))
+ ? CString(mask).TrimRight(_T("\\/")) + _T("\\*.*")
+ : mask;
+
+ {
+ CString dir = mask.Left(max(mask.ReverseFind('\\'), mask.ReverseFind('/'))+1);
+
+ WIN32_FIND_DATA fd;
+ HANDLE h = FindFirstFile(mask, &fd);
+ if(h != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) continue;
+
+ CString fn = fd.cFileName;
+ CString ext = fn.Mid(fn.ReverseFind('.')+1).MakeLower();
+ CString path = dir + fd.cFileName;
+
+ if(!fFilterKnownExts || mf.FindExt(ext))
+ sl.AddTail(path);
+ }
+ while(FindNextFile(h, &fd));
+
+ FindClose(h);
+
+ if(sl.GetCount() == 0 && mask.Find(_T(":\\")) == 1)
+ {
+ GetCDROMType(mask[0], sl);
+ }
+ }
+ }
+
+ return(sl.GetCount() > 1
+ || sl.GetCount() == 1 && sl.GetHead().CompareNoCase(mask)
+ || sl.GetCount() == 0 && mask.FindOneOf(_T("?*")) >= 0);
+}
+
+void CPlayerPlaylistBar::ParsePlayList(CString fn, CAtlList<CString>* subs)
+{
+ CAtlList<CString> sl;
+ sl.AddTail(fn);
+ ParsePlayList(sl, subs);
+}
+
+void CPlayerPlaylistBar::ParsePlayList(CAtlList<CString>& fns, CAtlList<CString>* subs)
+{
+ if(fns.IsEmpty()) return;
+
+ // resolve .lnk files
+
+ CComPtr<IShellLink> pSL;
+ pSL.CoCreateInstance(CLSID_ShellLink);
+ CComQIPtr<IPersistFile> pPF = pSL;
+
+ POSITION pos = fns.GetHeadPosition();
+ while(pSL && pPF && pos)
+ {
+ CString& fn = fns.GetNext(pos);
+ TCHAR buff[MAX_PATH];
+ if(CPath(fn).GetExtension().MakeLower() != _T(".lnk")
+ || FAILED(pPF->Load(CStringW(fn), STGM_READ))
+ || FAILED(pSL->Resolve(NULL, SLR_ANY_MATCH|SLR_NO_UI))
+ || FAILED(pSL->GetPath(buff, countof(buff), NULL, 0)))
+ continue;
+
+ fn = buff;
+ }
+
+ //
+
+ CAtlList<CString> sl;
+ if(SearchFiles(fns.GetHead(), sl))
+ {
+ if(sl.GetCount() > 1) subs = NULL;
+ POSITION pos = sl.GetHeadPosition();
+ while(pos) ParsePlayList(sl.GetNext(pos), subs);
+ return;
+ }
+
+ CAtlList<CString> redir;
+ CStringA ct = GetContentType(fns.GetHead(), &redir);
+ if(!redir.IsEmpty())
+ {
+ POSITION pos = redir.GetHeadPosition();
+ while(pos) ParsePlayList(sl.GetNext(pos), subs);
+ return;
+ }
+
+ if(ct == "application/x-mpc-playlist")
+ {
+ ParseMPCPlayList(fns.GetHead());
+ return;
+ }
+
+ AddItem(fns, subs);
+}
+
+static int s_int_comp(const void* i1, const void* i2)
+{
+ return (int)i1 - (int)i2;
+}
+
+static CString CombinePath(CPath p, CString fn)
+{
+ if(fn.Find(':') >= 0 || fn.Find(_T("\\")) == 0) return fn;
+ p.Append(CPath(fn));
+ return (LPCTSTR)p;
+}
+
+bool CPlayerPlaylistBar::ParseMPCPlayList(CString fn)
+{
+ CString str;
+ CAtlMap<int, CPlaylistItem> pli;
+ CAtlArray<int> idx;
+
+ CWebTextFile f(CTextFile::ANSI);
+ if(!f.Open(fn) || !f.ReadString(str) || str != _T("MPCPLAYLIST"))
+ return false;
+
+ CPath base(fn);
+ base.RemoveFileSpec();
+
+ while(f.ReadString(str))
+ {
+ CAtlList<CString> sl;
+ Explode(str, sl, ',', 3);
+ if(sl.GetCount() != 3) continue;
+
+ if(int i = _ttoi(sl.RemoveHead()))
+ {
+ CString key = sl.RemoveHead();
+ CString value = sl.RemoveHead();
+
+ if(key == _T("type")) {pli[i].m_type = (CPlaylistItem::type_t)_ttol(value); idx.Add(i);}
+ else if(key == _T("label")) pli[i].m_label = value;
+ else if(key == _T("filename")) {value = CombinePath(base, value); pli[i].m_fns.AddTail(value);}
+ else if(key == _T("subtitle")) {value = CombinePath(base, value); pli[i].m_subs.AddTail(value);}
+ else if(key == _T("video")) {while(pli[i].m_fns.GetCount() < 2) pli[i].m_fns.AddTail(_T("")); pli[i].m_fns.GetHead() = value;}
+ else if(key == _T("audio")) {while(pli[i].m_fns.GetCount() < 2) pli[i].m_fns.AddTail(_T("")); pli[i].m_fns.GetTail() = value;}
+ else if(key == _T("vinput")) pli[i].m_vinput = _ttol(value);
+ else if(key == _T("vchannel")) pli[i].m_vchannel = _ttol(value);
+ else if(key == _T("ainput")) pli[i].m_ainput = _ttol(value);
+ else if(key == _T("country")) pli[i].m_country = _ttol(value);
+ }
+ }
+
+ qsort(idx.GetData(), idx.GetCount(), sizeof(int), s_int_comp);
+ for(int i = 0; i < idx.GetCount(); i++)
+ m_pl.AddTail(pli[idx[i]]);
+
+ return pli.GetCount() > 0;
+}
+
+bool CPlayerPlaylistBar::SaveMPCPlayList(CString fn, CTextFile::enc e, bool fRemovePath)
+{
+ CTextFile f;
+ if(!f.Save(fn, e))
+ return false;
+
+ f.WriteString(_T("MPCPLAYLIST\n"));
+
+ POSITION pos = m_pl.GetHeadPosition(), pos2;
+ for(int i = 1; pos; i++)
+ {
+ CPlaylistItem& pli = m_pl.GetNext(pos);
+
+ CString idx;
+ idx.Format(_T("%d"), i);
+
+ CString str;
+ str.Format(_T("%d,type,%d"), i, pli.m_type);
+ f.WriteString(str + _T("\n"));
+
+ if(!pli.m_label.IsEmpty())
+ f.WriteString(idx + _T(",label,") + pli.m_label + _T("\n"));
+
+ if(pli.m_type == CPlaylistItem::file)
+ {
+ pos2 = pli.m_fns.GetHeadPosition();
+ while(pos2)
+ {
+ CString fn = pli.m_fns.GetNext(pos2);
+ if(fRemovePath) {CPath p(fn); p.StripPath(); fn = (LPCTSTR)p;}
+ f.WriteString(idx + _T(",filename,") + fn + _T("\n"));
+ }
+
+ pos2 = pli.m_subs.GetHeadPosition();
+ while(pos2)
+ {
+ CString fn = pli.m_subs.GetNext(pos2);
+ if(fRemovePath) {CPath p(fn); p.StripPath(); fn = (LPCTSTR)p;}
+ f.WriteString(idx + _T(",subtitle,") + fn + _T("\n"));
+ }
+ }
+ else if(pli.m_type == CPlaylistItem::device && pli.m_fns.GetCount() == 2)
+ {
+ f.WriteString(idx + _T(",video,") + pli.m_fns.GetHead() + _T("\n"));
+ f.WriteString(idx + _T(",audio,") + pli.m_fns.GetTail() + _T("\n"));
+ str.Format(_T("%d,vinput,%d"), i, pli.m_vinput);
+ f.WriteString(str + _T("\n"));
+ str.Format(_T("%d,vchannel,%d"), i, pli.m_vchannel);
+ f.WriteString(str + _T("\n"));
+ str.Format(_T("%d,ainput,%d"), i, pli.m_ainput);
+ f.WriteString(str + _T("\n"));
+ str.Format(_T("%d,country,%d"), i, pli.m_country);
+ f.WriteString(str + _T("\n"));
+ }
+ }
+
+ return true;
+}
+
+void CPlayerPlaylistBar::Refresh()
+{
+ SetupList();
+ ResizeListColumn();
+}
+
+void CPlayerPlaylistBar::Empty()
+{
+ m_pl.RemoveAll();
+ m_list.DeleteAllItems();
+ SavePlaylist();
+}
+
+void CPlayerPlaylistBar::Open(CAtlList<CString>& fns, bool fMulti, CAtlList<CString>* subs)
+{
+ Empty();
+ Append(fns, fMulti, subs);
+}
+
+void CPlayerPlaylistBar::Append(CAtlList<CString>& fns, bool fMulti, CAtlList<CString>* subs)
+{
+ if(fMulti)
+ {
+ ASSERT(subs == NULL || subs->GetCount() == 0);
+ POSITION pos = fns.GetHeadPosition();
+ while(pos) ParsePlayList(fns.GetNext(pos), NULL);
+ }
+ else
+ {
+ ParsePlayList(fns, subs);
+ }
+
+ Refresh();
+ SavePlaylist();
+}
+
+void CPlayerPlaylistBar::Open(CStringW vdn, CStringW adn, int vinput, int vchannel, int ainput)
+{
+ Empty();
+ Append(vdn, adn, vinput, vchannel, ainput);
+}
+
+void CPlayerPlaylistBar::Append(CStringW vdn, CStringW adn, int vinput, int vchannel, int ainput)
+{
+ CPlaylistItem pli;
+ pli.m_type = CPlaylistItem::device;
+ pli.m_fns.AddTail(CString(vdn));
+ pli.m_fns.AddTail(CString(adn));
+ pli.m_vinput = vinput;
+ pli.m_vchannel = vchannel;
+ pli.m_ainput = ainput;
+ CAtlList<CStringW> sl;
+ CStringW vfn = GetFriendlyName(vdn);
+ CStringW afn = GetFriendlyName(adn);
+ if(!vfn.IsEmpty()) sl.AddTail(vfn);
+ if(!afn.IsEmpty()) sl.AddTail(afn);
+ CStringW label = Implode(sl, '|');
+ label.Replace(L"|", L" - ");
+ pli.m_label = CString(label);
+ m_pl.AddTail(pli);
+
+ Refresh();
+ SavePlaylist();
+}
+
+void CPlayerPlaylistBar::SetupList()
+{
+ m_list.DeleteAllItems();
+
+ POSITION pos = m_pl.GetHeadPosition();
+ for(int i = 0; pos; i++)
+ {
+ CPlaylistItem& pli = m_pl.GetAt(pos);
+ m_list.SetItemData(m_list.InsertItem(i, pli.GetLabel()), (DWORD_PTR)pos);
+ m_list.SetItemText(i, COL_TIME, pli.GetLabel(1));
+ m_pl.GetNext(pos);
+ }
+}
+
+void CPlayerPlaylistBar::UpdateList()
+{
+ POSITION pos = m_pl.GetHeadPosition();
+ for(int i = 0, j = m_list.GetItemCount(); pos && i < j; i++)
+ {
+ CPlaylistItem& pli = m_pl.GetAt(pos);
+ m_list.SetItemData(i, (DWORD_PTR)pos);
+ m_list.SetItemText(i, COL_NAME, pli.GetLabel(0));
+ m_list.SetItemText(i, COL_TIME, pli.GetLabel(1));
+ m_pl.GetNext(pos);
+ }
+}
+
+void CPlayerPlaylistBar::EnsureVisible(POSITION pos)
+{
+ int i = FindItem(m_pl.GetPos());
+ if(i < 0) return;
+ m_list.EnsureVisible(i, TRUE);
+ m_list.Invalidate();
+}
+
+int CPlayerPlaylistBar::FindItem(POSITION pos)
+{
+ for(int i = 0; i < m_list.GetItemCount(); i++)
+ if((POSITION)m_list.GetItemData(i) == pos)
+ return(i);
+ return(-1);
+}
+
+POSITION CPlayerPlaylistBar::FindPos(int i)
+{
+ if(i < 0) return(NULL);
+ return((POSITION)m_list.GetItemData(i));
+}
+
+int CPlayerPlaylistBar::GetCount()
+{
+ return(m_pl.GetCount()); // TODO: n - .fInvalid
+}
+
+int CPlayerPlaylistBar::GetSelIdx()
+{
+ return(FindItem(m_pl.GetPos()));
+}
+
+void CPlayerPlaylistBar::SetSelIdx(int i)
+{
+ m_pl.SetPos(FindPos(i));
+}
+
+bool CPlayerPlaylistBar::IsAtEnd()
+{
+ return(m_pl.GetPos() && m_pl.GetPos() == m_pl.GetTailPosition());
+}
+
+bool CPlayerPlaylistBar::GetCur(CPlaylistItem& pli)
+{
+ if(!m_pl.GetPos()) return(false);
+ pli = m_pl.GetAt(m_pl.GetPos());
+ return(true);
+}
+
+CString CPlayerPlaylistBar::GetCur()
+{
+ CString fn;
+ CPlaylistItem pli;
+ if(GetCur(pli) && !pli.m_fns.IsEmpty()) fn = pli.m_fns.GetHead();
+ return(fn);
+}
+
+void CPlayerPlaylistBar::SetNext()
+{
+ POSITION pos = m_pl.GetPos(), org = pos;
+ while(m_pl.GetNextWrap(pos).m_fInvalid && pos != org);
+UpdateList();
+ m_pl.SetPos(pos);
+ EnsureVisible(pos);
+}
+
+void CPlayerPlaylistBar::SetPrev()
+{
+ POSITION pos = m_pl.GetPos(), org = pos;
+ while(m_pl.GetPrevWrap(pos).m_fInvalid && pos != org);
+ m_pl.SetPos(pos);
+ EnsureVisible(pos);
+}
+
+void CPlayerPlaylistBar::SetFirst()
+{
+ POSITION pos = m_pl.GetTailPosition(), org = pos;
+ while(m_pl.GetNextWrap(pos).m_fInvalid && pos != org);
+UpdateList();
+ m_pl.SetPos(pos);
+ EnsureVisible(pos);
+}
+
+void CPlayerPlaylistBar::SetLast()
+{
+ POSITION pos = m_pl.GetHeadPosition(), org = pos;
+ while(m_pl.GetPrevWrap(pos).m_fInvalid && pos != org);
+ m_pl.SetPos(pos);
+ EnsureVisible(pos);
+}
+
+void CPlayerPlaylistBar::SetCurValid(bool fValid)
+{
+ if(POSITION pos = m_pl.GetPos())
+ {
+ if(m_pl.GetAt(pos).m_fInvalid = !fValid)
+ {
+ int i = FindItem(pos);
+ m_list.RedrawItems(i, i);
+ }
+ }
+}
+
+void CPlayerPlaylistBar::SetCurTime(REFERENCE_TIME rt)
+{
+ if(POSITION pos = m_pl.GetPos())
+ {
+ CPlaylistItem& pli = m_pl.GetAt(pos);
+ pli.m_duration = rt;
+ m_list.SetItemText(FindItem(pos), COL_TIME, pli.GetLabel(1));
+ }
+}
+
+OpenMediaData* CPlayerPlaylistBar::GetCurOMD(REFERENCE_TIME rtStart)
+{
+ CPlaylistItem pli;
+ if(!GetCur(pli)) return NULL;
+
+ CString fn = CString(pli.m_fns.GetHead()).MakeLower();
+
+ if(fn.Find(_T("video_ts.ifo")) >= 0
+ || fn.Find(_T(".ratdvd")) >= 0)
+ {
+ if(OpenDVDData* p = new OpenDVDData())
+ {
+ p->path = pli.m_fns.GetHead();
+ p->subs.AddTailList(&pli.m_subs);
+ return p;
+ }
+ }
+
+ if(pli.m_type == CPlaylistItem::device)
+ {
+ if(OpenDeviceData* p = new OpenDeviceData())
+ {
+ POSITION pos = pli.m_fns.GetHeadPosition();
+ for(int i = 0; i < countof(p->DisplayName) && pos; i++)
+ p->DisplayName[i] = pli.m_fns.GetNext(pos);
+ p->vinput = pli.m_vinput;
+ p->vchannel = pli.m_vchannel;
+ p->ainput = pli.m_ainput;
+ return p;
+ }
+ }
+ else
+ {
+ if(OpenFileData* p = new OpenFileData())
+ {
+ p->fns.AddTailList(&pli.m_fns);
+ p->subs.AddTailList(&pli.m_subs);
+ p->rtStart = rtStart;
+ return p;
+ }
+ }
+
+ return NULL;
+}
+
+void CPlayerPlaylistBar::LoadPlaylist()
+{
+ CString base;
+ if(AfxGetMyApp()->GetAppDataPath(base))
+ {
+ CPath p;
+ p.Combine(base, _T("default.mpcpl"));
+
+ if(!AfxGetApp()->GetProfileInt(ResStr(IDS_R_SETTINGS), _T("RememberPlaylistItems"), TRUE))
+ {
+ DeleteFile(p);
+ }
+ else
+ {
+ ParseMPCPlayList(p);
+ Refresh();
+ }
+ }
+}
+
+void CPlayerPlaylistBar::SavePlaylist()
+{
+ CString base;
+ if(AfxGetMyApp()->GetAppDataPath(base))
+ {
+ CPath p;
+ p.Combine(base, _T("default.mpcpl"));
+
+ if(!AfxGetApp()->GetProfileInt(ResStr(IDS_R_SETTINGS), _T("RememberPlaylistItems"), TRUE))
+ {
+ DeleteFile(p);
+ }
+ else
+ {
+ SaveMPCPlayList(p, CTextFile::UTF8, false);
+ }
+ }
+}
+
+BEGIN_MESSAGE_MAP(CPlayerPlaylistBar, CSizingControlBarG)
+ ON_WM_SIZE()
+ ON_NOTIFY(LVN_KEYDOWN, IDC_PLAYLIST, OnLvnKeyDown)
+ ON_NOTIFY(NM_DBLCLK, IDC_PLAYLIST, OnNMDblclkList)
+// ON_NOTIFY(NM_CUSTOMDRAW, IDC_PLAYLIST, OnCustomdrawList)
+ ON_WM_DRAWITEM()
+ ON_COMMAND_EX(ID_FILE_CLOSEPLAYLIST, OnFileClosePlaylist)
+ ON_COMMAND_EX(ID_PLAY_PLAY, OnPlayPlay)
+ ON_WM_DROPFILES()
+ ON_NOTIFY(LVN_BEGINDRAG, IDC_PLAYLIST, OnBeginDrag)
+ ON_WM_MOUSEMOVE()
+ ON_WM_LBUTTONUP()
+ ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify)
+ ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify)
+ ON_WM_TIMER()
+ ON_WM_CONTEXTMENU()
+ ON_NOTIFY(LVN_ENDLABELEDIT, IDC_PLAYLIST, OnLvnEndlabeleditList)
+END_MESSAGE_MAP()
+
+
+// CPlayerPlaylistBar message handlers
+
+void CPlayerPlaylistBar::ResizeListColumn()
+{
+ if(::IsWindow(m_list.m_hWnd))
+ {
+ CRect r;
+ GetClientRect(r);
+ r.DeflateRect(2, 2);
+ m_list.SetRedraw(FALSE);
+ m_list.MoveWindow(r);
+ m_list.GetClientRect(r);
+ m_list.SetColumnWidth(COL_NAME, r.Width()-m_nTimeColWidth); //LVSCW_AUTOSIZE_USEHEADER
+ m_list.SetRedraw(TRUE);
+ }
+}
+
+void CPlayerPlaylistBar::OnSize(UINT nType, int cx, int cy)
+{
+ CSizingControlBarG::OnSize(nType, cx, cy);
+
+ ResizeListColumn();
+}
+
+void CPlayerPlaylistBar::OnLvnKeyDown(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMLVKEYDOWN pLVKeyDown = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);
+
+ *pResult = FALSE;
+
+ CList<int> items;
+ POSITION pos = m_list.GetFirstSelectedItemPosition();
+ while(pos) items.AddHead(m_list.GetNextSelectedItem(pos));
+
+ if(pLVKeyDown->wVKey == VK_DELETE && items.GetCount() > 0)
+ {
+ pos = items.GetHeadPosition();
+ while(pos)
+ {
+ int i = items.GetNext(pos);
+ if(m_pl.RemoveAt(FindPos(i))) ((CMainFrame*)AfxGetMainWnd())->CloseMedia();
+ m_list.DeleteItem(i);
+ }
+
+ m_list.SetItemState(-1, 0, LVIS_SELECTED);
+ m_list.SetItemState(
+ max(min(items.GetTail(), m_list.GetItemCount()-1), 0),
+ LVIS_SELECTED, LVIS_SELECTED);
+
+ ResizeListColumn();
+
+ *pResult = TRUE;
+ }
+ else if(pLVKeyDown->wVKey == VK_SPACE && items.GetCount() == 1)
+ {
+ m_pl.SetPos(FindPos(items.GetHead()));
+
+ ((CMainFrame*)AfxGetMainWnd())->OpenCurPlaylistItem();
+
+ *pResult = TRUE;
+ }
+}
+
+void CPlayerPlaylistBar::OnNMDblclkList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)pNMHDR;
+
+ if(lpnmlv->iItem >= 0 && lpnmlv->iSubItem >= 0)
+ {
+ m_pl.SetPos(FindPos(lpnmlv->iItem));
+ m_list.Invalidate();
+ ((CMainFrame*)AfxGetMainWnd())->OpenCurPlaylistItem();
+ }
+
+ *pResult = 0;
+}
+/*
+void CPlayerPlaylistBar::OnCustomdrawList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
+
+ *pResult = CDRF_DODEFAULT;
+
+ if(CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)
+ {
+ *pResult = CDRF_NOTIFYPOSTPAINT|CDRF_NOTIFYITEMDRAW;
+ }
+ else if(CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
+ {
+ pLVCD->nmcd.uItemState &= ~CDIS_SELECTED;
+ pLVCD->nmcd.uItemState &= ~CDIS_FOCUS;
+
+ pLVCD->clrText = (pLVCD->nmcd.dwItemSpec == m_playList.m_idx) ? 0x0000ff : CLR_DEFAULT;
+ pLVCD->clrTextBk = m_list.GetItemState(pLVCD->nmcd.dwItemSpec, LVIS_SELECTED) ? 0xf1dacc : CLR_DEFAULT;
+
+ *pResult = CDRF_NOTIFYPOSTPAINT;
+ }
+ else if(CDDS_ITEMPOSTPAINT == pLVCD->nmcd.dwDrawStage)
+ {
+ int nItem = static_cast<int>(pLVCD->nmcd.dwItemSpec);
+
+ if(m_list.GetItemState(pLVCD->nmcd.dwItemSpec, LVIS_SELECTED))
+ {
+ CRect r, r2;
+ m_list.GetItemRect(nItem, &r, LVIR_BOUNDS);
+ m_list.GetItemRect(nItem, &r2, LVIR_LABEL);
+ r.left = r2.left;
+ FrameRect(pLVCD->nmcd.hdc, &r, CBrush(0xc56a31));
+ }
+
+ *pResult = CDRF_SKIPDEFAULT;
+ }
+ else if(CDDS_POSTPAINT == pLVCD->nmcd.dwDrawStage)
+ {
+ }
+}
+*/
+
+void CPlayerPlaylistBar::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
+{
+ if(nIDCtl != IDC_PLAYLIST) return;
+
+ int nItem = lpDrawItemStruct->itemID;
+ CRect rcItem = lpDrawItemStruct->rcItem;
+ POSITION pos = FindPos(nItem);
+ bool fSelected = pos == m_pl.GetPos();
+ CPlaylistItem& pli = m_pl.GetAt(pos);
+
+ CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
+
+ if(!!m_list.GetItemState(nItem, LVIS_SELECTED))
+ {
+ FillRect(pDC->m_hDC, rcItem, CBrush(0xf1dacc));
+ FrameRect(pDC->m_hDC, rcItem, CBrush(0xc56a31));
+ }
+ else
+ {
+ FillRect(pDC->m_hDC, rcItem, CBrush(GetSysColor(COLOR_WINDOW)));
+ }
+
+ COLORREF textcolor = fSelected?0xff:0;
+ if(pli.m_fInvalid) textcolor |= 0xA0A0A0;
+
+ CString time = !pli.m_fInvalid ? m_list.GetItemText(nItem, COL_TIME) : _T("Invalid");
+ CSize timesize(0, 0);
+ CPoint timept(rcItem.right, 0);
+ if(time.GetLength() > 0)
+ {
+ timesize = pDC->GetTextExtent(time);
+ if((3+timesize.cx+3) < rcItem.Width()/2)
+ {
+ timept = CPoint(rcItem.right-(3+timesize.cx+3), (rcItem.top+rcItem.bottom-timesize.cy)/2);
+
+ pDC->SetTextColor(textcolor);
+ pDC->TextOut(timept.x, timept.y, time);
+ }
+ }
+
+ CString fmt, file;
+ fmt.Format(_T("%%0%dd. %%s"), (int)log10(0.1+m_pl.GetCount())+1);
+ file.Format(fmt, nItem+1, m_list.GetItemText(nItem, COL_NAME));
+ CSize filesize = pDC->GetTextExtent(file);
+ while(3+filesize.cx+6 > timept.x && file.GetLength() > 3)
+ {
+ file = file.Left(file.GetLength()-4) + _T("...");
+ filesize = pDC->GetTextExtent(file);
+ }
+
+ if(file.GetLength() > 3)
+ {
+ pDC->SetTextColor(textcolor);
+ pDC->TextOut(rcItem.left+3, (rcItem.top+rcItem.bottom-filesize.cy)/2, file);
+ }
+}
+
+BOOL CPlayerPlaylistBar::OnFileClosePlaylist(UINT nID)
+{
+ Empty();
+ return FALSE;
+}
+
+BOOL CPlayerPlaylistBar::OnPlayPlay(UINT nID)
+{
+ m_list.Invalidate();
+ return FALSE;
+}
+
+void CPlayerPlaylistBar::OnDropFiles(HDROP hDropInfo)
+{
+ SetActiveWindow();
+
+ CAtlList<CString> sl;
+
+ UINT nFiles = ::DragQueryFile(hDropInfo, (UINT)-1, NULL, 0);
+ for(UINT iFile = 0; iFile < nFiles; iFile++)
+ {
+ TCHAR szFileName[_MAX_PATH];
+ ::DragQueryFile(hDropInfo, iFile, szFileName, _MAX_PATH);
+ sl.AddTail(szFileName);
+ }
+ ::DragFinish(hDropInfo);
+
+ Append(sl, true);
+}
+
+void CPlayerPlaylistBar::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ ModifyStyle(WS_EX_ACCEPTFILES, 0);
+
+ m_nDragIndex = ((LPNMLISTVIEW)pNMHDR)->iItem;
+
+ CPoint p(0, 0);
+ m_pDragImage = m_list.CreateDragImageEx(&p);
+
+ CPoint p2 = ((LPNMLISTVIEW)pNMHDR)->ptAction;
+
+ m_pDragImage->BeginDrag(0, p2 - p);
+ m_pDragImage->DragEnter(GetDesktopWindow(), ((LPNMLISTVIEW)pNMHDR)->ptAction);
+
+ m_bDragging = TRUE;
+ m_nDropIndex = -1;
+
+ SetCapture();
+}
+
+void CPlayerPlaylistBar::OnMouseMove(UINT nFlags, CPoint point)
+{
+ if(m_bDragging)
+ {
+ m_ptDropPoint = point;
+ ClientToScreen(&m_ptDropPoint);
+
+ m_pDragImage->DragMove(m_ptDropPoint);
+ m_pDragImage->DragShowNolock(FALSE);
+
+ WindowFromPoint(m_ptDropPoint)->ScreenToClient(&m_ptDropPoint);
+
+ m_pDragImage->DragShowNolock(TRUE);
+
+ {
+ int iOverItem = m_list.HitTest(m_ptDropPoint);
+ int iTopItem = m_list.GetTopIndex();
+ int iBottomItem = m_list.GetBottomIndex();
+
+ if(iOverItem == iTopItem && iTopItem != 0) // top of list
+ SetTimer(1, 100, NULL);
+ else
+ KillTimer(1);
+
+ if(iOverItem >= iBottomItem && iBottomItem != (m_list.GetItemCount() - 1)) // bottom of list
+ SetTimer(2, 100, NULL);
+ else
+ KillTimer(2);
+ }
+ }
+
+ __super::OnMouseMove(nFlags, point);
+}
+
+void CPlayerPlaylistBar::OnTimer(UINT nIDEvent)
+{
+ int iTopItem = m_list.GetTopIndex();
+ int iBottomItem = iTopItem + m_list.GetCountPerPage() - 1;
+
+ if(m_bDragging)
+ {
+ m_pDragImage->DragShowNolock(FALSE);
+
+ if(nIDEvent == 1)
+ {
+ m_list.EnsureVisible(iTopItem - 1, false);
+ m_list.UpdateWindow();
+ if(m_list.GetTopIndex() == 0) KillTimer(1);
+ }
+ else if(nIDEvent == 2)
+ {
+ m_list.EnsureVisible(iBottomItem + 1, false);
+ m_list.UpdateWindow();
+ if(m_list.GetBottomIndex() == (m_list.GetItemCount() - 1)) KillTimer(2);
+ }
+
+ m_pDragImage->DragShowNolock(TRUE);
+ }
+
+ __super::OnTimer(nIDEvent);
+}
+
+void CPlayerPlaylistBar::OnLButtonUp(UINT nFlags, CPoint point)
+{
+ if(m_bDragging)
+ {
+ ::ReleaseCapture();
+
+ m_bDragging = FALSE;
+ m_pDragImage->DragLeave(GetDesktopWindow());
+ m_pDragImage->EndDrag();
+
+ delete m_pDragImage;
+ m_pDragImage = NULL;
+
+ KillTimer(1);
+ KillTimer(2);
+
+ CPoint pt(point);
+ ClientToScreen(&pt);
+
+ if(WindowFromPoint(pt) == &m_list)
+ DropItemOnList();
+ }
+
+ ModifyStyle(0, WS_EX_ACCEPTFILES);
+
+ __super::OnLButtonUp(nFlags, point);
+}
+
+void CPlayerPlaylistBar::DropItemOnList()
+{
+ m_ptDropPoint.y += 10; //
+ m_nDropIndex = m_list.HitTest(CPoint(10, m_ptDropPoint.y));
+
+ TCHAR szLabel[MAX_PATH];
+ LV_ITEM lvi;
+ ZeroMemory(&lvi, sizeof(LV_ITEM));
+ lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
+ lvi.stateMask = LVIS_DROPHILITED | LVIS_FOCUSED | LVIS_SELECTED;
+ lvi.pszText = szLabel;
+ lvi.iItem = m_nDragIndex;
+ lvi.cchTextMax = MAX_PATH;
+ m_list.GetItem(&lvi);
+
+ if(m_nDropIndex < 0) m_nDropIndex = m_list.GetItemCount();
+ lvi.iItem = m_nDropIndex;
+ m_list.InsertItem(&lvi);
+
+ CHeaderCtrl* pHeader = (CHeaderCtrl*)m_list.GetDlgItem(0);
+ int nColumnCount = pHeader->GetItemCount();
+ lvi.mask = LVIF_TEXT;
+ lvi.iItem = m_nDropIndex;
+ //INDEX OF DRAGGED ITEM WILL CHANGE IF ITEM IS DROPPED ABOVE ITSELF
+ if(m_nDropIndex < m_nDragIndex) m_nDragIndex++;
+ for(int col=1; col < nColumnCount; col++)
+ {
+ _tcscpy(lvi.pszText, (LPCTSTR)(m_list.GetItemText(m_nDragIndex, col)));
+ lvi.iSubItem = col;
+ m_list.SetItem(&lvi);
+ }
+
+ m_list.DeleteItem(m_nDragIndex);
+
+ CList<CPlaylistItem> tmp;
+ UINT id = -1;
+ for(int i = 0; i < m_list.GetItemCount(); i++)
+ {
+ POSITION pos = (POSITION)m_list.GetItemData(i);
+ CPlaylistItem& pli = m_pl.GetAt(pos);
+ tmp.AddTail(pli);
+ if(pos == m_pl.GetPos()) id = pli.m_id;
+ }
+ m_pl.RemoveAll();
+ POSITION pos = tmp.GetHeadPosition();
+ for(int i = 0; pos; i++)
+ {
+ CPlaylistItem& pli = tmp.GetNext(pos);
+ m_pl.AddTail(pli);
+ if(pli.m_id == id) m_pl.SetPos(m_pl.GetTailPosition());
+ m_list.SetItemData(i, (DWORD_PTR)m_pl.GetTailPosition());
+ }
+
+ ResizeListColumn();
+}
+
+BOOL CPlayerPlaylistBar::OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
+{
+ TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
+ TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
+
+ if((pNMHDR->code == TTN_NEEDTEXTA && (HWND)pTTTA->lParam != m_list.m_hWnd)
+ || (pNMHDR->code == TTN_NEEDTEXTW && (HWND)pTTTW->lParam != m_list.m_hWnd))
+ return FALSE;
+
+ int row = ((pNMHDR->idFrom-1) >> 10) & 0x3fffff;
+ int col = (pNMHDR->idFrom-1) & 0x3ff;
+
+ if(row < 0 || row >= m_pl.GetCount())
+ return FALSE;
+
+ CPlaylistItem& pli = m_pl.GetAt(FindPos(row));
+
+ CString strTipText;
+
+ if(col == COL_NAME)
+ {
+ POSITION pos = pli.m_fns.GetHeadPosition();
+ while(pos) strTipText += _T("\n") + pli.m_fns.GetNext(pos);
+ strTipText.Trim();
+
+ if(pli.m_type == CPlaylistItem::device)
+ {
+ CString str;
+ str.Format(_T("Video Input %d"), pli.m_vinput);
+ if(pli.m_vinput >= 0) strTipText += _T("\n") + str;
+ str.Format(_T("Video Channel %d"), pli.m_vchannel);
+ if(pli.m_vchannel >= 0) strTipText += _T("\n") + str;
+ str.Format(_T("Audio Input %d"), pli.m_ainput);
+ if(pli.m_ainput >= 0) strTipText += _T("\n") + str;
+ }
+
+ ::SendMessage(pNMHDR->hwndFrom, TTM_SETMAXTIPWIDTH, 0, (LPARAM)(INT)1000);
+ }
+ else if(col == COL_TIME)
+ {
+ return FALSE;
+ }
+
+ static CStringA m_strTipTextA;
+ static CStringW m_strTipTextW;
+
+ if(pNMHDR->code == TTN_NEEDTEXTA)
+ {
+ m_strTipTextA = strTipText;
+ pTTTA->lpszText = (LPSTR)(LPCSTR)m_strTipTextA;
+ }
+ else
+ {
+ m_strTipTextW = strTipText;
+ pTTTW->lpszText = (LPWSTR)(LPCWSTR)m_strTipTextW;
+ }
+
+ *pResult = 0;
+
+ return TRUE; // message was handled
+}
+
+void CPlayerPlaylistBar::OnContextMenu(CWnd* /*pWnd*/, CPoint p)
+{
+ LVHITTESTINFO lvhti;
+ lvhti.pt = p;
+ m_list.ScreenToClient(&lvhti.pt);
+ m_list.SubItemHitTest(&lvhti);
+
+ POSITION pos = FindPos(lvhti.iItem);
+// bool fSelected = (pos == m_pl.GetPos());
+ bool fOnItem = !!(lvhti.flags&LVHT_ONITEM);
+
+ CMenu m;
+ m.CreatePopupMenu();
+
+ enum
+ {
+ M_OPEN=1, M_ADD, M_REMOVE, M_CLIPBOARD, M_SAVEAS,
+ M_SORTBYNAME, M_SORTBYPATH, M_RANDOMIZE, M_SORTBYID,
+ M_REMEMBERPLAYLIST, M_SHUFFLE
+ };
+
+ m.AppendMenu(MF_STRING|(!fOnItem?(MF_DISABLED|MF_GRAYED):MF_ENABLED), M_OPEN, ResStr(IDS_PLAYLIST_OPEN));
+ if(((CMainFrame*)AfxGetMainWnd())->m_iPlaybackMode == PM_CAPTURE) m.AppendMenu(MF_STRING|MF_ENABLED, M_ADD, ResStr(IDS_PLAYLIST_ADD));
+ m.AppendMenu(MF_STRING|(/*fSelected||*/!fOnItem?(MF_DISABLED|MF_GRAYED):MF_ENABLED), M_REMOVE, ResStr(IDS_PLAYLIST_REMOVE));
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING|(!fOnItem?(MF_DISABLED|MF_GRAYED):MF_ENABLED), M_CLIPBOARD, ResStr(IDS_PLAYLIST_COPYTOCLIPBOARD));
+ m.AppendMenu(MF_STRING|(!m_pl.GetCount()?(MF_DISABLED|MF_GRAYED):MF_ENABLED), M_SAVEAS, ResStr(IDS_PLAYLIST_SAVEAS));
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING|(!m_pl.GetCount()?(MF_DISABLED|MF_GRAYED):MF_ENABLED), M_SORTBYNAME, ResStr(IDS_PLAYLIST_SORTBYLABEL));
+ m.AppendMenu(MF_STRING|(!m_pl.GetCount()?(MF_DISABLED|MF_GRAYED):MF_ENABLED), M_SORTBYPATH, ResStr(IDS_PLAYLIST_SORTBYPATH));
+ m.AppendMenu(MF_STRING|(!m_pl.GetCount()?(MF_DISABLED|MF_GRAYED):MF_ENABLED), M_RANDOMIZE, ResStr(IDS_PLAYLIST_RANDOMIZE));
+ m.AppendMenu(MF_STRING|(!m_pl.GetCount()?(MF_DISABLED|MF_GRAYED):MF_ENABLED), M_SORTBYID, ResStr(IDS_PLAYLIST_RESTORE));
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING|MF_ENABLED|(AfxGetApp()->GetProfileInt(ResStr(IDS_R_SETTINGS), _T("ShufflePlaylistItems"), FALSE)?MF_CHECKED:0), M_SHUFFLE, ResStr(IDS_PLAYLIST_SHUFFLE));
+ m.AppendMenu(MF_STRING|MF_ENABLED|(AfxGetApp()->GetProfileInt(ResStr(IDS_R_SETTINGS), _T("RememberPlaylistItems"), TRUE)?MF_CHECKED:0), M_REMEMBERPLAYLIST, ResStr(IDS_PLAYLIST_REMEBERITEMS));
+
+ CMainFrame* pMainFrm = (CMainFrame*)AfxGetMainWnd();
+
+ int nID = (int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this);
+ switch(nID)
+ {
+ case M_OPEN:
+ m_pl.SetPos(pos);
+ m_list.Invalidate();
+ pMainFrm->OpenCurPlaylistItem();
+ break;
+ case M_ADD:
+ pMainFrm->AddCurDevToPlaylist();
+ m_pl.SetPos(m_pl.GetTailPosition());
+ break;
+ case M_REMOVE:
+ if(m_pl.RemoveAt(pos)) pMainFrm->CloseMedia();
+ m_list.DeleteItem(lvhti.iItem);
+ SavePlaylist();
+ break;
+ case M_SORTBYID:
+ m_pl.SortById();
+ SetupList();
+ SavePlaylist();
+ break;
+ case M_SORTBYNAME:
+ m_pl.SortByName();
+ SetupList();
+ SavePlaylist();
+ break;
+ case M_SORTBYPATH:
+ m_pl.SortByPath();
+ SetupList();
+ SavePlaylist();
+ break;
+ case M_RANDOMIZE:
+ m_pl.Randomize();
+ SetupList();
+ SavePlaylist();
+ break;
+ case M_CLIPBOARD:
+ if(OpenClipboard() && EmptyClipboard())
+ {
+ CString str;
+
+ CPlaylistItem& pli = m_pl.GetAt(pos);
+ POSITION pos = pli.m_fns.GetHeadPosition();
+ while(pos) str += _T("\r\n") + pli.m_fns.GetNext(pos);
+ str.Trim();
+
+ if(HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, (str.GetLength()+1)*sizeof(TCHAR)))
+ {
+ if(TCHAR* s = (TCHAR*)GlobalLock(h))
+ {
+ _tcscpy(s, str);
+ GlobalUnlock(h);
+#ifdef UNICODE
+ SetClipboardData(CF_UNICODETEXT, h);
+#else
+ SetClipboardData(CF_TEXT, h);
+#endif
+ }
+ }
+ CloseClipboard();
+ }
+ break;
+ case M_SAVEAS:
+ {
+ CSaveTextFileDialog fd(
+ CTextFile::ASCII, NULL, NULL,
+ _T("Media Player Classic playlist (*.mpcpl)|*.mpcpl|Playlist (*.pls)|*.pls|WinAmp playlist (*.m3u)|*.m3u|Windows Media Playlist (*.asx)|*.asx||"),
+ this);
+
+ if(fd.DoModal() != IDOK)
+ break;
+
+ CTextFile::enc encoding = (CTextFile::enc)fd.GetEncoding();
+ if(encoding == CTextFile::ASCII) encoding = CTextFile::ANSI;
+
+ int idx = fd.m_pOFN->nFilterIndex;
+
+ CPath path(fd.GetPathName());
+
+ switch(idx)
+ {
+ case 1: path.AddExtension(_T(".mpcpl")); break;
+ case 2: path.AddExtension(_T(".pls")); break;
+ case 3: path.AddExtension(_T(".m3u")); break;
+ case 4: path.AddExtension(_T(".asx")); break;
+ default: break;
+ }
+
+ bool fRemovePath = true;
+
+ CPath p(path);
+ p.RemoveFileSpec();
+ CString base = (LPCTSTR)p;
+
+ pos = m_pl.GetHeadPosition();
+ while(pos && fRemovePath)
+ {
+ CPlaylistItem& pli = m_pl.GetNext(pos);
+
+ if(pli.m_type != CPlaylistItem::file) fRemovePath = false;
+ else
+ {
+ POSITION pos;
+
+ pos = pli.m_fns.GetHeadPosition();
+ while(pos && fRemovePath)
+ {
+ CString fn = pli.m_fns.GetNext(pos);
+
+ CPath p(fn);
+ p.RemoveFileSpec();
+ if(base != (LPCTSTR)p) fRemovePath = false;
+ }
+
+ pos = pli.m_subs.GetHeadPosition();
+ while(pos && fRemovePath)
+ {
+ CString fn = pli.m_subs.GetNext(pos);
+
+ CPath p(fn);
+ p.RemoveFileSpec();
+ if(base != (LPCTSTR)p) fRemovePath = false;
+ }
+ }
+ }
+
+ if(idx == 1)
+ {
+ SaveMPCPlayList(path, encoding, fRemovePath);
+ break;
+ }
+
+ CTextFile f;
+ if(!f.Save(path, encoding))
+ break;
+
+ if(idx == 4)
+ {
+ f.WriteString(_T("<ASX version = \"3.0\">\n"));
+ }
+
+ pos = m_pl.GetHeadPosition();
+ for(int i = 0; pos; i++)
+ {
+ CPlaylistItem& pli = m_pl.GetNext(pos);
+
+ if(pli.m_type != CPlaylistItem::file)
+ continue;
+
+ CString fn = pli.m_fns.GetHead();
+
+ /*
+ if(fRemovePath)
+ {
+ CPath p(path);
+ p.StripPath();
+ fn = (LPCTSTR)p;
+ }
+ */
+
+ CString str;
+ switch(idx)
+ {
+ case 2: str.Format(_T("File%d=%s\n"), i+1, fn); break;
+ case 3: str.Format(_T("%s\n"), fn); break;
+ case 4: str.Format(_T("<Entry><Ref href = \"%s\"/></Entry>\n"), fn); break;
+ default: break;
+ }
+ f.WriteString(str);
+ }
+
+ if(idx == 4)
+ {
+ f.WriteString(_T("</ASX>\n"));
+ }
+ }
+ break;
+ case M_REMEMBERPLAYLIST:
+ AfxGetApp()->WriteProfileInt(ResStr(IDS_R_SETTINGS), _T("RememberPlaylistItems"),
+ !AfxGetApp()->GetProfileInt(ResStr(IDS_R_SETTINGS), _T("RememberPlaylistItems"), TRUE));
+ break;
+ case M_SHUFFLE:
+ AfxGetApp()->WriteProfileInt(ResStr(IDS_R_SETTINGS), _T("ShufflePlaylistItems"),
+ !AfxGetApp()->GetProfileInt(ResStr(IDS_R_SETTINGS), _T("ShufflePlaylistItems"), FALSE));
+ break;
+ default:
+ break;
+ }
+}
+
+void CPlayerPlaylistBar::OnLvnEndlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ NMLVDISPINFO* pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
+
+ if(pDispInfo->item.iItem >= 0 && pDispInfo->item.pszText)
+ {
+ CPlaylistItem& pli = m_pl.GetAt((POSITION)m_list.GetItemData(pDispInfo->item.iItem));
+ pli.m_label = pDispInfo->item.pszText;
+ m_list.SetItemText(pDispInfo->item.iItem, 0, pDispInfo->item.pszText);
+ }
+
+ *pResult = 0;
+}
diff --git a/src/apps/mplayerc/PlayerPlaylistBar.h b/src/apps/mplayerc/PlayerPlaylistBar.h
new file mode 100644
index 000000000..56c7021d9
--- /dev/null
+++ b/src/apps/mplayerc/PlayerPlaylistBar.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include <afxcoll.h>
+#include "PlayerListCtrl.h"
+#include "Playlist.h"
+
+class OpenMediaData;
+
+class CPlayerPlaylistBar : public CSizingControlBarG
+{
+ DECLARE_DYNAMIC(CPlayerPlaylistBar)
+
+private:
+ enum {COL_NAME, COL_TIME};
+
+ CImageList m_fakeImageList;
+ CPlayerListCtrl m_list;
+
+ int m_nTimeColWidth;
+ void ResizeListColumn();
+
+ void AddItem(CString fn, CAtlList<CString>* subs);
+ void AddItem(CAtlList<CString>& fns, CAtlList<CString>* subs);
+ void ParsePlayList(CString fn, CAtlList<CString>* subs);
+ void ParsePlayList(CAtlList<CString>& fns, CAtlList<CString>* subs);
+
+ bool ParseMPCPlayList(CString fn);
+ bool SaveMPCPlayList(CString fn, CTextFile::enc e, bool fRemovePath);
+
+ void SetupList();
+ void UpdateList();
+ void EnsureVisible(POSITION pos);
+ int FindItem(POSITION pos);
+ POSITION FindPos(int i);
+
+ CImageList* m_pDragImage;
+ BOOL m_bDragging;
+ int m_nDragIndex, m_nDropIndex;
+ CPoint m_ptDropPoint;
+
+ void DropItemOnList();
+
+public:
+ CPlayerPlaylistBar();
+ virtual ~CPlayerPlaylistBar();
+
+ BOOL Create(CWnd* pParentWnd);
+
+ CPlaylist m_pl;
+
+ int GetCount();
+ int GetSelIdx();
+ void SetSelIdx(int i);
+ bool IsAtEnd();
+ bool GetCur(CPlaylistItem& pli);
+ CString GetCur();
+ void SetNext(), SetPrev(), SetFirst(), SetLast();
+ void SetCurValid(bool fValid);
+ void SetCurTime(REFERENCE_TIME rt);
+
+ void Refresh();
+ void Empty();
+
+ void Open(CAtlList<CString>& fns, bool fMulti, CAtlList<CString>* subs = NULL);
+ void Append(CAtlList<CString>& fns, bool fMulti, CAtlList<CString>* subs = NULL);
+
+ void Open(CStringW vdn, CStringW adn, int vinput, int vchannel, int ainput);
+ void Append(CStringW vdn, CStringW adn, int vinput, int vchannel, int ainput);
+
+ OpenMediaData* GetCurOMD(REFERENCE_TIME rtStart = 0);
+
+ void LoadPlaylist();
+ void SavePlaylist();
+
+protected:
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnLvnKeyDown(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnNMDblclkList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnLvnKeydownList(NMHDR* pNMHDR, LRESULT* pResult);
+// afx_msg void OnCustomdrawList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
+ afx_msg BOOL OnFileClosePlaylist(UINT nID);
+ afx_msg BOOL OnPlayPlay(UINT nID);
+ afx_msg void OnDropFiles(HDROP hDropInfo);
+ afx_msg void OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+ afx_msg BOOL OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnTimer(UINT nIDEvent);
+ afx_msg void OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/);
+ afx_msg void OnLvnEndlabeleditList(NMHDR* pNMHDR, LRESULT* pResult);
+};
diff --git a/src/apps/mplayerc/PlayerSeekBar.cpp b/src/apps/mplayerc/PlayerSeekBar.cpp
new file mode 100644
index 000000000..b8efe5e44
--- /dev/null
+++ b/src/apps/mplayerc/PlayerSeekBar.cpp
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PlayerSeekBar.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PlayerSeekBar.h"
+
+// CPlayerSeekBar
+
+IMPLEMENT_DYNAMIC(CPlayerSeekBar, CDialogBar)
+
+CPlayerSeekBar::CPlayerSeekBar() :
+ m_start(0), m_stop(100), m_pos(0), m_posreal(0),
+ m_fEnabled(false)
+{
+}
+
+CPlayerSeekBar::~CPlayerSeekBar()
+{
+}
+
+BOOL CPlayerSeekBar::Create(CWnd* pParentWnd)
+{
+ if(!CDialogBar::Create(pParentWnd, IDD_PLAYERSEEKBAR, WS_CHILD|WS_VISIBLE|CBRS_ALIGN_BOTTOM, IDD_PLAYERSEEKBAR))
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL CPlayerSeekBar::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if(!CDialogBar::PreCreateWindow(cs))
+ return FALSE;
+
+ m_dwStyle &= ~CBRS_BORDER_TOP;
+ m_dwStyle &= ~CBRS_BORDER_BOTTOM;
+ m_dwStyle |= CBRS_SIZE_FIXED;
+
+ return TRUE;
+}
+
+void CPlayerSeekBar::Enable(bool fEnable)
+{
+ m_fEnabled = fEnable;
+ Invalidate();
+}
+
+void CPlayerSeekBar::GetRange(__int64& start, __int64& stop)
+{
+ start = m_start;
+ stop = m_stop;
+}
+
+void CPlayerSeekBar::SetRange(__int64 start, __int64 stop)
+{
+ if(start > stop) start ^= stop, stop ^= start, start ^= stop;
+ m_start = start;
+ m_stop = stop;
+ if(m_pos < m_start || m_pos >= m_stop) SetPos(m_start);
+}
+
+__int64 CPlayerSeekBar::GetPos()
+{
+ return(m_pos);
+}
+
+__int64 CPlayerSeekBar::GetPosReal()
+{
+ return(m_posreal);
+}
+
+void CPlayerSeekBar::SetPos(__int64 pos)
+{
+ CWnd* w = GetCapture();
+ if(w && w->m_hWnd == m_hWnd) return;
+
+ SetPosInternal(pos);
+}
+
+void CPlayerSeekBar::SetPosInternal(__int64 pos)
+{
+ if(m_pos == pos) return;
+
+ CRect before = GetThumbRect();
+ m_pos = min(max(pos, m_start), m_stop);
+ m_posreal = pos;
+ CRect after = GetThumbRect();
+
+ if(before != after) InvalidateRect(before | after);
+}
+
+CRect CPlayerSeekBar::GetChannelRect()
+{
+ CRect r;
+ GetClientRect(&r);
+ r.DeflateRect(8, 9, 9, 0);
+ r.bottom = r.top + 5;
+ return(r);
+}
+
+CRect CPlayerSeekBar::GetThumbRect()
+{
+// bool fEnabled = m_fEnabled || m_start >= m_stop;
+
+ CRect r = GetChannelRect();
+
+ int x = r.left + (int)((m_start < m_stop /*&& fEnabled*/) ? (__int64)r.Width() * (m_pos - m_start) / (m_stop - m_start) : 0);
+ int y = r.CenterPoint().y;
+
+ r.SetRect(x, y, x, y);
+ r.InflateRect(6, 7, 7, 8);
+
+ return(r);
+}
+
+CRect CPlayerSeekBar::GetInnerThumbRect()
+{
+ CRect r = GetThumbRect();
+
+ bool fEnabled = m_fEnabled && m_start < m_stop;
+ r.DeflateRect(3, fEnabled ? 5 : 4, 3, fEnabled ? 5 : 4);
+
+ return(r);
+}
+
+void CPlayerSeekBar::MoveThumb(CPoint point)
+{
+ CRect r = GetChannelRect();
+
+ if(r.left >= r.right) return;
+
+ if(point.x < r.left) SetPos(m_start);
+ else if(point.x >= r.right) SetPos(m_stop);
+ else
+ {
+ __int64 w = r.right - r.left;
+ if(m_start < m_stop)
+ SetPosInternal(m_start + ((m_stop - m_start) * (point.x - r.left) + (w/2)) / w);
+ }
+}
+
+BEGIN_MESSAGE_MAP(CPlayerSeekBar, CDialogBar)
+ //{{AFX_MSG_MAP(CPlayerSeekBar)
+ ON_WM_PAINT()
+ ON_WM_SIZE()
+ ON_WM_LBUTTONDOWN()
+ ON_WM_LBUTTONUP()
+ ON_WM_MOUSEMOVE()
+ ON_WM_ERASEBKGND()
+ //}}AFX_MSG_MAP
+ ON_COMMAND_EX(ID_PLAY_STOP, OnPlayStop)
+END_MESSAGE_MAP()
+
+
+// CPlayerSeekBar message handlers
+
+void CPlayerSeekBar::OnPaint()
+{
+ CPaintDC dc(this); // device context for painting
+
+ bool fEnabled = m_fEnabled && m_start < m_stop;
+
+ COLORREF
+ white = GetSysColor(COLOR_WINDOW),
+ shadow = GetSysColor(COLOR_3DSHADOW),
+ light = GetSysColor(COLOR_3DHILIGHT),
+ bkg = GetSysColor(COLOR_BTNFACE);
+
+ // thumb
+ {
+ CRect r = GetThumbRect(), r2 = GetInnerThumbRect();
+ CRect rt = r, rit = r2;
+
+ dc.Draw3dRect(&r, light, 0);
+ r.DeflateRect(0, 0, 1, 1);
+ dc.Draw3dRect(&r, light, shadow);
+ r.DeflateRect(1, 1, 1, 1);
+
+ CBrush b(bkg);
+
+ dc.FrameRect(&r, &b);
+ r.DeflateRect(0, 1, 0, 1);
+ dc.FrameRect(&r, &b);
+
+ r.DeflateRect(1, 1, 0, 0);
+ dc.Draw3dRect(&r, shadow, bkg);
+
+ if(fEnabled)
+ {
+ r.DeflateRect(1, 1, 1, 2);
+ CPen white(PS_INSIDEFRAME, 1, white);
+ CPen* old = dc.SelectObject(&white);
+ dc.MoveTo(r.left, r.top);
+ dc.LineTo(r.right, r.top);
+ dc.MoveTo(r.left, r.bottom);
+ dc.LineTo(r.right, r.bottom);
+ dc.SelectObject(old);
+ dc.SetPixel(r.CenterPoint().x, r.top, 0);
+ dc.SetPixel(r.CenterPoint().x, r.bottom, 0);
+ }
+
+ dc.SetPixel(r.CenterPoint().x+5, r.top-4, bkg);
+
+ {
+ CRgn rgn1, rgn2;
+ rgn1.CreateRectRgnIndirect(&rt);
+ rgn2.CreateRectRgnIndirect(&rit);
+ ExtSelectClipRgn(dc, rgn1, RGN_DIFF);
+ ExtSelectClipRgn(dc, rgn2, RGN_OR);
+ }
+ }
+
+ // channel
+ {
+ CRect r = GetChannelRect();
+
+ dc.FillSolidRect(&r, fEnabled ? white : bkg);
+ r.InflateRect(1, 1);
+ dc.Draw3dRect(&r, shadow, light);
+ dc.ExcludeClipRect(&r);
+ }
+
+ // background
+ {
+ CRect r;
+ GetClientRect(&r);
+ CBrush b(bkg);
+ dc.FillRect(&r, &b);
+ }
+
+
+ // Do not call CDialogBar::OnPaint() for painting messages
+}
+
+
+void CPlayerSeekBar::OnSize(UINT nType, int cx, int cy)
+{
+ CDialogBar::OnSize(nType, cx, cy);
+
+ Invalidate();
+}
+
+void CPlayerSeekBar::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ if(m_fEnabled && (GetChannelRect() | GetThumbRect()).PtInRect(point))
+ {
+ SetCapture();
+ MoveThumb(point);
+ GetParent()->PostMessage(WM_HSCROLL, MAKEWPARAM((short)m_pos, SB_THUMBPOSITION), (LPARAM)m_hWnd);
+ }
+
+ CDialogBar::OnLButtonDown(nFlags, point);
+}
+
+void CPlayerSeekBar::OnLButtonUp(UINT nFlags, CPoint point)
+{
+ ReleaseCapture();
+
+ CDialogBar::OnLButtonUp(nFlags, point);
+}
+
+void CPlayerSeekBar::OnMouseMove(UINT nFlags, CPoint point)
+{
+ CWnd* w = GetCapture();
+ if(w && w->m_hWnd == m_hWnd && (nFlags & MK_LBUTTON))
+ {
+ MoveThumb(point);
+ GetParent()->PostMessage(WM_HSCROLL, MAKEWPARAM((short)m_pos, SB_THUMBTRACK), (LPARAM)m_hWnd);
+ }
+
+ CDialogBar::OnMouseMove(nFlags, point);
+}
+
+BOOL CPlayerSeekBar::OnEraseBkgnd(CDC* pDC)
+{
+ return TRUE;
+}
+
+BOOL CPlayerSeekBar::OnPlayStop(UINT nID)
+{
+ SetPos(0);
+ return FALSE;
+}
diff --git a/src/apps/mplayerc/PlayerSeekBar.h b/src/apps/mplayerc/PlayerSeekBar.h
new file mode 100644
index 000000000..7919232b5
--- /dev/null
+++ b/src/apps/mplayerc/PlayerSeekBar.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+// CPlayerSeekBar
+
+class CPlayerSeekBar : public CDialogBar
+{
+ DECLARE_DYNAMIC(CPlayerSeekBar)
+
+private:
+ __int64 m_start, m_stop, m_pos, m_posreal;
+ bool m_fEnabled;
+
+ void MoveThumb(CPoint point);
+ void SetPosInternal(__int64 pos);
+
+ CRect GetChannelRect();
+ CRect GetThumbRect();
+ CRect GetInnerThumbRect();
+
+public:
+ CPlayerSeekBar();
+ virtual ~CPlayerSeekBar();
+
+ void Enable(bool fEnable);
+
+ void GetRange(__int64& start, __int64& stop);
+ void SetRange(__int64 start, __int64 stop);
+ __int64 GetPos(), GetPosReal();
+ void SetPos(__int64 pos);
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CPlayerSeekBar)
+ virtual BOOL Create(CWnd* pParentWnd);
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ //}}AFX_VIRTUAL
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CPlayerSeekBar)
+ afx_msg void OnPaint();
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+public:
+ afx_msg BOOL OnPlayStop(UINT nID);
+};
diff --git a/src/apps/mplayerc/PlayerShaderEditorBar.cpp b/src/apps/mplayerc/PlayerShaderEditorBar.cpp
new file mode 100644
index 000000000..d098dff71
--- /dev/null
+++ b/src/apps/mplayerc/PlayerShaderEditorBar.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PlayerShaderEditorBar.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "PlayerShaderEditorBar.h"
+
+// CPlayerShaderEditorBar
+
+IMPLEMENT_DYNAMIC(CPlayerShaderEditorBar, baseCPlayerShaderEditorBar)
+CPlayerShaderEditorBar::CPlayerShaderEditorBar()
+{
+}
+
+CPlayerShaderEditorBar::~CPlayerShaderEditorBar()
+{
+}
+
+BOOL CPlayerShaderEditorBar::Create(CWnd* pParentWnd)
+{
+ if(!__super::Create(_T("Shader Editor"), pParentWnd, 0))
+ return FALSE;
+
+ m_dlg.Create(this);
+ m_dlg.ShowWindow(SW_SHOWNORMAL);
+
+ CRect r;
+ m_dlg.GetWindowRect(r);
+ m_szMinVert = m_szVert = r.Size();
+ m_szMinHorz = m_szHorz = r.Size();
+ m_szMinFloat = m_szFloat = r.Size();
+ m_bFixedFloat = false;
+
+ return TRUE;
+}
+
+BOOL CPlayerShaderEditorBar::PreTranslateMessage(MSG* pMsg)
+{
+ if(IsWindow(pMsg->hwnd) && IsVisible() && pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
+ {
+ if(IsDialogMessage(pMsg))
+ return TRUE;
+ }
+
+ return __super::PreTranslateMessage(pMsg);
+}
+
+BEGIN_MESSAGE_MAP(CPlayerShaderEditorBar, baseCPlayerShaderEditorBar)
+ ON_WM_SIZE()
+END_MESSAGE_MAP()
+
+// CPlayerShaderEditorBar message handlers
+
+void CPlayerShaderEditorBar::OnSize(UINT nType, int cx, int cy)
+{
+ __super::OnSize(nType, cx, cy);
+
+ if(::IsWindow(m_dlg.m_hWnd))
+ {
+ CRect r;
+ GetClientRect(r);
+ m_dlg.MoveWindow(r);
+ }
+} \ No newline at end of file
diff --git a/src/apps/mplayerc/PlayerShaderEditorBar.h b/src/apps/mplayerc/PlayerShaderEditorBar.h
new file mode 100644
index 000000000..5db9d5f0a
--- /dev/null
+++ b/src/apps/mplayerc/PlayerShaderEditorBar.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "ShaderEditorDlg.h"
+
+#ifndef baseCPlayerShaderEditorBar
+#define baseCPlayerShaderEditorBar CSizingControlBarG
+#endif
+
+// CPlayerShaderEditorBar
+
+class CPlayerShaderEditorBar : public baseCPlayerShaderEditorBar
+{
+ DECLARE_DYNAMIC(CPlayerShaderEditorBar)
+
+public:
+ CPlayerShaderEditorBar();
+ virtual ~CPlayerShaderEditorBar();
+
+ BOOL Create(CWnd* pParentWnd);
+
+public:
+ CShaderEditorDlg m_dlg;
+
+protected:
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+};
diff --git a/src/apps/mplayerc/PlayerStatusBar.cpp b/src/apps/mplayerc/PlayerStatusBar.cpp
new file mode 100644
index 000000000..18240774b
--- /dev/null
+++ b/src/apps/mplayerc/PlayerStatusBar.cpp
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PlayerStatusBar.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PlayerStatusBar.h"
+#include "MainFrm.h"
+#include "..\..\DSUtil\DSUtil.h"
+
+// CPlayerStatusBar
+
+IMPLEMENT_DYNAMIC(CPlayerStatusBar, CDialogBar)
+
+CPlayerStatusBar::CPlayerStatusBar()
+ : m_status(false, false)
+ , m_time(true, false)
+ , m_bmid(0)
+ , m_hIcon(0)
+{
+}
+
+CPlayerStatusBar::~CPlayerStatusBar()
+{
+ if(m_hIcon) DestroyIcon(m_hIcon);
+}
+
+BOOL CPlayerStatusBar::Create(CWnd* pParentWnd)
+{
+ return CDialogBar::Create(pParentWnd, IDD_PLAYERSTATUSBAR, WS_CHILD|WS_VISIBLE|CBRS_ALIGN_BOTTOM, IDD_PLAYERSTATUSBAR);
+}
+
+BOOL CPlayerStatusBar::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if(!CDialogBar::PreCreateWindow(cs))
+ return FALSE;
+
+ m_dwStyle &= ~CBRS_BORDER_TOP;
+ m_dwStyle &= ~CBRS_BORDER_BOTTOM;
+
+ return TRUE;
+}
+
+int CPlayerStatusBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if(CDialogBar::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ CRect r;
+ r.SetRectEmpty();
+
+ m_type.Create(_T(""), WS_CHILD|WS_VISIBLE|SS_ICON,
+ r, this, IDC_STATIC1);
+
+ m_status.Create(_T(""), WS_CHILD|WS_VISIBLE|SS_OWNERDRAW,
+ r, this, IDC_PLAYERSTATUS);
+
+ m_time.Create(_T(""), WS_CHILD|WS_VISIBLE|SS_OWNERDRAW,
+ r, this, IDC_PLAYERTIME);
+
+ m_status.SetWindowPos(&m_time, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+
+ Relayout();
+
+ return 0;
+}
+
+void CPlayerStatusBar::Relayout()
+{
+ BITMAP bm;
+ memset(&bm, 0, sizeof(bm));
+ if(m_bm.m_hObject) m_bm.GetBitmap(&bm);
+
+ CRect r, r2;
+ GetClientRect(r);
+
+ r.DeflateRect(27, 5, bm.bmWidth + 8, 4);
+ int div = r.right - (m_time.IsWindowVisible() ? 140 : 0);
+
+ CString str;
+ m_time.GetWindowText(str);
+ if(CDC* pDC = m_time.GetDC())
+ {
+ CFont* pOld = pDC->SelectObject(&m_time.GetFont());
+ div = r.right - pDC->GetTextExtent(str).cx;
+ pDC->SelectObject(pOld);
+ m_time.ReleaseDC(pDC);
+ }
+
+ r2 = r;
+ r2.right = div - 2;
+ m_status.MoveWindow(&r2);
+
+ r2 = r;
+ r2.left = div;
+ m_time.MoveWindow(&r2);
+
+ GetClientRect(r);
+ r.SetRect(6, r.top+4, 22, r.bottom-4);
+ m_type.MoveWindow(r);
+
+ Invalidate();
+}
+
+void CPlayerStatusBar::Clear()
+{
+ m_status.SetWindowText(_T(""));
+ m_time.SetWindowText(_T(""));
+ SetStatusBitmap(0);
+ SetStatusTypeIcon(0);
+
+ Relayout();
+}
+
+void CPlayerStatusBar::SetStatusBitmap(UINT id)
+{
+ if(m_bmid == id) return;
+
+ if(m_bm.m_hObject) m_bm.DeleteObject();
+ if(id) m_bm.LoadBitmap(id);
+ m_bmid = id;
+
+ Relayout();
+}
+
+void CPlayerStatusBar::SetStatusTypeIcon(HICON hIcon)
+{
+ if(m_hIcon == hIcon) return;
+
+ if(m_hIcon) DestroyIcon(m_hIcon);
+ m_type.SetIcon(m_hIcon = hIcon);
+
+ Relayout();
+}
+
+void CPlayerStatusBar::SetStatusMessage(CString str)
+{
+ str.Trim();
+ m_status.SetWindowText(str);
+}
+
+CString CPlayerStatusBar::GetStatusTimer()
+{
+ CString strResult;
+
+ m_time.GetWindowText(strResult);
+
+ return strResult;
+}
+
+void CPlayerStatusBar::SetStatusTimer(CString str)
+{
+ CString tmp;
+ m_time.GetWindowText(tmp);
+ if(tmp == str) return;
+
+ str.Trim();
+ m_time.SetWindowText(str);
+
+ Relayout();
+}
+
+void CPlayerStatusBar::SetStatusTimer(REFERENCE_TIME rtNow, REFERENCE_TIME rtDur, bool fHighPrecision, const GUID* pTimeFormat)
+{
+ ASSERT(pTimeFormat);
+
+ CString str;
+ CString posstr, durstr;
+
+ if(*pTimeFormat == TIME_FORMAT_MEDIA_TIME)
+ {
+ DVD_HMSF_TIMECODE tcNow = RT2HMSF(rtNow);
+ DVD_HMSF_TIMECODE tcDur = RT2HMSF(rtDur);
+
+ if(tcDur.bHours > 0 || (rtNow >= rtDur && tcNow.bHours > 0))
+ posstr.Format(_T("%02d:%02d:%02d"), tcNow.bHours, tcNow.bMinutes, tcNow.bSeconds);
+ else
+ posstr.Format(_T("%02d:%02d"), tcNow.bMinutes, tcNow.bSeconds);
+
+ if(tcDur.bHours > 0)
+ durstr.Format(_T("%02d:%02d:%02d"), tcDur.bHours, tcDur.bMinutes, tcDur.bSeconds);
+ else
+ durstr.Format(_T("%02d:%02d"), tcDur.bMinutes, tcDur.bSeconds);
+
+ if(fHighPrecision)
+ {
+ str.Format(_T("%s.%03d"), posstr, (rtNow/10000)%1000);
+ posstr = str;
+ str.Format(_T("%s.%03d"), durstr, (rtDur/10000)%1000);
+ durstr = str;
+ str.Empty();
+ }
+ }
+ else if(*pTimeFormat == TIME_FORMAT_FRAME)
+ {
+ posstr.Format(_T("%I64d"), rtNow);
+ durstr.Format(_T("%I64d"), rtDur);
+ }
+
+ str = (/*start <= 0 &&*/ rtDur <= 0) ? posstr : posstr + _T(" / ") + durstr;
+
+ SetStatusTimer(str);
+}
+
+void CPlayerStatusBar::ShowTimer(bool fShow)
+{
+ m_time.ShowWindow(fShow ? SW_SHOW : SW_HIDE);
+
+ Relayout();
+}
+
+BEGIN_MESSAGE_MAP(CPlayerStatusBar, CDialogBar)
+ ON_WM_ERASEBKGND()
+ ON_WM_PAINT()
+ ON_WM_SIZE()
+ ON_WM_CREATE()
+ ON_WM_LBUTTONDOWN()
+ ON_WM_SETCURSOR()
+ ON_WM_CTLCOLOR()
+END_MESSAGE_MAP()
+
+
+// CPlayerStatusBar message handlers
+
+
+BOOL CPlayerStatusBar::OnEraseBkgnd(CDC* pDC)
+{
+ for(CWnd* pChild = GetWindow(GW_CHILD); pChild; pChild = pChild->GetNextWindow())
+ {
+ if(!pChild->IsWindowVisible()) continue;
+
+ CRect r;
+ pChild->GetClientRect(&r);
+ pChild->MapWindowPoints(this, &r);
+ pDC->ExcludeClipRect(&r);
+ }
+
+ CRect r;
+ GetClientRect(&r);
+
+ CMainFrame* pFrame = ((CMainFrame*)GetParentFrame());
+
+ if(pFrame->m_pLastBar != this || pFrame->m_fFullScreen)
+ r.InflateRect(0, 0, 0, 1);
+
+ if(pFrame->m_fFullScreen)
+ r.InflateRect(1, 0, 1, 0);
+
+ pDC->Draw3dRect(&r, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
+
+ r.DeflateRect(1, 1);
+
+ pDC->FillSolidRect(&r, 0);
+
+ return TRUE;
+}
+
+void CPlayerStatusBar::OnPaint()
+{
+ CPaintDC dc(this); // device context for painting
+
+ CRect r;
+
+ if(m_bm.m_hObject)
+ {
+ BITMAP bm;
+ m_bm.GetBitmap(&bm);
+ CDC memdc;
+ memdc.CreateCompatibleDC(&dc);
+ memdc.SelectObject(&m_bm);
+ GetClientRect(&r);
+ dc.BitBlt(r.right-bm.bmWidth-1, (r.Height() - bm.bmHeight)/2, bm.bmWidth, bm.bmHeight, &memdc, 0, 0, SRCCOPY);
+
+ //
+ }
+/*
+ if(m_hIcon)
+ {
+ GetClientRect(&r);
+ r.SetRect(6, r.top+4, 22-1, r.bottom-4-1);
+ DrawIconEx(dc, r.left, r.top, m_hIcon, r.Width(), r.Height(), 0, NULL, DI_NORMAL|DI_COMPAT);
+ }
+*/
+ // Do not call CDialogBar::OnPaint() for painting messages
+}
+
+void CPlayerStatusBar::OnSize(UINT nType, int cx, int cy)
+{
+ CDialogBar::OnSize(nType, cx, cy);
+
+ Relayout();
+}
+
+void CPlayerStatusBar::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ CMainFrame* pFrame = ((CMainFrame*)GetParentFrame());
+
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(wp);
+ pFrame->GetWindowPlacement(&wp);
+
+ if(!pFrame->m_fFullScreen && wp.showCmd != SW_SHOWMAXIMIZED)
+ {
+ CRect r;
+ GetClientRect(r);
+ CPoint p = point;
+
+ MapWindowPoints(pFrame, &point, 1);
+ pFrame->PostMessage(WM_NCLBUTTONDOWN,
+// (p.x+p.y >= r.Width()) ? HTBOTTOMRIGHT : HTCAPTION,
+ (p.x >= r.Width()-r.Height()) ? HTBOTTOMRIGHT :
+ HTCAPTION,
+ MAKELPARAM(point.x, point.y));
+ }
+}
+
+BOOL CPlayerStatusBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
+{
+ CMainFrame* pFrame = ((CMainFrame*)GetParentFrame());
+
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(wp);
+ pFrame->GetWindowPlacement(&wp);
+
+ if(!pFrame->m_fFullScreen && wp.showCmd != SW_SHOWMAXIMIZED)
+ {
+ CRect r;
+ GetClientRect(r);
+ CPoint p;
+ GetCursorPos(&p);
+ ScreenToClient(&p);
+// if(p.x+p.y >= r.Width())
+ if(p.x >= r.Width()-r.Height())
+ {
+ SetCursor(LoadCursor(NULL, IDC_SIZENWSE));
+ return TRUE;
+ }
+ }
+
+ return CDialogBar::OnSetCursor(pWnd, nHitTest, message);
+}
+
+HBRUSH CPlayerStatusBar::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+ HBRUSH hbr = CDialogBar::OnCtlColor(pDC, pWnd, nCtlColor);
+
+ if(*pWnd == m_type)
+ {
+ hbr = GetStockBrush(BLACK_BRUSH);
+ }
+
+ // TODO: Return a different brush if the default is not desired
+ return hbr;
+}
diff --git a/src/apps/mplayerc/PlayerStatusBar.h b/src/apps/mplayerc/PlayerStatusBar.h
new file mode 100644
index 000000000..4e459be17
--- /dev/null
+++ b/src/apps/mplayerc/PlayerStatusBar.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "StatusLabel.h"
+
+// CPlayerStatusBar
+
+class CPlayerStatusBar : public CDialogBar
+{
+ DECLARE_DYNAMIC(CPlayerStatusBar)
+
+ CStatic m_type;
+ CStatusLabel m_status, m_time;
+ CBitmap m_bm;
+ UINT m_bmid;
+ HICON m_hIcon;
+
+ void Relayout();
+
+public:
+ CPlayerStatusBar();
+ virtual ~CPlayerStatusBar();
+
+ void Clear();
+
+ void SetStatusBitmap(UINT id);
+ void SetStatusTypeIcon(HICON hIcon);
+ void SetStatusMessage(CString str);
+ void SetStatusTimer(CString str);
+ void SetStatusTimer(REFERENCE_TIME rtNow, REFERENCE_TIME rtDur, bool fHighPrecision, const GUID* pTimeFormat = &TIME_FORMAT_MEDIA_TIME);
+
+ CString GetStatusTimer();
+
+ void ShowTimer(bool fShow);
+
+// Overrides
+ virtual BOOL Create(CWnd* pParentWnd);
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+
+ DECLARE_MESSAGE_MAP()
+
+protected:
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ afx_msg void OnPaint();
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
+public:
+ afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+};
diff --git a/src/apps/mplayerc/PlayerSubresyncBar.cpp b/src/apps/mplayerc/PlayerSubresyncBar.cpp
new file mode 100644
index 000000000..aa4ba19f0
--- /dev/null
+++ b/src/apps/mplayerc/PlayerSubresyncBar.cpp
@@ -0,0 +1,1301 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PlayerSubresyncBar.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "mainfrm.h"
+#include "PlayerSubresyncBar.h"
+
+// CPlayerSubresyncBar
+
+IMPLEMENT_DYNAMIC(CPlayerSubresyncBar, CSizingControlBarG)
+CPlayerSubresyncBar::CPlayerSubresyncBar()
+{
+ m_rt = 0;
+ m_fUnlink = false;
+ m_lastSegment = -1;
+}
+
+CPlayerSubresyncBar::~CPlayerSubresyncBar()
+{
+}
+
+BOOL CPlayerSubresyncBar::Create(CWnd* pParentWnd, CCritSec* pSubLock)
+{
+ if(!CSizingControlBarG::Create(_T("Subresync"), pParentWnd, 0))
+ return FALSE;
+
+ m_pSubLock = pSubLock;
+
+ m_list.CreateEx(
+ WS_EX_DLGMODALFRAME|WS_EX_CLIENTEDGE,
+ WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_TABSTOP|LVS_REPORT/*|LVS_SHOWSELALWAYS*/|LVS_AUTOARRANGE|LVS_NOSORTHEADER,
+ CRect(0,0,100,100), this, IDC_SUBRESYNCLIST);
+
+ m_list.SetExtendedStyle(m_list.GetExtendedStyle()|LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER);
+
+ return TRUE;
+}
+
+BOOL CPlayerSubresyncBar::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if(!CSizingControlBarG::PreCreateWindow(cs))
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL CPlayerSubresyncBar::PreTranslateMessage(MSG* pMsg)
+{
+ if(IsWindow(pMsg->hwnd) && IsVisible() && pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
+ {
+ if(IsShortCut(pMsg) || IsDialogMessage(pMsg))
+ return TRUE;
+ }
+
+ return CSizingControlBarG::PreTranslateMessage(pMsg);
+}
+
+void CPlayerSubresyncBar::SetTime(__int64 rt)
+{
+ m_rt = rt;
+
+ int curSegment;
+
+ if(!m_sts.SearchSubs((int)(rt/10000), 25, &curSegment))
+ {
+ curSegment = -1;
+ }
+
+ if(m_lastSegment != curSegment) m_list.Invalidate();
+ m_lastSegment = curSegment;
+}
+
+void CPlayerSubresyncBar::SetSubtitle(ISubStream* pSubStream, double fps)
+{
+ m_pSubStream = pSubStream;
+
+ m_mode = NONE;
+ m_lastSegment = -1;
+ m_sts.Empty();
+
+ ResetSubtitle();
+
+ if(!m_pSubStream) return;
+
+ CLSID clsid;
+ m_pSubStream->GetClassID(&clsid);
+
+ if(clsid == __uuidof(CVobSubFile))
+ {
+ CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)m_pSubStream;
+
+ m_mode = VOBSUB;
+
+ CAtlArray<CVobSubFile::SubPos>& sp = pVSF->m_langs[pVSF->m_iLang].subpos;
+
+ for(int i = 0, j = sp.GetCount(); i < j; i++)
+ {
+ CString str;
+ str.Format(_T("%d,%d,%d,%d"), sp[i].vobid, sp[i].cellid, sp[i].fForced, i);
+ m_sts.Add(TToW(str), false, (int)sp[i].start, (int)sp[i].stop);
+ }
+
+ m_sts.CreateDefaultStyle(DEFAULT_CHARSET);
+
+ pVSF->m_fOnlyShowForcedSubs = false;
+
+ for(int i = 0, j = m_list.GetHeaderCtrl()->GetItemCount(); i < j; i++) m_list.DeleteColumn(0);
+ m_list.InsertColumn(COL_START, _T("Time"), LVCFMT_LEFT, 80);
+ m_list.InsertColumn(COL_END, _T("End"), LVCFMT_LEFT, 80);
+ m_list.InsertColumn(COL_PREVSTART, _T("Preview"), LVCFMT_LEFT, 80);
+ m_list.InsertColumn(COL_PREVEND, _T("End"), LVCFMT_LEFT, 80);
+ m_list.InsertColumn(COL_VOBID, _T("Vob ID"), LVCFMT_CENTER, 60);
+ m_list.InsertColumn(COL_CELLID, _T("Cell ID"), LVCFMT_CENTER, 60);
+ m_list.InsertColumn(COL_FORCED, _T("Forced"), LVCFMT_CENTER, 60);
+ }
+ else if(clsid == __uuidof(CRenderedTextSubtitle))
+ {
+ CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;
+
+ m_mode = TEXTSUB;
+
+ m_sts.Copy(*pRTS);
+ m_sts.ConvertToTimeBased(fps);
+ m_sts.Sort(true); /*!!m_fUnlink*/
+
+#ifndef UNICODE
+ if(!m_sts.IsEntryUnicode(0))
+ {
+ CFont* f = m_list.GetFont();
+ LOGFONT lf;
+ f->GetLogFont(&lf);
+ lf.lfCharSet = m_sts.GetCharSet(0);
+ m_font.DeleteObject();
+ m_font.CreateFontIndirect(&lf);
+ m_list.SetFont(&m_font);
+ }
+#endif
+ for(int i = 0, j = m_list.GetHeaderCtrl()->GetItemCount(); i < j; i++) m_list.DeleteColumn(0);
+ m_list.InsertColumn(COL_START, _T("Time"), LVCFMT_LEFT, 90);
+ m_list.InsertColumn(COL_END, _T("End"), LVCFMT_LEFT, 4);
+ m_list.InsertColumn(COL_PREVSTART, _T("Preview"), LVCFMT_LEFT, 80);
+ m_list.InsertColumn(COL_PREVEND, _T("End"), LVCFMT_LEFT, 4);
+ m_list.InsertColumn(COL_TEXT, _T("Text"), LVCFMT_LEFT, 275);
+ m_list.InsertColumn(COL_STYLE, _T("Style"), LVCFMT_LEFT, 80);
+ m_list.InsertColumn(COL_FONT, _T("Font"), LVCFMT_LEFT, 60);
+ m_list.InsertColumn(COL_CHARSET, _T("CharSet"), LVCFMT_CENTER, 20);
+ m_list.InsertColumn(COL_UNICODE, _T("Unicode"), LVCFMT_CENTER, 40);
+ m_list.InsertColumn(COL_LAYER, _T("Layer"), LVCFMT_CENTER, 50);
+ m_list.InsertColumn(COL_ACTOR, _T("Actor"), LVCFMT_LEFT, 80);
+ m_list.InsertColumn(COL_EFFECT, _T("Effect"), LVCFMT_LEFT, 80);
+ }
+
+ m_subtimes.SetCount(m_sts.GetCount());
+
+ for(int i = 0, j = m_sts.GetCount(); i < j; i++)
+ {
+ m_subtimes[i].orgstart = m_sts[i].start;
+ m_subtimes[i].orgend = m_sts[i].end;
+ }
+
+ ResetSubtitle();
+}
+
+void CPlayerSubresyncBar::ResetSubtitle()
+{
+ m_list.DeleteAllItems();
+
+ if(m_mode == VOBSUB || m_mode == TEXTSUB)
+ {
+ TCHAR buff[32];
+
+ int prevstart = INT_MIN;
+
+ for(int i = 0, j = m_sts.GetCount(); i < j; i++)
+ {
+ m_subtimes[i].newstart = m_subtimes[i].orgstart;
+ m_subtimes[i].newend = m_subtimes[i].orgend;
+
+ FormatTime(i, buff, 0, false);
+ m_list.InsertItem(i, buff, COL_START);
+ FormatTime(i, buff, 0, true);
+ m_list.SetItemText(i, COL_END, buff);
+
+ if(prevstart > m_subtimes[i].orgstart) m_list.SetItemData(i, TSEP);
+ prevstart = m_subtimes[i].orgstart;
+
+ SetCheck(i, false, false);
+ }
+
+ UpdatePreview();
+
+ m_list.SetColumnWidth(COL_START, LVSCW_AUTOSIZE);
+ m_list.SetColumnWidth(COL_PREVSTART, LVSCW_AUTOSIZE);
+ }
+
+ UpdateStrings();
+}
+
+void CPlayerSubresyncBar::SaveSubtitle()
+{
+ CMainFrame* pFrame = ((CMainFrame*)AfxGetMainWnd());
+ if(!pFrame) return;
+
+ CLSID clsid;
+ m_pSubStream->GetClassID(&clsid);
+
+ if(clsid == __uuidof(CVobSubFile) && m_mode == VOBSUB)
+ {
+ CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)m_pSubStream;
+
+ CAutoLock cAutoLock(m_pSubLock);
+
+ CAtlArray<CVobSubFile::SubPos>& sp = pVSF->m_langs[pVSF->m_iLang].subpos;
+
+ for(int i = 0, j = sp.GetCount(); i < j; i++)
+ {
+ sp[i].fValid = false;
+ }
+
+ for(int i = 0, j = m_sts.GetCount(); i < j; i++)
+ {
+ int vobid, cellid, forced, spnum, c;
+ if(_stscanf(m_sts.GetStr(i), _T("%d%c%d%c%d%c%d"), &vobid, &c, &cellid, &c, &forced, &c, &spnum) != 7) continue;
+ sp[spnum].start = m_sts[i].start;
+ sp[spnum].stop = m_sts[i].end;
+ sp[spnum].fValid = true;
+ }
+ }
+ else if(clsid == __uuidof(CRenderedTextSubtitle) && m_mode == TEXTSUB)
+ {
+ CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;
+
+ CAutoLock cAutoLock(m_pSubLock);
+
+ pRTS->Copy(m_sts);
+ }
+ else
+ {
+ return;
+ }
+
+ pFrame->InvalidateSubtitle();
+}
+
+void CPlayerSubresyncBar::UpdatePreview()
+{
+ if(m_mode == VOBSUB || m_mode == TEXTSUB)
+ {
+ if(0/*m_fUnlink*/)
+ {
+ for(int i = 0, j = m_sts.GetCount(); i < j; i++)
+ {
+ bool fStartMod, fEndMod, fStartAdj, fEndAdj;
+ GetCheck(i, fStartMod, fEndMod, fStartAdj, fEndAdj);
+ m_sts[i].start = (fStartMod||fStartAdj) ? m_subtimes[i].newstart : m_subtimes[i].orgstart;
+ m_sts[i].end = (fEndMod||fEndAdj) ? m_subtimes[i].newend : m_subtimes[i].orgend;
+ }
+ }
+ else
+ {
+ CAtlArray<int> schk;
+
+ for(int i = 0, j = m_sts.GetCount(); i < j;)
+ {
+ schk.RemoveAll();
+
+ int start = i, end;
+
+ for(end = i; end < j; end++)
+ {
+ int data = (int)m_list.GetItemData(end);
+ if((data&TSEP) && end > i) break;
+ if(data&(TSMOD|TSADJ))
+ schk.Add(end);
+ }
+
+ if(schk.GetCount() == 0)
+ {
+ for(; start < end; start++)
+ {
+ m_sts[start].start = m_subtimes[start].orgstart;
+ m_sts[start].end = m_subtimes[start].orgend;
+ }
+ }
+ else if(schk.GetCount() == 1)
+ {
+ int k = schk[0];
+ int dt = m_subtimes[k].newstart - m_subtimes[k].orgstart;
+ for(; start < end; start++)
+ {
+ m_sts[start].start = m_subtimes[start].orgstart + dt;
+ m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
+ ? m_subtimes[start].newend
+ : (m_subtimes[start].orgend + dt);
+ }
+ }
+ else if(schk.GetCount() >= 2)
+ {
+ int i0, i1, ti0, ds;
+ double m = 0;
+
+ for(int k = 0, l = schk.GetCount()-1; k < l; k++)
+ {
+ i0 = schk[k];
+ i1 = schk[k+1];
+
+ ti0 = m_subtimes[i0].orgstart;
+ ds = m_subtimes[i1].orgstart - ti0;
+
+ if(ds == 0)
+ {
+ for(; start < i1; start++)
+ {
+ m_sts[start].start = ti0;
+ m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
+ ? m_subtimes[start].newend
+ : (ti0 + m_subtimes[start].orgend - m_subtimes[start].orgstart);
+ }
+ }
+ else
+ {
+ m = double(m_subtimes[i1].newstart - m_subtimes[i0].newstart) / ds;
+
+ for(; start < i1; start++)
+ {
+ m_sts[start].start = int((m_subtimes[start].orgstart - ti0)*m + m_subtimes[i0].newstart);
+ m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
+ ? m_subtimes[start].newend
+ : m_mode == VOBSUB
+ ? (m_sts[start].start + m_subtimes[start].orgend - m_subtimes[start].orgstart)
+ : (m_sts[start].start + int((m_subtimes[start].orgend - m_subtimes[start].orgstart)*m));
+ }
+ }
+ }
+
+ if(ds == 0)
+ {
+ for(; start < end; start++)
+ {
+ m_sts[start].start = ti0;
+ m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
+ ? m_subtimes[start].newend
+ : (ti0 + (m_subtimes[start].orgend - m_subtimes[start].orgstart));
+ }
+ }
+ else
+ {
+ for(; start < end; start++)
+ {
+ m_sts[start].start = int((m_subtimes[start].orgstart - ti0)*m + m_subtimes[i0].newstart);
+ m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
+ ? m_subtimes[start].newend
+ : m_mode == VOBSUB
+ ? (m_sts[start].start + m_subtimes[start].orgend - m_subtimes[start].orgstart)
+ : (m_sts[start].start + int((m_subtimes[start].orgend - m_subtimes[start].orgstart)*m));
+ }
+ }
+ }
+
+ i = end;
+ }
+ }
+
+ m_sts.CreateSegments();
+
+ for(int i = 0, j = m_sts.GetCount(); i < j; i++)
+ {
+ TCHAR buff[32];
+ FormatTime(i, buff, 2, false);
+ m_list.SetItemText(i, COL_PREVSTART, buff);
+ FormatTime(i, buff, 2, true);
+ m_list.SetItemText(i, COL_PREVEND, buff);
+ }
+
+ if(IsWindowVisible())
+ {
+ SaveSubtitle();
+ }
+ }
+}
+
+void CPlayerSubresyncBar::UpdateStrings()
+{
+ CString str;
+
+ if(m_mode == TEXTSUB)
+ {
+ for(int i = 0, j = m_sts.GetCount(); i < j; i++)
+ {
+ STSStyle stss;
+ m_sts.GetStyle(i, stss);
+
+ m_list.SetItemText(i, COL_TEXT, m_sts.GetStr(i, true));
+ m_list.SetItemText(i, COL_STYLE, m_sts[i].style);
+ m_list.SetItemText(i, COL_FONT, stss.fontName);
+ str.Format(_T("%d"), stss.charSet);
+ m_list.SetItemText(i, COL_CHARSET, str);
+ m_list.SetItemText(i, COL_UNICODE, m_sts.IsEntryUnicode(i) ? _T("yes") : _T("no"));
+ str.Format(_T("%d"), m_sts[i].layer);
+ m_list.SetItemText(i, COL_LAYER, str);
+ m_list.SetItemText(i, COL_ACTOR, m_sts[i].actor);
+ m_list.SetItemText(i, COL_EFFECT, m_sts[i].effect);
+ }
+ }
+ else if(m_mode == VOBSUB)
+ {
+ for(int i = 0, j = m_sts.GetCount(); i < j; i++)
+ {
+ int vobid, cellid, forced, c;
+ if(_stscanf(m_sts.GetStr(i), _T("%d%c%d%c%d"), &vobid, &c, &cellid, &c, &forced) != 5) continue;
+ if(vobid < 0) str = _T("-");
+ else str.Format(_T("%d"), vobid);
+ m_list.SetItemText(i, COL_VOBID, str);
+ if(cellid < 0) str = _T("-");
+ else str.Format(_T("%d"), cellid);
+ m_list.SetItemText(i, COL_CELLID, str);
+ str = forced?_T("Yes"):_T("");
+ m_list.SetItemText(i, COL_FORCED, str);
+ }
+ }
+}
+
+void CPlayerSubresyncBar::GetCheck(int iItem, bool& fStartMod, bool& fEndMod, bool& fStartAdj, bool& fEndAdj)
+{
+ if(0 <= iItem && iItem < m_sts.GetCount())
+ {
+ int nCheck = (int)m_list.GetItemData(iItem);
+ fStartMod = !!(nCheck&TSMOD);
+ fEndMod = !!(nCheck&TEMOD);
+ fStartAdj = !!(nCheck&TSADJ);
+ fEndAdj = !!(nCheck&TEADJ);
+ }
+}
+
+void CPlayerSubresyncBar::SetCheck(int iItem, bool fStart, bool fEnd)
+{
+ if(0 <= iItem && iItem < m_sts.GetCount())
+ {
+ SubTime& st = m_subtimes[iItem];
+
+ int nCheck = (int)m_list.GetItemData(iItem) & TSEP;
+
+ if(fStart) nCheck |= TSMOD;
+ else if(abs(st.orgstart-st.newstart)) nCheck |= TSADJ;
+ if(fEnd) nCheck |= TEMOD;
+ else if(abs(st.orgend-st.newend)) nCheck |= TEADJ;
+
+ m_list.SetItemData(iItem, (DWORD)nCheck);
+
+ TCHAR buff[32];
+ FormatTime(iItem, buff, fStart, false);
+ m_list.SetItemText(iItem, COL_START, buff);
+ FormatTime(iItem, buff, fEnd, true);
+ m_list.SetItemText(iItem, COL_END, buff);
+ }
+}
+
+bool CPlayerSubresyncBar::ModStart(int iItem, int t, bool fReset)
+{
+ bool fRet = false;
+
+ bool fStartMod, fEndMod, fStartAdj, fEndAdj;
+ GetCheck(iItem, fStartMod, fEndMod, fStartAdj, fEndAdj);
+
+ SubTime& st = m_subtimes[iItem];
+
+// if(fStartMod || fStartAdj || st.orgstart != t || fReset)
+ {
+ fRet = (st.newstart != t);
+
+ st.newstart = t;
+ if(!fEndMod) st.newend = st.newstart + (st.orgend - st.orgstart);
+ else if(fReset) st.newstart = st.newend - (st.orgend - st.orgstart);
+
+ SetCheck(iItem, !fReset, fEndMod);
+ }
+
+ return(fRet);
+}
+
+bool CPlayerSubresyncBar::ModEnd(int iItem, int t, bool fReset)
+{
+ bool fRet = false;
+
+ bool fStartMod, fEndMod, fStartAdj, fEndAdj;
+ GetCheck(iItem, fStartMod, fEndMod, fStartAdj, fEndAdj);
+
+ SubTime& st = m_subtimes[iItem];
+
+// if(fEndMod || fEndAdj || st.orgend != t || fReset)
+ {
+ fRet = (st.newend != t);
+
+ st.newend = t;
+ if(!fStartMod) st.newstart = st.newend - (st.orgend - st.orgstart);
+ else if(fReset) st.newend = st.newstart + (st.orgend - st.orgstart);
+
+ SetCheck(iItem, fStartMod, !fReset);
+ }
+
+ return(fRet);
+}
+
+void CPlayerSubresyncBar::FormatTime(int iItem, TCHAR* buff, int time, bool fEnd)
+{
+ int t = !fEnd
+ ?(time == 2 ? m_sts[iItem].start
+ : time == 1 ? m_subtimes[iItem].newstart
+ : m_subtimes[iItem].orgstart)
+ : (time == 2 ? m_sts[iItem].end
+ : time == 1 ? m_subtimes[iItem].newend
+ : m_subtimes[iItem].orgend);
+
+ _stprintf(buff, t >= 0
+ ? _T("%02d:%02d:%02d.%03d")
+ : _T("-%02d:%02d:%02d.%03d"),
+ abs(t)/60/60/1000,
+ (abs(t)/60/1000)%60,
+ (abs(t)/1000)%60,
+ abs(t)%1000);
+}
+
+
+BEGIN_MESSAGE_MAP(CPlayerSubresyncBar, CSizingControlBarG)
+ ON_WM_SIZE()
+ ON_NOTIFY(LVN_BEGINLABELEDIT, IDC_SUBRESYNCLIST, OnBeginlabeleditList)
+ ON_NOTIFY(LVN_DOLABELEDIT, IDC_SUBRESYNCLIST, OnDolabeleditList)
+ ON_NOTIFY(LVN_ENDLABELEDIT, IDC_SUBRESYNCLIST, OnEndlabeleditList)
+ ON_NOTIFY(NM_RCLICK, IDC_SUBRESYNCLIST, OnRclickList)
+ ON_NOTIFY(NM_DBLCLK, IDC_SUBRESYNCLIST, OnNMDblclkList)
+ ON_NOTIFY(LVN_KEYDOWN, IDC_SUBRESYNCLIST, OnLvnKeydownList)
+ ON_NOTIFY(NM_CUSTOMDRAW, IDC_SUBRESYNCLIST, OnCustomdrawList)
+END_MESSAGE_MAP()
+
+
+// CPlayerSubresyncBar message handlers
+
+void CPlayerSubresyncBar::OnSize(UINT nType, int cx, int cy)
+{
+ CSizingControlBarG::OnSize(nType, cx, cy);
+
+ if(::IsWindow(m_list.m_hWnd))
+ {
+ CRect r;
+ GetClientRect(r);
+ r.DeflateRect(2, 2);
+ m_list.MoveWindow(r);
+ }
+}
+
+static bool ParseTime(CString str, int& ret, bool fWarn = true)
+{
+ int sign = 1, h, m, s, ms;
+ TCHAR c;
+
+ str.Trim();
+ if(str.GetLength() > 0 && str[0] == '-') sign = -1;
+
+ int n = _stscanf(str, _T("%d%c%d%c%d%c%d"), &h, &c, &m, &c, &s, &c, &ms);
+
+ h = abs(h);
+
+ if(n == 7
+ && 0 <= h && h < 24
+ && 0 <= m && m < 60
+ && 0 <= s && s < 60
+ && 0 <= ms && ms < 1000)
+ {
+ ret = sign*(h*60*60*1000+m*60*1000+s*1000+ms);
+ return(true);
+ }
+
+ if(fWarn) AfxMessageBox(_T("The correct time format is [-]hh:mm:ss.ms\n(e.g. 01:23:45.678)"));
+ return(false);
+}
+
+void CPlayerSubresyncBar::OnBeginlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
+ LV_ITEM* pItem = &pDispInfo->item;
+
+ *pResult = FALSE;
+
+ if(pItem->iItem >= 0)
+ {
+ if((pItem->iSubItem == COL_START || pItem->iSubItem == COL_END || pItem->iSubItem == COL_TEXT
+ || pItem->iSubItem == COL_STYLE || pItem->iSubItem == COL_LAYER
+ || pItem->iSubItem == COL_ACTOR || pItem->iSubItem == COL_EFFECT)
+ && m_mode == TEXTSUB)
+ {
+ *pResult = TRUE;
+ }
+ else if((pItem->iSubItem == COL_START)
+ && m_mode == VOBSUB)
+ {
+ *pResult = TRUE;
+ }
+ }
+}
+
+void CPlayerSubresyncBar::OnDolabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
+ LV_ITEM* pItem = &pDispInfo->item;
+
+ *pResult = FALSE;
+
+ if(pItem->iItem >= 0)
+ {
+ if((pItem->iSubItem == COL_START || pItem->iSubItem == COL_END || pItem->iSubItem == COL_TEXT
+ || pItem->iSubItem == COL_STYLE || pItem->iSubItem == COL_LAYER
+ || pItem->iSubItem == COL_ACTOR || pItem->iSubItem == COL_EFFECT)
+ && m_mode == TEXTSUB)
+ {
+ m_list.ShowInPlaceEdit(pItem->iItem, pItem->iSubItem);
+ *pResult = TRUE;
+ }
+ else if((pItem->iSubItem == COL_START)
+ && m_mode == VOBSUB)
+ {
+ m_list.ShowInPlaceEdit(pItem->iItem, pItem->iSubItem);
+ *pResult = TRUE;
+ }
+ }
+}
+
+void CPlayerSubresyncBar::OnEndlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
+ LV_ITEM* pItem = &pDispInfo->item;
+
+ *pResult = FALSE;
+
+ if(!m_list.m_fInPlaceDirty)
+ return;
+
+ bool fNeedsUpdate = false;
+
+ if(pItem->iItem >= 0 && pItem->pszText && (m_mode == VOBSUB || m_mode == TEXTSUB))
+ {
+ if(pItem->iSubItem == COL_START)
+ {
+ int t;
+ if(ParseTime(pItem->pszText, t))
+ {
+ fNeedsUpdate = ModStart(pItem->iItem, t);
+
+ *pResult = TRUE;
+ }
+ }
+ else if(pItem->iSubItem == COL_END && m_mode == TEXTSUB)
+ {
+ int t;
+ if(ParseTime(pItem->pszText, t))
+ {
+ fNeedsUpdate = ModEnd(pItem->iItem, t);
+
+ *pResult = TRUE;
+ }
+ }
+ else if(pItem->iSubItem == COL_TEXT && m_mode == TEXTSUB)
+ {
+ CString str = m_sts.GetStr(pItem->iItem, true);
+
+ if(str != pItem->pszText)
+ {
+ fNeedsUpdate = true;
+ m_sts.SetStr(pItem->iItem, CString(pItem->pszText), true);
+ m_list.SetItemText(pItem->iItem, pItem->iSubItem, m_sts.GetStr(pItem->iItem, true));
+ }
+ }
+ else if(pItem->iSubItem == COL_STYLE && m_mode == TEXTSUB)
+ {
+ CString str(pItem->pszText);
+ str.Trim();
+
+ if(!str.IsEmpty() && m_sts[pItem->iItem].style != str)
+ {
+ fNeedsUpdate = true;
+
+ if(!m_sts.m_styles.Lookup(str))
+ m_sts.AddStyle(str, new STSStyle());
+
+ m_sts[pItem->iItem].style = str;
+
+ m_list.SetItemText(pItem->iItem, pItem->iSubItem, pItem->pszText);
+ }
+ }
+ else if(pItem->iSubItem == COL_LAYER && m_mode == TEXTSUB)
+ {
+ int l;
+ if(_stscanf(pItem->pszText, _T("%d"), &l) == 1)
+ {
+ fNeedsUpdate = true;
+ m_sts[pItem->iItem].layer = l;
+ CString str;
+ str.Format(_T("%d"), l);
+ m_list.SetItemText(pItem->iItem, pItem->iSubItem, str);
+ }
+ }
+ else if(pItem->iSubItem == COL_ACTOR && m_mode == TEXTSUB)
+ {
+ CString str(pItem->pszText);
+ str.Trim();
+ if(!str.IsEmpty())
+ {
+ fNeedsUpdate = true;
+ m_sts[pItem->iItem].actor = str;
+ m_list.SetItemText(pItem->iItem, pItem->iSubItem, str);
+ }
+ }
+ else if(pItem->iSubItem == COL_EFFECT && m_mode == TEXTSUB)
+ {
+ CString str(pItem->pszText);
+ str.Trim();
+ if(!str.IsEmpty())
+ {
+ fNeedsUpdate = true;
+ m_sts[pItem->iItem].effect = str;
+ m_list.SetItemText(pItem->iItem, pItem->iSubItem, str);
+ }
+ }
+ }
+
+ if(fNeedsUpdate)
+ {
+ UpdatePreview();
+ }
+}
+
+static int uintcomp(const void* i1, const void* i2)
+{
+ return(*((UINT*)i2) - *((UINT*)i1));
+}
+
+void CPlayerSubresyncBar::OnRclickList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)pNMHDR;
+
+ if(lpnmlv->iItem >= 0 && lpnmlv->iSubItem >= 0)
+ {
+ enum
+ {
+ TOGSEP=1,
+ DUPITEM, DELITEM,
+ RESETS, SETOS, SETCS, RESETE, SETOE, SETCE,
+ STYLEFIRST, STYLELAST=STYLEFIRST+1000, STYLEEDIT,
+ UNICODEYES, UNICODENO,
+ LAYERDEC, LAYERINC,
+ ACTORFIRST, ACTORLAST=ACTORFIRST+1000,
+ EFFECTFIRST, EFFECTLAST=EFFECTFIRST+1000
+ };
+
+ CStringArray styles;
+ CStringArray actors;
+ CStringArray effects;
+
+ CMenu m;
+ m.CreatePopupMenu();
+
+ if(m_mode == VOBSUB || m_mode == TEXTSUB)
+ {
+ m.AppendMenu(MF_STRING|MF_ENABLED, TOGSEP, ResStr(IDS_SUBRESYNC_SEPARATOR));
+ m.AppendMenu(MF_SEPARATOR);
+ if(m_mode == TEXTSUB) m.AppendMenu(MF_STRING|MF_ENABLED, DUPITEM, ResStr(IDS_SUBRESYNC_DUPLICATE));
+ m.AppendMenu(MF_STRING|MF_ENABLED, DELITEM, ResStr(IDS_SUBRESYNC_DELETE));
+ }
+
+ if(lpnmlv->iSubItem == COL_START && (m_mode == VOBSUB || m_mode == TEXTSUB))
+ {
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING|MF_ENABLED, RESETS, ResStr(IDS_SUBRESYNC_RESET) + _T("\tF1"));
+ m.AppendMenu(MF_STRING|MF_ENABLED, SETOS, ResStr(IDS_SUBRESYNC_ORIGINAL) + _T("\tF3"));
+ m.AppendMenu(MF_STRING|MF_ENABLED, SETCS, ResStr(IDS_SUBRESYNC_CURRENT) + _T("\tF5"));
+ }
+ else if(lpnmlv->iSubItem == COL_END && m_mode == TEXTSUB)
+ {
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING|MF_ENABLED, RESETE, ResStr(IDS_SUBRESYNC_RESET) + _T("\tF2"));
+ m.AppendMenu(MF_STRING|MF_ENABLED, SETOE, ResStr(IDS_SUBRESYNC_ORIGINAL) + _T("\tF4"));
+ m.AppendMenu(MF_STRING|MF_ENABLED, SETCE, ResStr(IDS_SUBRESYNC_CURRENT) + _T("\tF6"));
+ }
+ else if(lpnmlv->iSubItem == COL_STYLE && m_mode == TEXTSUB)
+ {
+ m.AppendMenu(MF_SEPARATOR);
+
+ int id = STYLEFIRST;
+
+ POSITION pos = m_sts.m_styles.GetStartPosition();
+ while(pos && id <= STYLELAST)
+ {
+ CString key;
+ STSStyle* val;
+ m_sts.m_styles.GetNextAssoc(pos, key, val);
+ styles.Add(key);
+ m.AppendMenu(MF_STRING|MF_ENABLED, id++, key);
+ }
+
+ if(id > STYLEFIRST && m_list.GetSelectedCount() == 1)
+ {
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING|MF_ENABLED, STYLEEDIT, ResStr(IDS_SUBRESYNC_EDIT));
+ }
+ }
+ else if(lpnmlv->iSubItem == COL_UNICODE && m_mode == TEXTSUB)
+ {
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING|MF_ENABLED, UNICODEYES, ResStr(IDS_SUBRESYNC_YES));
+ m.AppendMenu(MF_STRING|MF_ENABLED, UNICODENO, ResStr(IDS_SUBRESYNC_NO));
+ }
+ else if(lpnmlv->iSubItem == COL_LAYER && m_mode == TEXTSUB)
+ {
+ m.AppendMenu(MF_SEPARATOR);
+ m.AppendMenu(MF_STRING|MF_ENABLED, LAYERDEC, ResStr(IDS_SUBRESYNC_DECREASE));
+ m.AppendMenu(MF_STRING|MF_ENABLED, LAYERINC, ResStr(IDS_SUBRESYNC_INCREASE));
+ }
+ else if(lpnmlv->iSubItem == COL_ACTOR && m_mode == TEXTSUB)
+ {
+ CMapStringToPtr actormap;
+
+ for(int i = 0, j = m_sts.GetCount(); i < j; i++)
+ actormap[m_sts[i].actor] = NULL;
+
+ actormap.RemoveKey(_T(""));
+
+ if(actormap.GetCount() > 0)
+ {
+ m.AppendMenu(MF_SEPARATOR);
+
+ int id = ACTORFIRST;
+
+ POSITION pos = actormap.GetStartPosition();
+ while(pos && id <= ACTORLAST)
+ {
+ CString key;
+ void* val;
+ actormap.GetNextAssoc(pos, key, val);
+
+ actors.Add(key);
+
+ m.AppendMenu(MF_STRING|MF_ENABLED, id++, key);
+ }
+ }
+ }
+ else if(lpnmlv->iSubItem == COL_EFFECT && m_mode == TEXTSUB)
+ {
+ CMapStringToPtr effectmap;
+
+ for(int i = 0, j = m_sts.GetCount(); i < j; i++)
+ effectmap[m_sts[i].effect] = NULL;
+
+ effectmap.RemoveKey(_T(""));
+
+ if(effectmap.GetCount() > 0)
+ {
+ m.AppendMenu(MF_SEPARATOR);
+
+ int id = EFFECTFIRST;
+
+ POSITION pos = effectmap.GetStartPosition();
+ while(pos && id <= EFFECTLAST)
+ {
+ CString key;
+ void* val;
+ effectmap.GetNextAssoc(pos, key, val);
+
+ effects.Add(key);
+
+ m.AppendMenu(MF_STRING|MF_ENABLED, id++, key);
+ }
+ }
+ }
+
+ CPoint p = lpnmlv->ptAction;
+ ::MapWindowPoints(pNMHDR->hwndFrom, HWND_DESKTOP, &p, 1);
+
+ UINT id = m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this);
+
+ bool fNeedsUpdate = false;
+
+ POSITION pos = m_list.GetFirstSelectedItemPosition();
+ while(pos)
+ {
+ int iItem = m_list.GetNextSelectedItem(pos);
+
+ SubTime& st = m_subtimes[iItem];
+
+ switch(id)
+ {
+ case TOGSEP:
+ m_list.SetItemData(iItem, m_list.GetItemData(iItem)^TSEP);
+ m_list.Invalidate();
+ fNeedsUpdate = true;
+ break;
+ case DUPITEM:
+ {
+ CUIntArray items;
+ pos = m_list.GetFirstSelectedItemPosition();
+ while(pos) items.Add(m_list.GetNextSelectedItem(pos));
+
+ qsort(items.GetData(), items.GetCount(), sizeof(UINT), uintcomp);
+
+ for(int i = 0; i < items.GetCount(); i++)
+ {
+ iItem = items[i];
+
+ STSEntry stse = m_sts[iItem];
+ m_sts.InsertAt(iItem+1, stse);
+
+ SubTime st = m_subtimes[iItem];
+ m_subtimes.InsertAt(iItem+1, st);
+
+ CHeaderCtrl* pHeader = (CHeaderCtrl*)m_list.GetDlgItem(0);
+ int nColumnCount = pHeader->GetItemCount();
+
+ CStringArray sa;
+ sa.SetSize(nColumnCount);
+ for(int col = 0; col < nColumnCount; col++)
+ sa[col] = m_list.GetItemText(iItem, col);
+
+ DWORD data = m_list.GetItemData(iItem);
+ m_list.InsertItem(iItem+1, sa[0]);
+ m_list.SetItemData(iItem+1, data);
+ for(int col = 1; col < nColumnCount; col++)
+ m_list.SetItemText(iItem+1, col, sa[col]);
+ }
+ }
+
+ fNeedsUpdate = true;
+ break;
+ case DELITEM:
+ {
+ CUIntArray items;
+ pos = m_list.GetFirstSelectedItemPosition();
+ while(pos) items.Add(m_list.GetNextSelectedItem(pos));
+
+ qsort(items.GetData(), items.GetCount(), sizeof(UINT), uintcomp);
+
+ for(int i = 0; i < items.GetCount(); i++)
+ {
+ iItem = items[i];
+ m_sts.RemoveAt(iItem);
+ m_subtimes.RemoveAt(iItem);
+ m_list.DeleteItem(iItem);
+ }
+
+ iItem = items[items.GetCount()-1];
+ if(iItem >= m_list.GetItemCount()) iItem = m_list.GetItemCount()-1;
+
+ m_list.SetSelectionMark(iItem);
+ }
+ fNeedsUpdate = true;
+ break;
+ case RESETS: /*if(*/ModStart(iItem, st.orgstart, true);/*)*/ fNeedsUpdate = true; break;
+ case SETOS: /*if(*/ModStart(iItem, st.orgstart);/*)*/ fNeedsUpdate = true; break;
+ case SETCS: /*if(*/ModStart(iItem, (int)(m_rt/10000));/*)*/ fNeedsUpdate = true; break;
+ case RESETE: /*if(*/ModEnd(iItem, st.orgend, true);/*)*/ fNeedsUpdate = true; break;
+ case SETOE: /*if(*/ModEnd(iItem, st.orgend);/*)*/ fNeedsUpdate = true; break;
+ case SETCE: /*if(*/ModEnd(iItem, (int)(m_rt/10000));/*)*/ fNeedsUpdate = true; break;
+ default:
+ if(STYLEFIRST <= id && id <= STYLELAST)
+ {
+ CString s = styles[id - STYLEFIRST];
+ if(m_sts[iItem].style != s) fNeedsUpdate = true;
+ m_sts[iItem].style = s;
+ m_list.SetItemText(iItem, lpnmlv->iSubItem, s);
+ }
+ else if(id == STYLEEDIT)
+ {
+ CAutoPtrArray<CPPageSubStyle> pages;
+ CAtlArray<STSStyle*> styles;
+
+ STSStyle* stss = m_sts.GetStyle(iItem);
+ int iSelPage = 0;
+
+ POSITION pos = m_sts.m_styles.GetStartPosition();
+ for(int i = 0; pos; i++)
+ {
+ CString key;
+ STSStyle* val;
+ m_sts.m_styles.GetNextAssoc(pos, key, val);
+
+ CAutoPtr<CPPageSubStyle> page(new CPPageSubStyle());
+ page->InitStyle(key, *val);
+ pages.Add(page);
+ styles.Add(val);
+
+ if(stss == val)
+ iSelPage = i;
+ }
+
+ CPropertySheet dlg(_T("Styles..."), this, iSelPage);
+ for(int i = 0; i < (int)pages.GetCount(); i++) dlg.AddPage(pages[i]);
+
+ if(dlg.DoModal() == IDOK)
+ {
+ for(int j = 0; j < (int)pages.GetCount(); j++)
+ {
+ stss = styles[j];
+ pages[j]->GetStyle(*stss);
+
+ for(int i = 0; i < m_sts.GetCount(); i++)
+ {
+ if(m_sts.GetStyle(i) == stss)
+ {
+ CString str;
+ m_list.SetItemText(i, COL_TEXT, m_sts.GetStr(i, true));
+ m_list.SetItemText(i, COL_FONT, stss->fontName);
+ str.Format(_T("%d"), stss->charSet);
+ m_list.SetItemText(i, COL_CHARSET, str);
+ str.Format(_T("%d"), m_sts[i].layer);
+ }
+ }
+ }
+
+ fNeedsUpdate = true;
+ }
+ }
+ else if(id == UNICODEYES || id == UNICODENO)
+ {
+ m_sts.ConvertUnicode(iItem, id == UNICODEYES);
+ m_list.SetItemText(iItem, COL_TEXT, m_sts.GetStr(iItem, true));
+ m_list.SetItemText(iItem, COL_UNICODE, m_sts.IsEntryUnicode(iItem) ? _T("yes") : _T("no"));
+ fNeedsUpdate = true;
+ }
+ else if(id == LAYERDEC || id == LAYERINC)
+ {
+ int d = (id == LAYERDEC) ? -1 : (id == LAYERINC) ? +1 : 0;
+ if(d != 0) fNeedsUpdate = true;
+ m_sts[iItem].layer += d;
+ CString s;
+ s.Format(_T("%d"), m_sts[iItem].layer);
+ m_list.SetItemText(iItem, lpnmlv->iSubItem, s);
+ }
+ else if(ACTORFIRST <= id && id <= ACTORLAST)
+ {
+ CString s = actors[id - ACTORFIRST];
+ if(m_sts[iItem].actor != s) fNeedsUpdate = true;
+ m_sts[iItem].actor = s;
+ m_list.SetItemText(iItem, lpnmlv->iSubItem, s);
+ }
+ else if(EFFECTFIRST <= id && id <= EFFECTLAST)
+ {
+ CString s = effects[id - EFFECTFIRST];
+ if(m_sts[iItem].effect != s) fNeedsUpdate = true;
+ m_sts[iItem].effect = s;
+ m_list.SetItemText(iItem, lpnmlv->iSubItem, s);
+ }
+ break;
+ }
+ }
+
+ if(fNeedsUpdate)
+ {
+ UpdatePreview();
+ }
+ }
+
+ *pResult = 0;
+}
+
+void CPlayerSubresyncBar::OnNMDblclkList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)pNMHDR;
+
+ if(lpnmlv->iItem >= 0 && lpnmlv->iSubItem >= 0 && (m_mode == VOBSUB || m_mode == TEXTSUB))
+ {
+ if(CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd())
+ {
+ int t = 0;
+ if(!ParseTime(m_list.GetItemText(lpnmlv->iItem, lpnmlv->iSubItem), t, false))
+ t = m_sts[lpnmlv->iItem].start;
+
+ REFERENCE_TIME rt =
+ lpnmlv->iSubItem == COL_START ? ((REFERENCE_TIME)t*10000) :
+ lpnmlv->iSubItem == COL_END ? ((REFERENCE_TIME)t*10000) :
+ lpnmlv->iSubItem == COL_PREVSTART ? ((REFERENCE_TIME)t*10000) :
+ lpnmlv->iSubItem == COL_PREVEND ? ((REFERENCE_TIME)t*10000) :
+ ((REFERENCE_TIME)t*10000);
+
+ pFrame->SeekTo(rt);
+ }
+ }
+
+ *pResult = 0;
+}
+
+void CPlayerSubresyncBar::OnLvnKeydownList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMLVKEYDOWN pLVKeyDown = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);
+
+ *pResult = 0;
+}
+
+static CUIntArray m_itemGroups;
+static int m_totalGroups;
+
+void CPlayerSubresyncBar::OnCustomdrawList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
+
+ *pResult = CDRF_DODEFAULT;
+
+ if(CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)
+ {
+ m_itemGroups.SetSize(m_list.GetItemCount());
+ m_totalGroups = 0;
+ for(int i = 0, j = m_list.GetItemCount(); i < j; i++)
+ {
+ if(m_list.GetItemData(i)&TSEP) m_totalGroups++;
+ m_itemGroups[i] = m_totalGroups;
+ }
+
+ *pResult = CDRF_NOTIFYPOSTPAINT|CDRF_NOTIFYITEMDRAW;
+ }
+ else if(CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
+ {
+ pLVCD->nmcd.uItemState &= ~CDIS_FOCUS;
+
+ *pResult = CDRF_NOTIFYPOSTPAINT|CDRF_NOTIFYSUBITEMDRAW;
+ }
+ else if((CDDS_ITEMPREPAINT|CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage)
+ {
+ COLORREF clrText;
+ COLORREF clrTextBk;
+
+ if((pLVCD->iSubItem == COL_START || pLVCD->iSubItem == COL_END || pLVCD->iSubItem == COL_TEXT || pLVCD->iSubItem == COL_STYLE
+ || pLVCD->iSubItem == COL_LAYER || pLVCD->iSubItem == COL_ACTOR || pLVCD->iSubItem == COL_EFFECT)
+ && m_mode == TEXTSUB)
+ {
+ clrText = 0;
+ }
+ else if((pLVCD->iSubItem == COL_START)
+ && m_mode == VOBSUB)
+ {
+ clrText = 0;
+ }
+ else
+ {
+ clrText = 0x606060;
+ }
+
+ clrTextBk = 0xffffff;
+// if(m_totalGroups > 0)
+ clrTextBk -= ((m_itemGroups[pLVCD->nmcd.dwItemSpec]&1) ? 0x100010 : 0x200020);
+
+ if(m_sts[pLVCD->nmcd.dwItemSpec].start <= m_rt/10000 && m_rt/10000 < m_sts[pLVCD->nmcd.dwItemSpec].end)
+ {
+ clrText |= 0xFF;
+ }
+
+ int nCheck = (int)m_list.GetItemData(pLVCD->nmcd.dwItemSpec);
+
+ if((nCheck&1) && (pLVCD->iSubItem == COL_START || pLVCD->iSubItem == COL_PREVSTART))
+ {
+ clrTextBk = 0xffddbb;
+ }
+ else if((nCheck&4) && (/*pLVCD->iSubItem == COL_START ||*/ pLVCD->iSubItem == COL_PREVSTART))
+ {
+ clrTextBk = 0xffeedd;
+ }
+
+ if((nCheck&2) && (pLVCD->iSubItem == COL_END || pLVCD->iSubItem == COL_PREVEND))
+ {
+ clrTextBk = 0xffddbb;
+ }
+ else if((nCheck&8) && (/*pLVCD->iSubItem == COL_END ||*/ pLVCD->iSubItem == COL_PREVEND))
+ {
+ clrTextBk = 0xffeedd;
+ }
+
+ pLVCD->clrText = clrText;
+ pLVCD->clrTextBk = clrTextBk;
+
+ *pResult = CDRF_NOTIFYPOSTPAINT;
+ }
+ else if((CDDS_ITEMPOSTPAINT|CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage)
+ {
+// *pResult = CDRF_DODEFAULT;
+ }
+ else if(CDDS_ITEMPOSTPAINT == pLVCD->nmcd.dwDrawStage)
+ {
+ int nItem = static_cast<int>(pLVCD->nmcd.dwItemSpec);
+
+ LVITEM rItem;
+ ZeroMemory(&rItem, sizeof(LVITEM));
+ rItem.mask = LVIF_IMAGE | LVIF_STATE;
+ rItem.iItem = nItem;
+ rItem.stateMask = LVIS_SELECTED;
+ m_list.GetItem(&rItem);
+
+ {
+ CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
+
+ CRect rcItem;
+ m_list.GetItemRect(nItem, &rcItem, LVIR_BOUNDS);
+
+ {
+ bool fSeparator = nItem < m_list.GetItemCount()-1 && (m_list.GetItemData(nItem+1)&TSEP);
+ CPen p(PS_INSIDEFRAME, 1, fSeparator ? 0x404040 : 0xe0e0e0);
+ CPen* old = pDC->SelectObject(&p);
+ pDC->MoveTo(CPoint(rcItem.left, rcItem.bottom-1));
+ pDC->LineTo(CPoint(rcItem.right, rcItem.bottom-1));
+ pDC->SelectObject(old);
+ }
+
+ {
+ CPen p(PS_INSIDEFRAME, 1, 0xe0e0e0);
+ CPen* old = pDC->SelectObject(&p);
+
+ CHeaderCtrl* pHeader = (CHeaderCtrl*)m_list.GetDlgItem(0);
+ int nColumnCount = pHeader->GetItemCount();
+
+ // Get the column offset
+ int offset = rcItem.left;
+ for(int i = 0; i < nColumnCount; i++)
+ {
+ offset += m_list.GetColumnWidth(i);
+ pDC->MoveTo(CPoint(offset, rcItem.top));
+ pDC->LineTo(CPoint(offset, rcItem.bottom));
+ }
+
+ pDC->SelectObject(old);
+ }
+
+ *pResult = CDRF_SKIPDEFAULT;
+ }
+ }
+ else if(CDDS_POSTPAINT == pLVCD->nmcd.dwDrawStage)
+ {
+ }
+}
+
+
+bool CPlayerSubresyncBar::IsShortCut(MSG* pMsg)
+{
+ if(pMsg->message == WM_KEYDOWN && VK_F1 <= pMsg->wParam && pMsg->wParam <= VK_F6)
+ {
+ int iItem = -1;
+
+ bool fNeedsUpdate = false;
+ bool fStep = false;
+
+ POSITION pos = m_list.GetFirstSelectedItemPosition();
+ while(pos)
+ {
+ iItem = m_list.GetNextSelectedItem(pos);
+
+ SubTime& st = m_subtimes[iItem];
+
+ switch(pMsg->wParam)
+ {
+ case VK_F1: /*if(*/ModStart(iItem, st.orgstart, true);/*)*/ fNeedsUpdate = true; break;
+ case VK_F3: /*if(*/ModStart(iItem, st.orgstart);/*)*/ fNeedsUpdate = true; break;
+ case VK_F5: /*if(*/ModStart(iItem, (int)(m_rt/10000));/*)*/ fNeedsUpdate = true; break;
+ case VK_F2: /*if(*/ModEnd(iItem, st.orgend, true);/*)*/ fNeedsUpdate = true; break;
+ case VK_F4: /*if(*/ModEnd(iItem, st.orgend);/*)*/ fNeedsUpdate = true; break;
+ case VK_F6: /*if(*/ModEnd(iItem, (int)(m_rt/10000));/*)*/ fNeedsUpdate = fStep = true; break;
+ }
+ }
+
+ if(fNeedsUpdate)
+ {
+ if(fStep && m_list.GetSelectedCount() == 1 && iItem < m_list.GetItemCount()-1)
+ {
+ m_list.SetItemState(iItem, 0, LVIS_SELECTED);
+ m_list.SetItemState(iItem+1, LVIS_SELECTED, LVIS_SELECTED);
+ m_list.SetSelectionMark(iItem+1);
+ m_list.EnsureVisible(iItem+1, false);
+ }
+
+ UpdatePreview();
+
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/src/apps/mplayerc/PlayerSubresyncBar.h b/src/apps/mplayerc/PlayerSubresyncBar.h
new file mode 100644
index 000000000..f826c511b
--- /dev/null
+++ b/src/apps/mplayerc/PlayerSubresyncBar.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <afxcview.h>
+#include "PlayerListCtrl.h"
+#include "..\..\subtitles\RTS.h"
+#include "..\..\subtitles\VobSubFile.h"
+
+// CPlayerSubresyncBar
+
+class CPlayerSubresyncBar : public CSizingControlBarG
+{
+ DECLARE_DYNAMIC(CPlayerSubresyncBar)
+
+private:
+ CPlayerListCtrl m_list;
+
+ CFont m_font;
+
+ CCritSec* m_pSubLock;
+ CComPtr<ISubStream> m_pSubStream;
+
+ int m_lastSegment;
+ __int64 m_rt;
+
+ enum
+ {
+ // TEXTSUB
+ COL_START=0, COL_END, COL_PREVSTART, COL_PREVEND, COL_TEXT, COL_STYLE, COL_FONT, COL_CHARSET, COL_UNICODE, COL_LAYER, COL_ACTOR, COL_EFFECT,
+ // VOBSUB
+ /* ........... same as TEXTSUB ............. */ COL_VOBID=COL_TEXT, COL_CELLID, COL_FORCED,
+ };
+
+ enum {NONE = 0, VOBSUB, TEXTSUB};
+ int m_mode;
+
+ bool m_fUnlink;
+
+ typedef struct {int orgstart, newstart, orgend, newend;} SubTime;
+ CAtlArray<SubTime> m_subtimes;
+
+// CRenderedTextSubtitle m_sts;
+ CSimpleTextSubtitle m_sts;
+
+ int GetStartTime(int iItem), GetEndTime(int iItem);
+ void FormatTime(int iItem, TCHAR* buff, int time /* 0:start, 1:newstart, 2:preview */, bool fEnd);
+
+ void UpdatePreview(), UpdateStrings();
+
+ enum {TSMOD=1, TEMOD=2, TSADJ=4, TEADJ=8, TSEP=0x80000000};
+
+ void GetCheck(int iItem, bool& fStartMod, bool& fEndMod, bool& fStartAdj, bool& fEndAdj);
+ void SetCheck(int iItem, bool fStart, bool fEnd);
+
+ bool ModStart(int iItem, int t, bool fReset = false);
+ bool ModEnd(int iItem, int t, bool fReset = false);
+
+public:
+ CPlayerSubresyncBar();
+ virtual ~CPlayerSubresyncBar();
+
+ BOOL Create(CWnd* pParentWnd, CCritSec* pSubLock);
+
+ void SetTime(__int64 rt);
+
+ void SetSubtitle(ISubStream* pSubStream, double fps);
+ void ResetSubtitle();
+ void SaveSubtitle();
+
+protected:
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ bool IsShortCut(MSG* pMsg);
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnBeginlabeleditList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnDolabeleditList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnEndlabeleditList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnRclickList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnNMDblclkList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnLvnKeydownList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnCustomdrawList(NMHDR* pNMHDR, LRESULT* pResult);
+};
diff --git a/src/apps/mplayerc/PlayerToolBar.cpp b/src/apps/mplayerc/PlayerToolBar.cpp
new file mode 100644
index 000000000..9bcf75d19
--- /dev/null
+++ b/src/apps/mplayerc/PlayerToolBar.cpp
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PlayerToolBar.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include <math.h>
+#include <atlbase.h>
+#include <afxpriv.h>
+#include "PlayerToolBar.h"
+#include "MainFrm.h"
+
+typedef HRESULT (__stdcall * SetWindowThemeFunct)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);
+
+// CPlayerToolBar
+
+IMPLEMENT_DYNAMIC(CPlayerToolBar, CToolBar)
+CPlayerToolBar::CPlayerToolBar()
+{
+}
+
+CPlayerToolBar::~CPlayerToolBar()
+{
+}
+
+BOOL CPlayerToolBar::Create(CWnd* pParentWnd)
+{
+ if(!__super::CreateEx(pParentWnd,
+ TBSTYLE_FLAT|TBSTYLE_TRANSPARENT|TBSTYLE_AUTOSIZE,
+ WS_CHILD|WS_VISIBLE|CBRS_ALIGN_BOTTOM|CBRS_TOOLTIPS, CRect(2,2,0,3))
+ || !LoadToolBar(IDB_PLAYERTOOLBAR))
+ return FALSE;
+
+ GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);
+
+ CToolBarCtrl& tb = GetToolBarCtrl();
+ tb.DeleteButton(tb.GetButtonCount()-1);
+ tb.DeleteButton(tb.GetButtonCount()-1);
+
+ SetMute(AfxGetAppSettings().fMute);
+
+ UINT styles[] =
+ {
+ TBBS_CHECKGROUP, TBBS_CHECKGROUP, TBBS_CHECKGROUP,
+ TBBS_SEPARATOR,
+ TBBS_BUTTON, TBBS_BUTTON, TBBS_BUTTON, TBBS_BUTTON,
+ TBBS_SEPARATOR,
+ TBBS_BUTTON/*|TBSTYLE_DROPDOWN*/,
+ TBBS_SEPARATOR,
+ TBBS_SEPARATOR,
+ TBBS_CHECKBOX,
+ /*TBBS_SEPARATOR,*/
+ };
+
+ for(int i = 0; i < countof(styles); i++)
+ SetButtonStyle(i, styles[i]|TBBS_DISABLED);
+
+ m_volctrl.Create(this);
+
+ if(AfxGetAppSettings().fDisabeXPToolbars)
+ {
+ if(HMODULE h = LoadLibrary(_T("uxtheme.dll")))
+ {
+ SetWindowThemeFunct f = (SetWindowThemeFunct)GetProcAddress(h, "SetWindowTheme");
+ if(f) f(m_hWnd, L" ", L" ");
+ FreeLibrary(h);
+ }
+ }
+
+ return TRUE;
+}
+
+BOOL CPlayerToolBar::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if(!__super::PreCreateWindow(cs))
+ return FALSE;
+
+ m_dwStyle &= ~CBRS_BORDER_TOP;
+ m_dwStyle &= ~CBRS_BORDER_BOTTOM;
+// m_dwStyle |= CBRS_SIZE_FIXED;
+
+ return TRUE;
+}
+
+void CPlayerToolBar::ArrangeControls()
+{
+ if(!::IsWindow(m_volctrl.m_hWnd)) return;
+
+ CRect r;
+ GetClientRect(&r);
+
+ CRect br = GetBorders();
+
+ CRect r10;
+ GetItemRect(10, &r10);
+
+ CRect vr;
+ m_volctrl.GetClientRect(&vr);
+ CRect vr2(r.right+br.right-60, r.top-1, r.right+br.right+6, r.bottom);
+ m_volctrl.MoveWindow(vr2);
+
+ UINT nID;
+ UINT nStyle;
+ int iImage;
+ GetButtonInfo(12, nID, nStyle, iImage);
+ SetButtonInfo(11, GetItemID(11), TBBS_SEPARATOR, vr2.left - iImage - r10.right - 11);
+}
+
+void CPlayerToolBar::SetMute(bool fMute)
+{
+ CToolBarCtrl& tb = GetToolBarCtrl();
+ TBBUTTONINFO bi;
+ bi.cbSize = sizeof(bi);
+ bi.dwMask = TBIF_IMAGE;
+ bi.iImage = fMute?13:12;
+ tb.SetButtonInfo(ID_VOLUME_MUTE, &bi);
+
+ AfxGetAppSettings().fMute = fMute;
+}
+
+bool CPlayerToolBar::IsMuted()
+{
+ CToolBarCtrl& tb = GetToolBarCtrl();
+ TBBUTTONINFO bi;
+ bi.cbSize = sizeof(bi);
+ bi.dwMask = TBIF_IMAGE;
+ tb.GetButtonInfo(ID_VOLUME_MUTE, &bi);
+ return(bi.iImage==13);
+}
+
+int CPlayerToolBar::GetVolume()
+{
+ int volume = m_volctrl.GetPos();
+ volume = (int)((log10(1.0*volume)-2)*5000);
+ volume = max(min(volume, 0), -10000);
+ return(IsMuted() ? -10000 : volume);
+}
+
+void CPlayerToolBar::SetVolume(int volume)
+{
+/*
+ volume = (int)pow(10, ((double)volume)/5000+2);
+ volume = max(min(volume, 100), 1);
+*/
+ m_volctrl.SetPosInternal(volume);
+}
+
+BEGIN_MESSAGE_MAP(CPlayerToolBar, CToolBar)
+ ON_WM_PAINT()
+ ON_WM_SIZE()
+ ON_MESSAGE_VOID(WM_INITIALUPDATE, OnInitialUpdate)
+ ON_COMMAND_EX(ID_VOLUME_MUTE, OnVolumeMute)
+ ON_UPDATE_COMMAND_UI(ID_VOLUME_MUTE, OnUpdateVolumeMute)
+ ON_COMMAND_EX(ID_VOLUME_UP, OnVolumeUp)
+ ON_COMMAND_EX(ID_VOLUME_DOWN, OnVolumeDown)
+ ON_WM_NCPAINT()
+ ON_WM_LBUTTONDOWN()
+END_MESSAGE_MAP()
+
+// CPlayerToolBar message handlers
+
+void CPlayerToolBar::OnPaint()
+{
+ if(m_bDelayedButtonLayout)
+ Layout();
+
+ CPaintDC dc(this); // device context for painting
+
+ DefWindowProc(WM_PAINT, WPARAM(dc.m_hDC), 0);
+
+ {
+ UINT nID;
+ UINT nStyle = 0;
+ int iImage = 0;
+ GetButtonInfo(11, nID, nStyle, iImage);
+ CRect ItemRect;
+ GetItemRect(11, ItemRect);
+ dc.FillSolidRect(ItemRect, GetSysColor(COLOR_BTNFACE));
+ }
+}
+
+void CPlayerToolBar::OnSize(UINT nType, int cx, int cy)
+{
+ __super::OnSize(nType, cx, cy);
+
+ ArrangeControls();
+}
+
+void CPlayerToolBar::OnInitialUpdate()
+{
+ ArrangeControls();
+}
+
+BOOL CPlayerToolBar::OnVolumeMute(UINT nID)
+{
+ SetMute(!IsMuted());
+ return FALSE;
+}
+
+void CPlayerToolBar::OnUpdateVolumeMute(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(true);
+ pCmdUI->SetCheck(IsMuted());
+}
+
+BOOL CPlayerToolBar::OnVolumeUp(UINT nID)
+{
+ m_volctrl.IncreaseVolume();
+ return FALSE;
+}
+
+BOOL CPlayerToolBar::OnVolumeDown(UINT nID)
+{
+ m_volctrl.DecreaseVolume();
+ return FALSE;
+}
+
+void CPlayerToolBar::OnNcPaint() // when using XP styles the NC area isn't drawn for our toolbar...
+{
+ CRect wr, cr;
+
+ CWindowDC dc(this);
+ GetClientRect(&cr);
+ ClientToScreen(&cr);
+ GetWindowRect(&wr);
+ cr.OffsetRect(-wr.left, -wr.top);
+ wr.OffsetRect(-wr.left, -wr.top);
+ dc.ExcludeClipRect(&cr);
+ dc.FillSolidRect(wr, GetSysColor(COLOR_BTNFACE));
+
+ // Do not call CToolBar::OnNcPaint() for painting messages
+}
+
+void CPlayerToolBar::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ for(int i = 0, j = GetToolBarCtrl().GetButtonCount(); i < j; i++)
+ {
+ if(GetButtonStyle(i)&(TBBS_SEPARATOR|TBBS_DISABLED))
+ continue;
+
+ CRect r;
+ GetItemRect(i, r);
+ if(r.PtInRect(point))
+ {
+ __super::OnLButtonDown(nFlags, point);
+ return;
+ }
+ }
+
+ CMainFrame* pFrame = ((CMainFrame*)GetParentFrame());
+ if(!pFrame->m_fFullScreen)
+ {
+ MapWindowPoints(pFrame, &point, 1);
+ pFrame->PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
+ }
+}
diff --git a/src/apps/mplayerc/PlayerToolBar.h b/src/apps/mplayerc/PlayerToolBar.h
new file mode 100644
index 000000000..a0b01800a
--- /dev/null
+++ b/src/apps/mplayerc/PlayerToolBar.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "VolumeCtrl.h"
+
+// CPlayerToolBar
+
+class CPlayerToolBar : public CToolBar
+{
+ DECLARE_DYNAMIC(CPlayerToolBar)
+
+private:
+ bool IsMuted();
+ void SetMute(bool fMute = true);
+
+public:
+ CPlayerToolBar();
+ virtual ~CPlayerToolBar();
+
+ int GetVolume();
+ void SetVolume(int volume);
+ __declspec(property(get=GetVolume, put=SetVolume)) int Volume;
+
+ void ArrangeControls();
+
+ CVolumeCtrl m_volctrl;
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CPlayerToolBar)
+ virtual BOOL Create(CWnd* pParentWnd);
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ //}}AFX_VIRTUAL
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CPlayerToolBar)
+ afx_msg void OnPaint();
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnInitialUpdate();
+ afx_msg BOOL OnVolumeMute(UINT nID);
+ afx_msg void OnUpdateVolumeMute(CCmdUI* pCmdUI);
+ afx_msg BOOL OnVolumeUp(UINT nID);
+ afx_msg BOOL OnVolumeDown(UINT nID);
+ afx_msg void OnNcPaint();
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
diff --git a/src/apps/mplayerc/Playlist.cpp b/src/apps/mplayerc/Playlist.cpp
new file mode 100644
index 000000000..1a6dd1bdd
--- /dev/null
+++ b/src/apps/mplayerc/Playlist.cpp
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "playlist.h"
+
+//
+// CPlaylistItem
+//
+
+UINT CPlaylistItem::m_globalid = 0;
+
+CPlaylistItem::CPlaylistItem()
+ : m_type(file)
+ , m_fInvalid(false)
+ , m_duration(0)
+ , m_vinput(-1)
+ , m_vchannel(-1)
+ , m_ainput(-1)
+{
+ m_id = m_globalid++;
+}
+
+CPlaylistItem::~CPlaylistItem()
+{
+}
+
+CPlaylistItem::CPlaylistItem(const CPlaylistItem& pli)
+{
+ *this = pli;
+}
+
+CPlaylistItem& CPlaylistItem::operator = (const CPlaylistItem& pli)
+{
+ m_id = pli.m_id;
+ m_label = pli.m_label;
+ m_fns.RemoveAll();
+ m_fns.AddTailList(&pli.m_fns);
+ m_subs.RemoveAll();
+ m_subs.AddTailList(&pli.m_subs);
+ m_type = pli.m_type;
+ m_fInvalid = pli.m_fInvalid;
+ m_duration = pli.m_duration;
+ m_vinput = pli.m_vinput;
+ m_vchannel = pli.m_vchannel;
+ m_ainput = pli.m_ainput;
+ return(*this);
+}
+
+POSITION CPlaylistItem::FindFile(CString path)
+{
+ POSITION pos = m_fns.GetHeadPosition();
+ while(pos && !m_fns.GetAt(pos).CompareNoCase(path)) m_fns.GetNext(pos);
+ return(NULL);
+}
+
+static CString StripPath(CString path)
+{
+ CString p = path;
+ p.Replace('\\', '/');
+ p = p.Mid(p.ReverseFind('/')+1);
+ return(p.IsEmpty() ? path : p);
+}
+
+CString CPlaylistItem::GetLabel(int i)
+{
+ CString str;
+
+ if(i == 0)
+ {
+ if(!m_label.IsEmpty()) str = m_label;
+ else if(!m_fns.IsEmpty()) str = StripPath(m_fns.GetHead());
+ }
+ else if(i == 1)
+ {
+ if(m_fInvalid) return _T("Invalid");
+
+ if(m_type == file)
+ {
+ REFERENCE_TIME rt = m_duration;
+
+ if(rt > 0)
+ {
+ rt /= 10000000;
+ int ss = int(rt%60);
+ rt /= 60;
+ int mm = int(rt%60);
+ rt /= 60;
+ int hh = int(rt);
+
+ str.Format(_T("%02d:%02d:%02d"), hh, mm, ss);
+ }
+ }
+ else if(m_type == device)
+ {
+ // TODO
+ }
+
+ }
+
+ return str;
+}
+
+//
+// CPlaylist
+//
+
+CPlaylist::CPlaylist()
+ : m_pos(NULL)
+{
+}
+
+CPlaylist::~CPlaylist()
+{
+}
+
+void CPlaylist::RemoveAll()
+{
+ __super::RemoveAll();
+ m_pos = NULL;
+}
+
+bool CPlaylist::RemoveAt(POSITION pos)
+{
+ if(pos)
+ {
+ __super::RemoveAt(pos);
+ if(m_pos == pos) {m_pos = NULL; return(true);}
+ }
+
+ return(false);
+}
+
+typedef struct {UINT n; POSITION pos;} plsort_t;
+
+static int compare(const void* arg1, const void* arg2)
+{
+ UINT a1 = ((plsort_t*)arg1)->n;
+ UINT a2 = ((plsort_t*)arg2)->n;
+ return a1 > a2 ? 1 : a1 < a2 ? -1 : 0;
+}
+
+typedef struct {LPCTSTR str; POSITION pos;} plsort2_t;
+
+int compare2(const void* arg1, const void* arg2)
+{
+ return _tcsicmp(((plsort2_t*)arg1)->str, ((plsort2_t*)arg2)->str);
+}
+
+void CPlaylist::SortById()
+{
+ CAtlArray<plsort_t> a;
+ a.SetCount(GetCount());
+ POSITION pos = GetHeadPosition();
+ for(int i = 0; pos; i++, GetNext(pos))
+ a[i].n = GetAt(pos).m_id, a[i].pos = pos;
+ qsort(a.GetData(), a.GetCount(), sizeof(plsort_t), compare);
+ for(int i = 0; i < a.GetCount(); i++)
+ {
+ AddTail(GetAt(a[i].pos));
+ __super::RemoveAt(a[i].pos);
+ if(m_pos == a[i].pos) m_pos = GetTailPosition();
+ }
+}
+
+void CPlaylist::SortByName()
+{
+ CAtlArray<plsort2_t> a;
+ a.SetCount(GetCount());
+ POSITION pos = GetHeadPosition();
+ for(int i = 0; pos; i++, GetNext(pos))
+ {
+ CString& fn = GetAt(pos).m_fns.GetHead();
+ a[i].str = (LPCTSTR)fn + max(fn.ReverseFind('/'), fn.ReverseFind('\\')) + 1;
+ a[i].pos = pos;
+ }
+ qsort(a.GetData(), a.GetCount(), sizeof(plsort2_t), compare2);
+ for(int i = 0; i < a.GetCount(); i++)
+ {
+ AddTail(GetAt(a[i].pos));
+ __super::RemoveAt(a[i].pos);
+ if(m_pos == a[i].pos) m_pos = GetTailPosition();
+ }
+}
+
+void CPlaylist::SortByPath()
+{
+ CAtlArray<plsort2_t> a;
+ a.SetCount(GetCount());
+ POSITION pos = GetHeadPosition();
+ for(int i = 0; pos; i++, GetNext(pos))
+ a[i].str = GetAt(pos).m_fns.GetHead(), a[i].pos = pos;
+ qsort(a.GetData(), a.GetCount(), sizeof(plsort2_t), compare2);
+ for(int i = 0; i < a.GetCount(); i++)
+ {
+ AddTail(GetAt(a[i].pos));
+ __super::RemoveAt(a[i].pos);
+ if(m_pos == a[i].pos) m_pos = GetTailPosition();
+ }
+}
+
+void CPlaylist::Randomize()
+{
+ CAtlArray<plsort_t> a;
+ a.SetCount(GetCount());
+ srand((unsigned int)time(NULL));
+ POSITION pos = GetHeadPosition();
+ for(int i = 0; pos; i++, GetNext(pos))
+ a[i].n = rand(), a[i].pos = pos;
+ qsort(a.GetData(), a.GetCount(), sizeof(plsort_t), compare);
+ CList<CPlaylistItem> pl;
+ for(int i = 0; i < a.GetCount(); i++)
+ {
+ AddTail(GetAt(a[i].pos));
+ __super::RemoveAt(a[i].pos);
+ if(m_pos == a[i].pos)
+ m_pos = GetTailPosition();
+ }
+}
+
+POSITION CPlaylist::GetPos()
+{
+ return(m_pos);
+}
+
+void CPlaylist::SetPos(POSITION pos)
+{
+ m_pos = pos;
+}
+
+CPlaylistItem& CPlaylist::GetNextWrap(POSITION& pos)
+{
+ GetNext(pos);
+
+ if(!pos)
+ {
+ // FIXME: add param: , bool fShuffle
+ if(GetCount() > 2 && AfxGetApp()->GetProfileInt(ResStr(IDS_R_SETTINGS), _T("ShufflePlaylistItems"), FALSE))
+ Randomize();
+
+ pos = GetHeadPosition();
+ }
+
+ return(GetAt(pos));
+}
+
+CPlaylistItem& CPlaylist::GetPrevWrap(POSITION& pos)
+{
+ GetPrev(pos);
+ if(!pos) pos = GetTailPosition();
+ return(GetAt(pos));
+}
+
diff --git a/src/apps/mplayerc/Playlist.h b/src/apps/mplayerc/Playlist.h
new file mode 100644
index 000000000..5aa7045ba
--- /dev/null
+++ b/src/apps/mplayerc/Playlist.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <afxcoll.h>
+
+class CPlaylistItem
+{
+ static UINT m_globalid;
+
+public:
+ UINT m_id;
+ CString m_label;
+ CAtlList<CString> m_fns;
+ CAtlList<CString> m_subs;
+ enum type_t {file, device} m_type;
+ REFERENCE_TIME m_duration;
+ int m_vinput, m_vchannel;
+ int m_ainput;
+ long m_country;
+
+ bool m_fInvalid;
+
+public:
+ CPlaylistItem();
+ virtual ~CPlaylistItem();
+
+ CPlaylistItem(const CPlaylistItem& pli);
+ CPlaylistItem& operator = (const CPlaylistItem& pli);
+
+ POSITION FindFile(CString path);
+
+ CString GetLabel(int i = 0);
+};
+
+class CPlaylist : public CList<CPlaylistItem>
+{
+protected:
+ POSITION m_pos;
+
+public:
+ CPlaylist();
+ virtual ~CPlaylist();
+
+ void RemoveAll();
+ bool RemoveAt(POSITION pos);
+
+ void SortById(), SortByName(), SortByPath(), Randomize();
+
+ POSITION GetPos();
+ void SetPos(POSITION pos);
+ CPlaylistItem& GetNextWrap(POSITION& pos);
+ CPlaylistItem& GetPrevWrap(POSITION& pos);
+};
diff --git a/src/apps/mplayerc/PnSPresetsDlg.cpp b/src/apps/mplayerc/PnSPresetsDlg.cpp
new file mode 100644
index 000000000..ae203595c
--- /dev/null
+++ b/src/apps/mplayerc/PnSPresetsDlg.cpp
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// PnSPresetsDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PnSPresetsDlg.h"
+
+
+// CPnSPresetsDlg dialog
+
+IMPLEMENT_DYNAMIC(CPnSPresetsDlg, CCmdUIDialog)
+CPnSPresetsDlg::CPnSPresetsDlg(CWnd* pParent /*=NULL*/)
+ : CCmdUIDialog(CPnSPresetsDlg::IDD, pParent)
+ , m_label(_T(""))
+{
+}
+
+CPnSPresetsDlg::~CPnSPresetsDlg()
+{
+}
+
+void CPnSPresetsDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_EDIT2, m_PosX);
+ DDX_Control(pDX, IDC_EDIT3, m_PosY);
+ DDX_Control(pDX, IDC_EDIT4, m_ZoomX);
+ DDX_Control(pDX, IDC_EDIT5, m_ZoomY);
+ DDX_Text(pDX, IDC_EDIT1, m_label);
+ DDX_Control(pDX, IDC_LIST1, m_list);
+}
+
+BOOL CPnSPresetsDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ for(int i = 0, j = m_pnspresets.GetCount(); i < j; i++)
+ {
+ CString label;
+ double PosX, PosY, ZoomX, ZoomY;
+ StringToParams(m_pnspresets[i], label, PosX, PosY, ZoomX, ZoomY);
+
+ m_list.AddString(label);
+
+ if(i == 0)
+ {
+ m_list.SetCurSel(0);
+ OnLbnSelchangeList1();
+ }
+ }
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+
+void CPnSPresetsDlg::StringToParams(CString str, CString& label, double& PosX, double& PosY, double& ZoomX, double& ZoomY)
+{
+ int i = 0, j = 0;
+
+ for(CString token = str.Tokenize(_T(","), i); !token.IsEmpty(); token = str.Tokenize(_T(","), i), j++)
+ {
+ if(j == 0)
+ {
+ label = token;
+ }
+ else
+ {
+ float f = 0;
+ if(_stscanf(token, _T("%f"), &f) != 1) continue;
+
+ switch(j)
+ {
+ case 1: PosX = f; break;
+ case 2: PosY = f; break;
+ case 3: ZoomX = f; break;
+ case 4: ZoomY = f; break;
+ default: break;
+ }
+ }
+ }
+}
+
+CString CPnSPresetsDlg::ParamsToString(CString label, double PosX, double PosY, double ZoomX, double ZoomY)
+{
+ CString str;
+ str.Format(_T("%s,%.3f,%.3f,%.3f,%.3f"), label, PosX, PosY, ZoomX, ZoomY);
+ return(str);
+}
+
+BEGIN_MESSAGE_MAP(CPnSPresetsDlg, CCmdUIDialog)
+ ON_LBN_SELCHANGE(IDC_LIST1, OnLbnSelchangeList1)
+ ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateButton2)
+ ON_BN_CLICKED(IDC_BUTTON3, OnBnClickedButton6)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON3, OnUpdateButton6)
+ ON_BN_CLICKED(IDC_BUTTON4, OnBnClickedButton9)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON4, OnUpdateButton9)
+ ON_BN_CLICKED(IDC_BUTTON5, OnBnClickedButton10)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON5, OnUpdateButton10)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateButton1)
+END_MESSAGE_MAP()
+
+
+// CPnSPresetsDlg message handlers
+void CPnSPresetsDlg::OnLbnSelchangeList1()
+{
+ int i = m_list.GetCurSel();
+ if(i >= 0 && i < m_pnspresets.GetCount())
+ {
+ double PosX, PosY, ZoomX, ZoomY;
+ StringToParams(m_pnspresets[i], m_label, PosX, PosY, ZoomX, ZoomY);
+ m_PosX = PosX; m_PosY = PosY;
+ m_ZoomX = ZoomX; m_ZoomY = ZoomY;
+ }
+ else
+ {
+ m_label.Empty();
+ m_PosX.SetWindowText(_T(""));
+ m_PosY.SetWindowText(_T(""));
+ m_ZoomX.SetWindowText(_T(""));
+ m_ZoomY.SetWindowText(_T(""));
+ }
+
+ UpdateData(FALSE);
+}
+
+void CPnSPresetsDlg::OnBnClickedButton2() // new
+{
+ m_pnspresets.Add(_T("New,0.5,0.5,1.0,1.0"));
+ m_list.SetCurSel(m_list.AddString(_T("New")));
+ OnLbnSelchangeList1();
+}
+
+void CPnSPresetsDlg::OnUpdateButton2(CCmdUI* pCmdUI)
+{
+ CString str;
+ int len = m_list.GetCount();
+ if(len > 0) m_list.GetText(len-1, str);
+ pCmdUI->Enable(str != _T("New"));
+}
+
+void CPnSPresetsDlg::OnBnClickedButton6() // del
+{
+ int i = m_list.GetCurSel();
+ m_list.DeleteString(i);
+ m_pnspresets.RemoveAt(i);
+ if(i == m_list.GetCount()) i--;
+ m_list.SetCurSel(i);
+ OnLbnSelchangeList1();
+}
+
+void CPnSPresetsDlg::OnUpdateButton6(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_list.GetCurSel() >= 0);
+}
+
+void CPnSPresetsDlg::OnBnClickedButton9() // up
+{
+ int i = m_list.GetCurSel();
+ CString str, str2;
+ m_list.GetText(i, str);
+ str2 = m_pnspresets.GetAt(i);
+ m_list.DeleteString(i);
+ m_pnspresets.RemoveAt(i);
+ i--;
+ m_list.InsertString(i, str);
+ m_pnspresets.InsertAt(i, str2);
+ m_list.SetCurSel(i);
+}
+
+void CPnSPresetsDlg::OnUpdateButton9(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_list.GetCurSel() > 0 && m_list.GetCurSel() < m_list.GetCount());
+}
+
+void CPnSPresetsDlg::OnBnClickedButton10() // down
+{
+ int i = m_list.GetCurSel();
+ CString str, str2;
+ m_list.GetText(i, str);
+ str2 = m_pnspresets.GetAt(i);
+ m_list.DeleteString(i);
+ m_pnspresets.RemoveAt(i);
+ i++;
+ m_list.InsertString(i, str);
+ m_pnspresets.InsertAt(i, str2);
+ m_list.SetCurSel(i);
+}
+
+void CPnSPresetsDlg::OnUpdateButton10(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(m_list.GetCurSel() >= 0 && m_list.GetCurSel() < m_list.GetCount()-1);
+}
+
+void CPnSPresetsDlg::OnBnClickedButton1() // set
+{
+ int i = m_list.GetCurSel();
+ UpdateData();
+ if(m_label.Remove(',') > 0)
+ UpdateData(FALSE);
+ m_pnspresets[i] = ParamsToString(m_label, m_PosX, m_PosY, m_ZoomX, m_ZoomY);
+ m_list.DeleteString(i);
+ m_list.InsertString(i, m_label);
+ m_list.SetCurSel(i);
+}
+
+void CPnSPresetsDlg::OnUpdateButton1(CCmdUI* pCmdUI)
+{
+ UpdateData();
+ pCmdUI->Enable(m_list.GetCurSel() >= 0
+ && !m_label.IsEmpty() && m_label.Find(',') < 0
+ && m_PosX >= 0 && m_PosX <= 1
+ && m_PosY >= 0 && m_PosY <= 1
+ && m_ZoomX >= 0.2 && m_ZoomX <= 3.0
+ && m_ZoomY >= 0.2 && m_ZoomY <= 3.0);
+}
+
+void CPnSPresetsDlg::OnOK()
+{
+ if(m_list.GetCurSel() >= 0)
+ OnBnClickedButton1();
+
+ __super::OnOK();
+}
diff --git a/src/apps/mplayerc/PnSPresetsDlg.h b/src/apps/mplayerc/PnSPresetsDlg.h
new file mode 100644
index 000000000..8e89d2de2
--- /dev/null
+++ b/src/apps/mplayerc/PnSPresetsDlg.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "FloatEdit.h"
+
+// CPnSPresetsDlg dialog
+
+class CPnSPresetsDlg : public CCmdUIDialog
+{
+ DECLARE_DYNAMIC(CPnSPresetsDlg)
+
+private:
+ void StringToParams(CString str, CString& label, double& PosX, double& PosY, double& ZoomX, double& ZoomY);
+ CString ParamsToString(CString label, double PosX, double PosY, double ZoomX, double ZoomY);
+
+public:
+ CPnSPresetsDlg(CWnd* pParent = NULL); // standard constructor
+ virtual ~CPnSPresetsDlg();
+
+ CStringArray m_pnspresets;
+
+// Dialog Data
+ enum { IDD = IDD_PNSPRESET_DLG };
+ CFloatEdit m_PosX;
+ CFloatEdit m_PosY;
+ CFloatEdit m_ZoomX;
+ CFloatEdit m_ZoomY;
+ CString m_label;
+ CListBox m_list;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+
+ DECLARE_MESSAGE_MAP()
+public:
+ afx_msg void OnLbnSelchangeList1();
+ afx_msg void OnBnClickedButton2();
+ afx_msg void OnUpdateButton2(CCmdUI* pCmdUI);
+ afx_msg void OnBnClickedButton6();
+ afx_msg void OnUpdateButton6(CCmdUI* pCmdUI);
+ afx_msg void OnBnClickedButton9();
+ afx_msg void OnUpdateButton9(CCmdUI* pCmdUI);
+ afx_msg void OnBnClickedButton10();
+ afx_msg void OnUpdateButton10(CCmdUI* pCmdUI);
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnUpdateButton1(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/QuicktimeGraph.cpp b/src/apps/mplayerc/QuicktimeGraph.cpp
new file mode 100644
index 000000000..047e0e53c
--- /dev/null
+++ b/src/apps/mplayerc/QuicktimeGraph.cpp
@@ -0,0 +1,652 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include <math.h>
+#include "QuicktimeGraph.h"
+#include "IQTVideoSurface.h"
+#include "mplayerc.h"
+#include "..\..\DSUtil\DSUtil.h"
+
+//
+// CQuicktimeGraph
+//
+
+#pragma warning(disable:4355) // 'this' : used in base member initializer list
+
+using namespace QT;
+
+CQuicktimeGraph::CQuicktimeGraph(HWND hWndParent, HRESULT& hr)
+ : CBaseGraph()
+ , m_wndDestFrame(this)
+ , m_fQtInitialized(false)
+{
+ hr = S_OK;
+
+ DWORD dwStyle = WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
+
+ AppSettings& s = AfxGetAppSettings();
+
+ if(s.iQTVideoRendererType == VIDRNDT_QT_DX7)
+ {
+ if(SUCCEEDED(CreateAP7(CLSID_QT7AllocatorPresenter, hWndParent, &m_pQTAP)))
+ dwStyle &= ~WS_VISIBLE;
+ }
+ else if(s.iQTVideoRendererType == VIDRNDT_QT_DX9)
+ {
+ if(SUCCEEDED(CreateAP9(CLSID_QT9AllocatorPresenter, hWndParent, &m_pQTAP)))
+ dwStyle &= ~WS_VISIBLE;
+ }
+
+ m_fQtInitialized = false;
+ if(InitializeQTML(0) != 0) {hr = E_FAIL; return;}
+ if(EnterMovies() != 0) {TerminateQTML(); hr = E_FAIL; return;}
+ m_fQtInitialized = true;
+
+ if(!m_wndWindowFrame.CreateEx(WS_EX_NOPARENTNOTIFY, NULL, NULL, dwStyle, CRect(0, 0, 0, 0), CWnd::FromHandle(hWndParent), 0))
+ {
+ hr = E_FAIL;
+ return;
+ }
+
+ if(!m_wndDestFrame.Create(NULL, NULL, dwStyle, CRect(0, 0, 0, 0), &m_wndWindowFrame, 0))
+ {
+ hr = E_FAIL;
+ return;
+ }
+}
+
+CQuicktimeGraph::~CQuicktimeGraph()
+{
+ m_wndDestFrame.DestroyWindow();
+ m_wndWindowFrame.DestroyWindow();
+
+ if(m_fQtInitialized)
+ {
+ ExitMovies();
+ TerminateQTML();
+ }
+}
+
+STDMETHODIMP CQuicktimeGraph::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ CheckPointer(ppv, E_POINTER);
+
+ return
+ QI(IVideoFrameStep)
+ (m_pQTAP && (riid == __uuidof(ISubPicAllocatorPresenter) || riid == __uuidof(IQTVideoSurface))) ? m_pQTAP->QueryInterface(riid, ppv) :
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+// IGraphBuilder
+STDMETHODIMP CQuicktimeGraph::RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList)
+{
+ bool fRet = m_wndDestFrame.OpenMovie(CString(lpcwstrFile));
+
+ if(fRet)
+ {
+ for(int i = 1, cnt = GetMovieTrackCount(m_wndDestFrame.theMovie); i <= cnt; i++)
+ {
+ Track aTrack = GetMovieIndTrack(m_wndDestFrame.theMovie, i);
+ Media aMedia = GetTrackMedia(aTrack);
+
+ OSType aTrackType;
+ GetMediaHandlerDescription(aMedia, &aTrackType, 0, 0);
+ if(aTrackType == SoundMediaType)
+ {
+ SampleDescriptionHandle aDesc = (SampleDescriptionHandle)NewHandle(sizeof(aDesc));
+ GetMediaSampleDescription(aMedia, 1, aDesc);
+ if(GetMoviesError() == noErr)
+ {
+ SoundDescription& desc = **(SoundDescriptionHandle)aDesc;
+ NotifyEvent(EC_BG_AUDIO_CHANGED, desc.numChannels, 0);
+ i = cnt;
+ }
+ DisposeHandle((Handle)aDesc);
+ }
+ }
+ }
+
+ return fRet ? S_OK : E_FAIL;
+}
+
+// IMediaControl
+STDMETHODIMP CQuicktimeGraph::Run()
+{
+ m_wndDestFrame.Run();
+ return S_OK;
+}
+STDMETHODIMP CQuicktimeGraph::Pause()
+{
+ m_wndDestFrame.Pause();
+ return S_OK;
+}
+STDMETHODIMP CQuicktimeGraph::Stop()
+{
+ m_wndDestFrame.Stop();
+ return S_OK;
+}
+STDMETHODIMP CQuicktimeGraph::GetState(LONG msTimeout, OAFilterState* pfs)
+{
+ // TODO: this seems to deadlock when opening from the net
+ return pfs ? *pfs = m_wndDestFrame.GetState(), S_OK : E_POINTER;
+}
+
+// IMediaSeeking
+STDMETHODIMP CQuicktimeGraph::GetDuration(LONGLONG* pDuration)
+{
+ CheckPointer(pDuration, E_POINTER);
+
+ *pDuration = 0;
+
+ if(!m_wndDestFrame.theMovie) return E_UNEXPECTED;
+
+ TimeScale ts = GetMovieTimeScale(m_wndDestFrame.theMovie);
+ if(ts == 0) return E_FAIL;
+
+ *pDuration = 10000i64*GetMovieDuration(m_wndDestFrame.theMovie)/ts*1000;
+
+ return S_OK;
+}
+STDMETHODIMP CQuicktimeGraph::GetCurrentPosition(LONGLONG* pCurrent)
+{
+ CheckPointer(pCurrent, E_POINTER);
+
+ *pCurrent = 0;
+
+ if(!m_wndDestFrame.theMovie) return E_UNEXPECTED;
+
+ TimeScale ts = GetMovieTimeScale(m_wndDestFrame.theMovie);
+ if(ts == 0) return E_FAIL;
+
+ TimeRecord tr;
+ *pCurrent = 10000i64*GetMovieTime(m_wndDestFrame.theMovie, &tr)/ts*1000;
+
+ return S_OK;
+}
+STDMETHODIMP CQuicktimeGraph::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)
+{
+ CheckPointer(pCurrent, E_POINTER);
+
+ if(!(dwCurrentFlags&AM_SEEKING_AbsolutePositioning)) return E_INVALIDARG;
+
+ if(!m_wndDestFrame.theMovie) return E_UNEXPECTED;
+
+ TimeScale ts = GetMovieTimeScale(m_wndDestFrame.theMovie);
+ if(ts == 0) return E_FAIL;
+
+ SetMovieTimeValue(m_wndDestFrame.theMovie, (TimeValue)(*pCurrent*ts/1000/10000i64));
+
+ if(!m_wndDestFrame.theMC)
+ {
+ UpdateMovie(m_wndDestFrame.theMovie);
+ MoviesTask(m_wndDestFrame.theMovie, 0L);
+ }
+
+ return S_OK;
+}
+STDMETHODIMP CQuicktimeGraph::SetRate(double dRate)
+{
+ return m_wndDestFrame.theMovie ? SetMovieRate(m_wndDestFrame.theMovie, (Fixed)(dRate * 0x10000)), S_OK : E_UNEXPECTED;
+}
+STDMETHODIMP CQuicktimeGraph::GetRate(double* pdRate)
+{
+ CheckPointer(pdRate, E_POINTER);
+ *pdRate = 1.0;
+ return m_wndDestFrame.theMovie ? *pdRate = (double)GetMovieRate(m_wndDestFrame.theMovie) / 0x10000, S_OK : E_UNEXPECTED;
+}
+
+// IVideoWindow
+STDMETHODIMP CQuicktimeGraph::SetWindowPosition(long Left, long Top, long Width, long Height)
+{
+ if(IsWindow(m_wndWindowFrame.m_hWnd))
+ m_wndWindowFrame.MoveWindow(Left, Top, Width, Height);
+
+ return S_OK;
+}
+
+// IBasicVideo
+STDMETHODIMP CQuicktimeGraph::SetDestinationPosition(long Left, long Top, long Width, long Height)// {return E_NOTIMPL;}
+{
+ if(!m_pQTAP && IsWindow(m_wndDestFrame.m_hWnd))
+ {
+ m_wndDestFrame.MoveWindow(Left, Top, Width, Height);
+
+ if(m_wndDestFrame.theMC)
+ {
+ Rect bounds = {0,0,(short)Height,(short)Width};
+ MCPositionController(m_wndDestFrame.theMC, &bounds, NULL, mcTopLeftMovie|mcScaleMovieToFit);
+ }
+ }
+
+ return S_OK;
+}
+STDMETHODIMP CQuicktimeGraph::GetVideoSize(long* pWidth, long* pHeight)
+{
+ if(!pWidth || !pHeight) return E_POINTER;
+
+ *pWidth = m_wndDestFrame.m_size.cx;
+ *pHeight = m_wndDestFrame.m_size.cy;
+
+ return S_OK;
+}
+
+// IBasicAudio
+STDMETHODIMP CQuicktimeGraph::put_Volume(long lVolume)
+{
+ if(m_wndDestFrame.theMovie)
+ {
+ lVolume = (lVolume == -10000) ? 0 : (int)pow(10.0, (double)lVolume/4152.41 + 2.41);
+ SetMovieVolume(m_wndDestFrame.theMovie, (short)max(min(lVolume, 256), 0));
+ return S_OK;
+ }
+
+ return E_UNEXPECTED;
+}
+STDMETHODIMP CQuicktimeGraph::get_Volume(long* plVolume)
+{
+ CheckPointer(plVolume, E_POINTER);
+
+ if(m_wndDestFrame.theMovie)
+ {
+ long lVolume = (long)GetMovieVolume(m_wndDestFrame.theMovie);
+ *plVolume = (int)((log10(1.0*lVolume)-2.41)*4152.41);
+ *plVolume = max(min(*plVolume, 0), -10000);
+ return S_OK;
+ }
+
+ return E_UNEXPECTED;
+}
+
+// IVideoFrameStep
+STDMETHODIMP CQuicktimeGraph::Step(DWORD dwFrames, IUnknown* pStepObject)
+{
+ if(pStepObject) return E_INVALIDARG;
+ if(dwFrames == 0) return S_OK;
+ if(!m_wndDestFrame.theMovie) return E_UNEXPECTED;
+
+ // w/o m_wndDestFrame.theMC
+
+ OSType myTypes[] = {VisualMediaCharacteristic};
+ TimeValue myCurrTime = GetMovieTime(m_wndDestFrame.theMovie, NULL);
+ Fixed theRate = (int)dwFrames > 0 ? 0x00010000 : 0xffff0000;
+
+ for(int nSteps = abs((int)dwFrames); nSteps > 0; nSteps--)
+ {
+ TimeValue myNextTime;
+ GetMovieNextInterestingTime(m_wndDestFrame.theMovie, nextTimeStep, 1, myTypes, myCurrTime, theRate, &myNextTime, NULL);
+ if(GetMoviesError() != noErr) return E_FAIL;
+ myCurrTime = myNextTime;
+ }
+
+ if(myCurrTime >= 0 && myCurrTime < GetMovieDuration(m_wndDestFrame.theMovie))
+ {
+ SetMovieTimeValue(m_wndDestFrame.theMovie, myCurrTime);
+ if(GetMoviesError() != noErr) return E_FAIL;
+ // the rest is not needed when we also have m_wndDestFrame.theMC:
+ UpdateMovie(m_wndDestFrame.theMovie);
+ if(GetMoviesError() != noErr) return E_FAIL;
+ MoviesTask(m_wndDestFrame.theMovie, 0L);
+ }
+
+ NotifyEvent(EC_STEP_COMPLETE);
+
+ return S_OK;
+
+/*
+ // w/ m_wndDestFrame.theMC
+
+ short myStep = (short)(long)dwFrames;
+ return noErr == MCDoAction(m_wndDestFrame.theMC, mcActionStep, (Ptr)myStep)
+ ? NotifyEvent(EC_STEP_COMPLETE), S_OK : E_FAIL;
+*/
+}
+STDMETHODIMP CQuicktimeGraph::CanStep(long bMultiple, IUnknown* pStepObject)
+{
+ return m_wndDestFrame.theMovie ? S_OK : S_FALSE;
+}
+STDMETHODIMP CQuicktimeGraph::CancelStep()
+{
+ return E_NOTIMPL;
+}
+
+// IGraphEngine
+STDMETHODIMP_(engine_t) CQuicktimeGraph::GetEngine() {return QuickTime;}
+
+//
+// CQuicktimeWindow
+//
+
+CQuicktimeWindow::CQuicktimeWindow(CQuicktimeGraph* pGraph)
+ : m_pGraph(pGraph)
+ , theMovie(NULL)
+ , theMC(NULL)
+ , m_size(0, 0)
+ , m_idEndPoller(0)
+ , m_fs(State_Stopped)
+ , m_offscreenGWorld(NULL)
+{
+}
+
+void CQuicktimeWindow::ProcessMovieEvent(unsigned int message, unsigned int wParam, long lParam)
+{
+ if(message >= WM_MOUSEFIRST && message <= WM_MOUSELAST
+ || message >= WM_KEYFIRST && message <= WM_KEYLAST)
+ return;
+
+ // Convert the Windows event to a QTML event
+ MSG theMsg;
+ EventRecord macEvent;
+ LONG thePoints = GetMessagePos();
+
+ theMsg.hwnd = m_hWnd;
+ theMsg.message = message;
+ theMsg.wParam = wParam;
+ theMsg.lParam = lParam;
+ theMsg.time = GetMessageTime();
+ theMsg.pt.x = LOWORD(thePoints);
+ theMsg.pt.y = HIWORD(thePoints);
+
+ // tranlate a windows event to a mac event
+ WinEventToMacEvent(&theMsg, &macEvent);
+
+ // Pump messages as mac event
+ MCIsPlayerEvent(theMC, (const EventRecord*)&macEvent);
+}
+
+LRESULT CQuicktimeWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if(message == WM_ERASEBKGND)
+ {
+ LRESULT theResult = __super::WindowProc(message, wParam, lParam);
+ ProcessMovieEvent(message, wParam, lParam);
+ return theResult;
+ }
+ else
+ {
+ ProcessMovieEvent(message, wParam, lParam);
+ return __super::WindowProc(message, wParam, lParam);
+ }
+}
+
+OSErr CQuicktimeWindow::MyMovieDrawingCompleteProc(Movie theMovie, long refCon)
+{
+ CQuicktimeWindow* pQW = (CQuicktimeWindow*)refCon;
+ if(!pQW) return noErr;
+
+ CQuicktimeGraph* pGraph = pQW->m_pGraph;
+ if(!pGraph) return noErr;
+
+ if(CComQIPtr<IQTVideoSurface> pQTVS = (IUnknown*)(INonDelegatingUnknown*)pGraph)
+ {
+ BITMAP bm;
+ pQW->m_bm.GetObject(sizeof(bm), &bm);
+ pQTVS->DoBlt(bm);
+ }
+ /*
+ else
+ {
+ pQW->Invalidate();
+ }*/
+
+ return(noErr);
+}
+
+bool CQuicktimeWindow::OpenMovie(CString fn)
+{
+ CloseMovie();
+
+ CComQIPtr<IQTVideoSurface> pQTVS = (IUnknown*)(INonDelegatingUnknown*)m_pGraph;
+
+ if(!pQTVS)
+ {
+ // Set the port
+ SetGWorld((CGrafPtr)GetHWNDPort(m_hWnd), NULL);
+ }
+
+ if(fn.Find(_T("://")) > 0)
+ {
+ Handle myHandle = NULL;
+ Size mySize = fn.GetLength()+1;
+
+ if(!(myHandle = NewHandleClear(mySize)))
+ return(false);
+
+ BlockMove((LPSTR)(LPCSTR)CStringA(fn), *myHandle, mySize);
+
+ OSErr err = NewMovieFromDataRef(&theMovie, newMovieActive, NULL, myHandle, URLDataHandlerSubType);
+
+ DisposeHandle(myHandle);
+
+ if(err != noErr) return(false);
+ }
+ else
+ {
+ if(!(fn.GetLength() > 0 && fn.GetLength() < 255))
+ return(false);
+
+ CHAR buff[MAX_PATH] = {0, 0};
+#ifdef UNICODE
+ WideCharToMultiByte(GetACP(), 0, fn, -1, buff+1, MAX_PATH-1, 0, 0);
+#else
+ strcpy(buff+1, fn);
+#endif
+ buff[0] = strlen(buff+1);
+
+ // Make a FSSpec with a pascal string filename
+ FSSpec sfFile;
+ FSMakeFSSpec(0, 0L, (BYTE*)buff, &sfFile);
+
+ // Open the movie file
+ short movieResFile;
+ OSErr err = OpenMovieFile(&sfFile, &movieResFile, fsRdPerm);
+ if(err == noErr)
+ {
+ err = NewMovieFromFile(&theMovie, movieResFile, 0, 0, newMovieActive, 0);
+ CloseMovieFile(movieResFile);
+ }
+ if(err != noErr) return(false);
+ }
+
+ Rect rect;
+ GetMovieBox(theMovie, &rect);
+ MacOffsetRect(&rect, -rect.left, -rect.top);
+ SetMovieBox(theMovie, &rect);
+ m_size.SetSize(rect.right - rect.left, rect.bottom - rect.top);
+
+ Rect nrect;
+ GetMovieNaturalBoundsRect(theMovie, &nrect);
+
+ if(!pQTVS)
+ {
+ theMC = NewMovieController(theMovie, &rect, mcTopLeftMovie|mcNotVisible);
+ }
+ else if(m_size.cx > 0 && m_size.cy > 0)
+ {
+ SetMovieDrawingCompleteProc(theMovie,
+ movieDrawingCallWhenChanged,//|movieDrawingCallAlways,
+ MyMovieDrawingCompleteProc, (long)this);
+
+ if(CDC* pDC = GetDC())
+ {
+ m_dc.CreateCompatibleDC(pDC);
+ ReleaseDC(pDC);
+
+ struct
+ {
+ BITMAPINFOHEADER bmiHeader;
+ long bmiColors[256];
+ } bmi;
+
+ memset(&bmi, 0, sizeof(bmi));
+
+ int bpp = m_dc.GetDeviceCaps(BITSPIXEL);
+
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biCompression = BI_BITFIELDS/*BI_RGB*/;
+ bmi.bmiHeader.biWidth = m_size.cx;
+ bmi.bmiHeader.biHeight = -m_size.cy;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32/*bpp*/;
+
+ bmi.bmiColors[0] = /*bpp == 16 ? 0xf800 :*/ 0xff0000;
+ bmi.bmiColors[1] = /*bpp == 16 ? 0x07e0 :*/ 0x00ff00;
+ bmi.bmiColors[2] = /*bpp == 16 ? 0x001f :*/ 0x0000ff;
+
+ void* bits;
+ m_bm.Attach(CreateDIBSection(m_dc, (BITMAPINFO*)&bmi, DIB_RGB_COLORS, &bits, NULL, 0));
+
+ QDErr err = NewGWorldFromHBITMAP(&m_offscreenGWorld, NULL, NULL, 0, m_bm.m_hObject, m_dc.m_hDC);
+
+ SetMovieGWorld(theMovie, m_offscreenGWorld, GetGWorldDevice(m_offscreenGWorld));
+
+ BITMAP bm;
+ m_bm.GetObject(sizeof(bm), &bm);
+ pQTVS->BeginBlt(bm);
+ }
+ }
+
+ return(theMovie != NULL);
+}
+
+void CQuicktimeWindow::CloseMovie()
+{
+ if(theMC) DisposeMovieController(theMC), theMC = NULL;
+ if(theMovie) DisposeMovie(theMovie), theMovie = NULL;
+ m_size.SetSize(0, 0);
+ m_fs = State_Stopped;
+
+ if(m_offscreenGWorld) DisposeGWorld(m_offscreenGWorld), m_offscreenGWorld = NULL;
+ m_dc.DeleteDC();
+ m_bm.DeleteObject();
+}
+
+void CQuicktimeWindow::Run()
+{
+ if(theMovie)
+ {
+ StartMovie(theMovie);
+ if(!m_idEndPoller) m_idEndPoller = SetTimer(1, 10, NULL); // 10ms -> 100fps max
+ }
+
+ m_fs = State_Running;
+}
+
+void CQuicktimeWindow::Pause()
+{
+ if(theMovie)
+ {
+ StopMovie(theMovie);
+ if(m_idEndPoller) KillTimer(m_idEndPoller), m_idEndPoller = 0;
+ }
+
+ m_fs = State_Paused;
+}
+
+void CQuicktimeWindow::Stop()
+{
+ if(theMovie)
+ {
+ StopMovie(theMovie);
+ GoToBeginningOfMovie(theMovie);
+ if(m_idEndPoller) KillTimer(m_idEndPoller), m_idEndPoller = 0;
+ }
+
+ m_fs = State_Stopped;
+}
+
+FILTER_STATE CQuicktimeWindow::GetState()
+{
+ return m_fs;
+}
+
+BEGIN_MESSAGE_MAP(CQuicktimeWindow, CPlayerWindow)
+ ON_WM_CREATE()
+ ON_WM_DESTROY()
+ ON_WM_ERASEBKGND()
+ ON_WM_TIMER()
+END_MESSAGE_MAP()
+
+int CQuicktimeWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if(__super::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ CComQIPtr<IQTVideoSurface> pQTVS = (IUnknown*)(INonDelegatingUnknown*)m_pGraph;
+
+ if(!pQTVS)
+ {
+ // Create GrafPort <-> HWND association
+ CreatePortAssociation(m_hWnd, NULL, 0);
+ }
+
+ return 0;
+}
+
+void CQuicktimeWindow::OnDestroy()
+{
+ CPlayerWindow::OnDestroy();
+
+ // close any movies before destroying PortAssocation
+ CloseMovie();
+
+ CComQIPtr<IQTVideoSurface> pQTVS = (IUnknown*)(INonDelegatingUnknown*)m_pGraph;
+
+ if(!pQTVS)
+ {
+ // Destroy the view's GrafPort <-> HWND association
+ if(m_hWnd)
+ if(CGrafPtr windowPort = (CGrafPtr)GetHWNDPort(m_hWnd))
+ DestroyPortAssociation(windowPort);
+ }
+}
+
+BOOL CQuicktimeWindow::OnEraseBkgnd(CDC* pDC)
+{
+ return m_fs != State_Stopped && theMovie ? TRUE : __super::OnEraseBkgnd(pDC);
+}
+
+void CQuicktimeWindow::OnTimer(UINT nIDEvent)
+{
+ if(nIDEvent == m_idEndPoller && theMovie)
+ {
+ if(IsMovieDone(theMovie))
+ {
+ Pause();
+ m_pGraph->NotifyEvent(EC_COMPLETE);
+ }
+ else if(CComQIPtr<IQTVideoSurface> pQTVS = (IUnknown*)(INonDelegatingUnknown*)m_pGraph)
+ {
+ MoviesTask(theMovie, 0);
+/*
+ long duration = 0, scale = 1000;
+ OSErr err = QTGetTimeUntilNextTask(&duration, scale);
+
+ // err is 0 but still doesn't seem to work... returns duration=0 always
+ TRACE(_T("%d\n"), duration);
+ KillTimer(m_idEndPoller);
+ m_idEndPoller = SetTimer(m_idEndPoller, duration, NULL);
+*/
+ }
+ }
+
+ __super::OnTimer(nIDEvent);
+}
diff --git a/src/apps/mplayerc/QuicktimeGraph.h b/src/apps/mplayerc/QuicktimeGraph.h
new file mode 100644
index 000000000..222169c12
--- /dev/null
+++ b/src/apps/mplayerc/QuicktimeGraph.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "BaseGraph.h"
+#include "DX7AllocatorPresenter.h"
+#include "DX9AllocatorPresenter.h"
+
+namespace DSObjects
+{
+
+class CQuicktimeGraph;
+
+class CQuicktimeWindow : public CPlayerWindow
+{
+ CDC m_dc;
+ CBitmap m_bm;
+ QT::GWorldPtr m_offscreenGWorld;
+
+ CQuicktimeGraph* m_pGraph;
+ FILTER_STATE m_fs;
+ UINT m_idEndPoller;
+
+ static QT::OSErr MyMovieDrawingCompleteProc(QT::Movie theMovie, long refCon);
+
+ void ProcessMovieEvent(unsigned int message, unsigned int wParam, long lParam);
+
+protected:
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
+
+public:
+ CQuicktimeWindow(CQuicktimeGraph* pGraph);
+
+ bool OpenMovie(CString fn);
+ void CloseMovie();
+
+ void Run(), Pause(), Stop();
+ FILTER_STATE GetState();
+
+ QT::Movie theMovie;
+ QT::MovieController theMC;
+ CSize m_size;
+
+public:
+ DECLARE_MESSAGE_MAP()
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnDestroy();
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ afx_msg void OnTimer(UINT nIDEvent);
+};
+
+class CQuicktimeGraph : public CBaseGraph, public IVideoFrameStep
+{
+protected:
+ bool m_fQtInitialized;
+
+ CPlayerWindow m_wndWindowFrame;
+ CQuicktimeWindow m_wndDestFrame;
+
+ CComPtr<ISubPicAllocatorPresenter> m_pQTAP;
+
+public:
+ CQuicktimeGraph(HWND hParent, HRESULT& hr);
+ virtual ~CQuicktimeGraph();
+
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+protected:
+ // IGraphBuilder
+ STDMETHODIMP RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList);
+
+ // IMediaControl
+ STDMETHODIMP Run();
+ STDMETHODIMP Pause();
+ STDMETHODIMP Stop();
+ STDMETHODIMP GetState(LONG msTimeout, OAFilterState* pfs);
+
+ // IMediaSeeking
+ STDMETHODIMP GetDuration(LONGLONG* pDuration);
+ STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
+ STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
+ STDMETHODIMP SetRate(double dRate);
+ STDMETHODIMP GetRate(double* pdRate);
+
+ // IVideoWindow
+ STDMETHODIMP SetWindowPosition(long Left, long Top, long Width, long Height);
+
+ // IBasicVideo
+ STDMETHODIMP SetDestinationPosition(long Left, long Top, long Width, long Height);
+ STDMETHODIMP GetVideoSize(long* pWidth, long* pHeight);
+
+ // IBasicAudio
+ STDMETHODIMP put_Volume(long lVolume);
+ STDMETHODIMP get_Volume(long* plVolume);
+
+ // IVideoFrameStep
+ STDMETHODIMP Step(DWORD dwFrames, IUnknown* pStepObject);
+ STDMETHODIMP CanStep(long bMultiple, IUnknown* pStepObject);
+ STDMETHODIMP CancelStep();
+
+ // IGraphEngine
+ STDMETHODIMP_(engine_t) GetEngine();
+};
+
+}
+using namespace DSObjects; \ No newline at end of file
diff --git a/src/apps/mplayerc/RealMediaGraph.cpp b/src/apps/mplayerc/RealMediaGraph.cpp
new file mode 100644
index 000000000..719b5282c
--- /dev/null
+++ b/src/apps/mplayerc/RealMediaGraph.cpp
@@ -0,0 +1,714 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include <math.h>
+#include <atlbase.h>
+#include <atlcoll.h>
+#include <initguid.h>
+#include "RealMediaGraph.h"
+#include "RealMediaWindowlessSite.h"
+#include "..\..\..\include\RealMedia\rmavsurf.h"
+#include "..\..\..\include\RealMedia\rmaevent.h"
+#include "..\..\..\include\RealMedia\rmaprefs.h"
+#include "..\..\DSUtil\DSUtil.h"
+#include "AuthDlg.h"
+
+// CRealMediaPlayer
+
+CRealMediaPlayer::CRealMediaPlayer(HWND hWndParent, CRealMediaGraph* pRMG)
+ : CUnknown(NAME("CRealMediaPlayer"), NULL)
+ , m_pRMG(pRMG)
+ , m_hWndParent(hWndParent)
+ , m_fpCreateEngine(NULL), m_fpCloseEngine(NULL), m_hRealMediaCore(NULL)
+ , m_State(State_Stopped), m_UserState(State_Stopped), m_nCurrent(0), m_nDuration(0)
+ , m_VideoSize(0, 0)
+ , m_fVideoSizeChanged(true)
+{
+}
+
+CRealMediaPlayer::~CRealMediaPlayer()
+{
+ Deinit();
+}
+
+bool CRealMediaPlayer::Init()
+{
+ CString prefs(_T("Software\\RealNetworks\\Preferences"));
+
+ CRegKey key;
+
+ if(ERROR_SUCCESS != key.Open(HKEY_CLASSES_ROOT, prefs + _T("\\DT_Common"), KEY_READ))
+ return(false);
+
+ TCHAR buff[MAX_PATH];
+ ULONG len = sizeof(buff);
+ if(ERROR_SUCCESS != key.QueryStringValue(NULL, buff, &len))
+ return(false);
+
+ key.Close();
+
+ if(!(m_hRealMediaCore = LoadLibrary(CString(buff) + _T("pnen3260.dll"))))
+ return(false);
+
+ m_fpCreateEngine = (FPRMCREATEENGINE)GetProcAddress(m_hRealMediaCore, "CreateEngine");
+ m_fpCloseEngine = (FPRMCLOSEENGINE)GetProcAddress(m_hRealMediaCore, "CloseEngine");
+ m_fpSetDLLAccessPath = (FPRMSETDLLACCESSPATH)GetProcAddress(m_hRealMediaCore, "SetDLLAccessPath");
+
+ if(!m_fpCreateEngine || !m_fpCloseEngine || !m_fpSetDLLAccessPath)
+ return(false);
+
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, prefs, KEY_READ))
+ {
+ CString dllpaths;
+
+ len = sizeof(buff);
+ for(int i = 0; ERROR_SUCCESS == key.EnumKey(i, buff, &len); i++, len = sizeof(buff))
+ {
+ CRegKey key2;
+ TCHAR buff2[MAX_PATH];
+ ULONG len2 = sizeof(buff2);
+ if(ERROR_SUCCESS != key2.Open(HKEY_CLASSES_ROOT, prefs + _T("\\") + buff, KEY_READ)
+ || ERROR_SUCCESS != key2.QueryStringValue(NULL, buff2, &len2))
+ continue;
+
+ dllpaths += CString(buff) + '=' + buff2 + '|';
+ }
+
+ key.Close();
+
+ if(!dllpaths.IsEmpty())
+ {
+ char* s = new char[dllpaths.GetLength()+1];
+ strcpy(s, CStringA(dllpaths));
+ for(int i = 0, j = strlen(s); i < j; i++) {if(s[i] == '|') s[i] = '\0';}
+ m_fpSetDLLAccessPath(s);
+ delete [] s;
+ }
+ }
+
+ if(PNR_OK != m_fpCreateEngine(&m_pEngine))
+ return(false);
+
+ if(PNR_OK != m_pEngine->CreatePlayer(*&m_pPlayer))
+ return(false);
+
+ if(!(m_pSiteManager = m_pPlayer) || !(m_pCommonClassFactory = m_pPlayer))
+ return(false);
+
+ m_pAudioPlayer = m_pPlayer;
+ m_pAudioPlayer->AddPostMixHook(static_cast<IRMAAudioHook*>(this), FALSE, FALSE);
+// m_pVolume = m_pAudioPlayer->GetDeviceVolume();
+ m_pVolume = m_pAudioPlayer->GetAudioVolume();
+
+ // IRMAVolume::SetVolume has a huge latency when used via GetAudioVolume,
+ // but by lowering this audio pushdown thing it can get better
+ CComQIPtr<IRMAAudioPushdown, &IID_IRMAAudioPushdown> pAP = m_pAudioPlayer;
+ if(pAP) pAP->SetAudioPushdown(300); // 100ms makes the playback sound choppy, 200ms looks ok, but for safety we set this to 300ms... :P
+
+ CComQIPtr<IRMAErrorSinkControl, &IID_IRMAErrorSinkControl> pErrorSinkControl = m_pPlayer;
+ if(pErrorSinkControl) pErrorSinkControl->AddErrorSink(static_cast<IRMAErrorSink*>(this), PNLOG_EMERG, PNLOG_INFO);
+
+ if(PNR_OK != m_pPlayer->AddAdviseSink(static_cast<IRMAClientAdviseSink*>(this)))
+ return(false);
+
+ if(PNR_OK != m_pPlayer->SetClientContext((IUnknown*)(INonDelegatingUnknown*)(this)))
+ return(false);
+
+ // TODO
+/*
+ if(CComQIPtr<IRMAPreferences, &IID_IRMAPreferences> pPrefs = m_pPlayer)
+ {
+ CComPtr<IRMABuffer> pBuffer;
+ HRESULT hr = pPrefs->ReadPref("HTTPProxyHost", *&pBuffer);
+
+ UCHAR* pData = NULL;
+ ULONG32 ulLength = 0;
+ hr = pBuffer->Get(pData, ulLength);
+
+ pBuffer = NULL;
+ hr = m_pCommonClassFactory->CreateInstance(CLSID_IRMABuffer, (void**)&pBuffer);
+ hr = pBuffer->SetSize(strlen("localhost")+1);
+ pData = pBuffer->GetBuffer();
+ strcpy((char*)pData, "localhost");
+ hr = pBuffer->Set(pData, strlen("localhost")+1);
+
+ pData = NULL;
+ ulLength = 0;
+ hr = pBuffer->Get(pData, ulLength);
+
+ hr = pPrefs->WritePref("HTTPProxyHost", pBuffer);
+
+ hr = hr;
+ }
+*/
+ return(true);
+}
+
+void CRealMediaPlayer::Deinit()
+{
+ if(m_pPlayer)
+ {
+ m_pPlayer->Stop();
+
+ CComQIPtr<IRMAErrorSinkControl, &IID_IRMAErrorSinkControl> pErrorSinkControl = m_pPlayer;
+ if(pErrorSinkControl) pErrorSinkControl->RemoveErrorSink(static_cast<IRMAErrorSink*>(this));
+
+ m_pPlayer->RemoveAdviseSink(static_cast<IRMAClientAdviseSink*>(this));
+
+ m_pVolume = NULL;
+ m_pAudioPlayer->RemovePostMixHook(static_cast<IRMAAudioHook*>(this));
+ m_pAudioPlayer.Release();
+
+ m_pEngine->ClosePlayer(m_pPlayer);
+
+ m_pSiteManager.Release();
+ m_pCommonClassFactory.Release();
+
+ m_pPlayer = NULL;
+ }
+
+ if(m_pEngine)
+ {
+ m_fpCloseEngine(m_pEngine);
+ m_pEngine = NULL;
+ }
+
+ if(m_hRealMediaCore)
+ {
+ FreeLibrary(m_hRealMediaCore);
+ m_hRealMediaCore = NULL;
+ }
+}
+
+STDMETHODIMP CRealMediaPlayer::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ CheckPointer(ppv, E_POINTER);
+
+ return
+ QI2(IRMAErrorSink)
+ QI2(IRMAClientAdviseSink)
+ QI2(IRMAAuthenticationManager)
+ QI2(IRMASiteSupplier)
+ QI2(IRMAPassiveSiteWatcher)
+ QI2(IRMAAudioHook)
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+// IRMAErrorSink
+STDMETHODIMP CRealMediaPlayer::ErrorOccurred(const UINT8 unSeverity, const UINT32 ulRMACode, const UINT32 ulUserCode, const char* pUserString, const char* pMoreInfoURL)
+{
+ char* errmsg = NULL;
+
+ if(unSeverity < 5)
+ {
+ if(CComQIPtr<IRMAErrorMessages, &IID_IRMAErrorMessages> pErrorMessages = m_pPlayer)
+ {
+ CComPtr<IRMABuffer> pBuffer = pErrorMessages->GetErrorText(ulRMACode);
+ if(pBuffer)
+ {
+ char* buff = (char*)pBuffer->GetBuffer();
+ int len = strlen(buff);
+ if(len > 0 && (errmsg = (char*)CoTaskMemAlloc(len+1)))
+ strcpy(errmsg, buff);
+ }
+ }
+
+ if(!errmsg && (errmsg = (char*)CoTaskMemAlloc(strlen("RealMedia error")+1)))
+ strcpy(errmsg, "RealMedia error");
+
+ m_pRMG->NotifyEvent(EC_BG_ERROR, (LONG_PTR)errmsg, 0);
+ }
+
+ return PNR_OK;
+}
+
+// IRMAClientAdviseSink
+STDMETHODIMP CRealMediaPlayer::OnPosLength(UINT32 ulPosition, UINT32 ulLength)
+{
+ m_nCurrent = (REFERENCE_TIME)ulPosition*10000;
+ m_nDuration = (REFERENCE_TIME)ulLength*10000;
+ return PNR_OK;
+}
+STDMETHODIMP CRealMediaPlayer::OnPresentationOpened() {return PNR_OK;}
+STDMETHODIMP CRealMediaPlayer::OnPresentationClosed() {return PNR_OK;}
+STDMETHODIMP CRealMediaPlayer::OnStatisticsChanged()
+{
+ m_pRMG->NotifyEvent(EC_LENGTH_CHANGED);
+ return PNR_OK;
+}
+STDMETHODIMP CRealMediaPlayer::OnPreSeek(UINT32 ulOldTime, UINT32 ulNewTime)
+{
+ m_nCurrent = (REFERENCE_TIME)ulNewTime*10000;
+ return PNR_OK;
+}
+STDMETHODIMP CRealMediaPlayer::OnPostSeek(UINT32 ulOldTime, UINT32 ulNewTime)
+{
+ m_nCurrent = (REFERENCE_TIME)ulNewTime*10000;
+ return PNR_OK;
+}
+STDMETHODIMP CRealMediaPlayer::OnStop()
+{
+ m_nCurrent = 0;
+ m_State = State_Stopped;
+ if(m_UserState != State_Stopped)
+ m_pRMG->NotifyEvent(EC_COMPLETE);
+ return PNR_OK;
+}
+STDMETHODIMP CRealMediaPlayer::OnPause(UINT32 ulTime)
+{
+ m_State = State_Paused;
+ return PNR_OK;
+}
+STDMETHODIMP CRealMediaPlayer::OnBegin(UINT32 ulTime)
+{
+ m_State = State_Running;
+ return PNR_OK;
+}
+STDMETHODIMP CRealMediaPlayer::OnBuffering(UINT32 ulFlags, UINT16 unPercentComplete)
+{
+ m_unPercentComplete = unPercentComplete;
+ return PNR_OK;
+}
+STDMETHODIMP CRealMediaPlayer::OnContacting(const char* pHostName) {return PNR_OK;}
+
+// IRMAAuthenticationManager
+STDMETHODIMP CRealMediaPlayer::HandleAuthenticationRequest(IRMAAuthenticationManagerResponse* pResponse)
+{
+ CAuthDlg dlg;
+
+ if(dlg.DoModal() == IDOK)
+ {
+ pResponse->AuthenticationRequestDone(
+ PNR_OK, CStringA(dlg.m_username), CStringA(dlg.m_password));
+ return PNR_OK;
+ }
+
+ return pResponse->AuthenticationRequestDone(PNR_NOT_AUTHORIZED, NULL, NULL);
+}
+
+// IRMASiteSupplier
+STDMETHODIMP CRealMediaPlayer::SitesNeeded(UINT32 uRequestID, IRMAValues* pProps)
+{
+ if(!pProps) return PNR_INVALID_PARAMETER;
+
+ if(m_pTheSite || m_pTheSite2 || !m_hWndParent) return PNR_UNEXPECTED;
+
+ HRESULT hr = PNR_OK;
+
+ if(!CreateSite(&m_pTheSite))
+ return E_FAIL;
+
+ ULONG refc = ((IRMASite*)m_pTheSite)->AddRef();
+ refc = ((IRMASite*)m_pTheSite)->Release();
+
+ if(!(m_pTheSite2 = m_pTheSite))
+ return E_NOINTERFACE;
+
+ CComQIPtr<IRMAValues, &IID_IRMAValues> pSiteProps = m_pTheSite;
+ if(!pSiteProps)
+ return E_NOINTERFACE;
+
+ IRMABuffer* pValue;
+
+ // no idea what these supposed to do... but they were in the example
+ hr = pProps->GetPropertyCString("playto", pValue);
+ if(PNR_OK == hr)
+ {
+ pSiteProps->SetPropertyCString("channel", pValue);
+ pValue->Release();
+ }
+ else
+ {
+ hr = pProps->GetPropertyCString("name", pValue);
+ if(PNR_OK == hr)
+ {
+ pSiteProps->SetPropertyCString("LayoutGroup", pValue);
+ pValue->Release();
+ }
+ }
+
+ m_pTheSite2->AddPassiveSiteWatcher(static_cast<IRMAPassiveSiteWatcher*>(this));
+
+ hr = m_pSiteManager->AddSite(m_pTheSite);
+ if(PNR_OK != hr)
+ return hr;
+
+ m_CreatedSites[uRequestID] = m_pTheSite;
+
+ return hr;
+}
+
+STDMETHODIMP CRealMediaPlayer::SitesNotNeeded(UINT32 uRequestID)
+{
+ IRMASite* pSite;
+ if(!m_CreatedSites.Lookup(uRequestID, pSite))
+ return PNR_INVALID_PARAMETER;
+
+ m_CreatedSites.RemoveKey(uRequestID);
+
+ m_pSiteManager->RemoveSite(pSite);
+
+ m_pTheSite2->RemovePassiveSiteWatcher(static_cast<IRMAPassiveSiteWatcher*>(this));
+
+ m_pTheSite.Release();
+ m_pTheSite2.Release();
+
+ DestroySite(pSite);
+
+ return PNR_OK;
+}
+STDMETHODIMP CRealMediaPlayer::BeginChangeLayout() {return E_NOTIMPL;}
+STDMETHODIMP CRealMediaPlayer::DoneChangeLayout()
+{
+ if(m_fVideoSizeChanged)
+ {
+ m_pRMG->NotifyEvent(EC_VIDEO_SIZE_CHANGED, MAKELPARAM(m_VideoSize.cx, m_VideoSize.cy), 0);
+ m_fVideoSizeChanged = false;
+ }
+
+ return PNR_OK;
+}
+
+// IRMAPassiveSiteWatcher
+STDMETHODIMP CRealMediaPlayer::PositionChanged(PNxPoint* pos) {return E_NOTIMPL;}
+STDMETHODIMP CRealMediaPlayer::SizeChanged(PNxSize* size)
+{
+ if(m_VideoSize.cx == 0 || m_VideoSize.cy == 0)
+ {
+ m_fVideoSizeChanged = true;
+ m_VideoSize.cx = size->cx;
+ m_VideoSize.cy = size->cy;
+ }
+ return PNR_OK;
+}
+
+// IRMAAudioHook
+STDMETHODIMP CRealMediaPlayer::OnBuffer(RMAAudioData* pAudioInData, RMAAudioData* pAudioOutData) {return E_NOTIMPL;}
+STDMETHODIMP CRealMediaPlayer::OnInit(RMAAudioFormat* pFormat)
+{
+ m_pRMG->NotifyEvent(EC_BG_AUDIO_CHANGED, pFormat->uChannels, 0);
+ return PNR_OK;
+}
+
+//
+// CRealMediaPlayerWindowed
+//
+
+CRealMediaPlayerWindowed::CRealMediaPlayerWindowed(HWND hWndParent, CRealMediaGraph* pRMG)
+ : CRealMediaPlayer(hWndParent, pRMG)
+{
+ if(!m_wndWindowFrame.CreateEx(WS_EX_NOPARENTNOTIFY, NULL, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_VISIBLE,
+ CRect(0, 0, 0, 0), CWnd::FromHandle(m_hWndParent), 0, NULL))
+ return;
+
+ if(!m_wndDestFrame.Create(NULL, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
+ CRect(0, 0, 0, 0), &m_wndWindowFrame, 0, NULL))
+ return;
+}
+
+CRealMediaPlayerWindowed::~CRealMediaPlayerWindowed()
+{
+ m_wndDestFrame.DestroyWindow();
+ m_wndWindowFrame.DestroyWindow();
+}
+
+void CRealMediaPlayerWindowed::SetWindowRect(CRect r)
+{
+ if(IsWindow(m_wndWindowFrame.m_hWnd))
+ m_wndWindowFrame.MoveWindow(r);
+}
+
+void CRealMediaPlayerWindowed::SetDestRect(CRect r)
+{
+ if(IsWindow(m_wndDestFrame.m_hWnd))
+ m_wndDestFrame.MoveWindow(r);
+
+ if(m_pTheSite)
+ {
+ PNxSize s = {r.Width(), r.Height()};
+ m_pTheSite->SetSize(s);
+ }
+}
+
+bool CRealMediaPlayerWindowed::CreateSite(IRMASite** ppSite)
+{
+ if(!ppSite)
+ return(false);
+
+ CComPtr<IRMASiteWindowed> pSiteWindowed;
+ if(PNR_OK != m_pCommonClassFactory->CreateInstance(CLSID_IRMASiteWindowed, (void**)&pSiteWindowed))
+ return(false);
+
+ DWORD style = WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
+ if(!AfxGetAppSettings().fIntRealMedia) style |= WS_DISABLED;
+ if(PNR_OK != pSiteWindowed->Create(m_wndDestFrame.m_hWnd, style))
+ return(false);
+
+ return !!(*ppSite = CComQIPtr<IRMASite, &IID_IRMASite>(pSiteWindowed).Detach());
+}
+
+void CRealMediaPlayerWindowed::DestroySite(IRMASite* pSite)
+{
+ if(CComQIPtr<IRMASiteWindowed, &IID_IRMASiteWindowed> pRMASiteWindowed = pSite)
+ pRMASiteWindowed->Destroy();
+}
+//
+// CRealMediaPlayerWindowless
+//
+
+CRealMediaPlayerWindowless::CRealMediaPlayerWindowless(HWND hWndParent, CRealMediaGraph* pRMG)
+ : CRealMediaPlayer(hWndParent, pRMG)
+{
+ AppSettings& s = AfxGetAppSettings();
+
+ switch(s.iRMVideoRendererType)
+ {
+ default:
+ case VIDRNDT_RM_DX7:
+ if(FAILED(CreateAP7(CLSID_RM7AllocatorPresenter, hWndParent, &m_pRMAP)))
+ return;
+ break;
+ case VIDRNDT_RM_DX9:
+ if(FAILED(CreateAP9(CLSID_RM9AllocatorPresenter, hWndParent, &m_pRMAP)))
+ return;
+ break;
+ }
+}
+
+CRealMediaPlayerWindowless::~CRealMediaPlayerWindowless()
+{
+}
+
+STDMETHODIMP CRealMediaPlayerWindowless::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ CheckPointer(ppv, E_POINTER);
+
+ return
+ (m_pRMAP && (riid == __uuidof(ISubPicAllocatorPresenter) || riid == IID_IRMAVideoSurface)) ? m_pRMAP->QueryInterface(riid, ppv) :
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+bool CRealMediaPlayerWindowless::CreateSite(IRMASite** ppSite)
+{
+ if(!ppSite || !m_pRMAP)
+ return(false);
+
+ HRESULT hr = S_OK;
+
+ CRealMediaWindowlessSite* pWMWlS;
+
+ CComPtr<IRMASiteWindowless> pSiteWindowless;
+ pSiteWindowless = (IRMASiteWindowless*)(pWMWlS = new CRealMediaWindowlessSite(hr, m_pPlayer, NULL, NULL));
+ if(FAILED(hr))
+ return(false);
+
+ pWMWlS->SetBltService(CComQIPtr<IRMAVideoSurface, &IID_IRMAVideoSurface>(m_pRMAP));
+
+ return !!(*ppSite = CComQIPtr<IRMASite, &IID_IRMASite>(pSiteWindowless).Detach());
+}
+
+void CRealMediaPlayerWindowless::DestroySite(IRMASite* pSite)
+{
+}
+
+STDMETHODIMP CRealMediaPlayerWindowless::SizeChanged(PNxSize* size)
+{
+ if(CComQIPtr<IRMAVideoSurface, &IID_IRMAVideoSurface> pRMAVS = m_pRMAP)
+ {
+ RMABitmapInfoHeader BitmapInfo;
+ memset(&BitmapInfo, 0, sizeof(BitmapInfo));
+ BitmapInfo.biWidth = size->cx;
+ BitmapInfo.biHeight = size->cy;
+ pRMAVS->BeginOptimizedBlt(&BitmapInfo);
+ }
+
+ return __super::SizeChanged(size);
+}
+
+
+////////////////
+
+CRealMediaGraph::CRealMediaGraph(HWND hWndParent, HRESULT& hr)
+ : CBaseGraph()
+{
+ hr = S_OK;
+
+ m_pRMP = AfxGetAppSettings().iRMVideoRendererType == VIDRNDT_RM_DEFAULT
+ ? (CRealMediaPlayer*)new CRealMediaPlayerWindowed(hWndParent, this)
+ : (CRealMediaPlayer*)new CRealMediaPlayerWindowless(hWndParent, this);
+
+ if(!m_pRMP)
+ {
+ hr = E_OUTOFMEMORY;
+ return;
+ }
+
+ if(!m_pRMP->Init())
+ {
+ delete m_pRMP, m_pRMP = NULL;
+ hr = E_FAIL;
+ return;
+ }
+
+ m_pRMP->AddRef();
+}
+
+CRealMediaGraph::~CRealMediaGraph()
+{
+ if(m_pRMP)
+ {
+ m_pRMP->Deinit();
+ m_pRMP->Release();
+ m_pRMP = NULL;
+ }
+}
+
+STDMETHODIMP CRealMediaGraph::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ CheckPointer(ppv, E_POINTER);
+
+ return
+ (m_pRMP && (riid == __uuidof(ISubPicAllocatorPresenter) || riid == __uuidof(ISubPicAllocatorPresenter))) ? m_pRMP->QueryInterface(riid, ppv) :
+ __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+// IGraphBuilder
+STDMETHODIMP CRealMediaGraph::RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList)
+{
+ m_fn = lpcwstrFile;
+
+ CHAR buff[MAX_PATH] = {0};
+ WideCharToMultiByte(GetACP(), 0, lpcwstrFile, -1, buff, MAX_PATH, 0, 0);
+
+ CStringA fn(buff);
+ if(fn.Find("://") < 0) fn = "file://" + fn;
+
+ m_pRMP->m_unPercentComplete = 100;
+
+ ClearMessageQueue();
+
+ if(PNR_OK != m_pRMP->m_pPlayer->OpenURL(fn))
+ return E_FAIL;
+
+ m_pRMP->m_pPlayer->Pause()/*Stop()*/; // please, don't start just yet
+
+ return S_OK;
+}
+
+// IMediaControl
+STDMETHODIMP CRealMediaGraph::Run()
+{
+ if(m_pRMP->m_pPlayer->IsDone())
+ RenderFile(m_fn, NULL);
+
+ m_pRMP->m_UserState = State_Running;
+ return (PNR_OK == m_pRMP->m_pPlayer->Begin()) ? S_OK : E_FAIL;
+}
+STDMETHODIMP CRealMediaGraph::Pause()
+{
+ m_pRMP->m_UserState = State_Paused;
+ return (PNR_OK == m_pRMP->m_pPlayer->Pause()) ? S_OK : E_FAIL;
+}
+STDMETHODIMP CRealMediaGraph::Stop()
+{
+ m_pRMP->m_UserState = State_Stopped;
+ return (PNR_OK == m_pRMP->m_pPlayer->Stop()) ? S_OK : E_FAIL;
+}
+STDMETHODIMP CRealMediaGraph::GetState(LONG msTimeout, OAFilterState* pfs)
+{
+ return pfs ? *pfs = m_pRMP->m_State, S_OK : E_POINTER;
+}
+
+// IMediaSeeking
+STDMETHODIMP CRealMediaGraph::GetDuration(LONGLONG* pDuration)
+{
+ return pDuration ? *pDuration = m_pRMP->m_nDuration, S_OK : E_POINTER;
+}
+STDMETHODIMP CRealMediaGraph::GetCurrentPosition(LONGLONG* pCurrent)
+{
+ return pCurrent ? *pCurrent = m_pRMP->m_nCurrent, S_OK : E_POINTER;
+}
+STDMETHODIMP CRealMediaGraph::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)
+{
+ return (dwCurrentFlags&AM_SEEKING_AbsolutePositioning)
+ && (PNR_OK == m_pRMP->m_pPlayer->Seek((ULONG)(*pCurrent / 10000))) ? S_OK : E_FAIL;
+}
+
+// IVideoWindow
+STDMETHODIMP CRealMediaGraph::SetWindowPosition(long Left, long Top, long Width, long Height)
+{
+ if(m_pRMP)
+ m_pRMP->SetWindowRect(CRect(CPoint(Left, Top), CSize(Width, Height)));
+
+ return S_OK;
+}
+
+// IBasicVideo
+STDMETHODIMP CRealMediaGraph::SetDestinationPosition(long Left, long Top, long Width, long Height)// {return E_NOTIMPL;}
+{
+ m_pRMP->SetDestRect(CRect(CPoint(Left, Top), CSize(Width, Height)));
+ return S_OK;
+}
+STDMETHODIMP CRealMediaGraph::GetVideoSize(long* pWidth, long* pHeight)
+{
+ if(!pWidth || !pHeight) return E_POINTER;
+ *pWidth = m_pRMP->GetVideoSize().cx;
+ *pHeight = m_pRMP->GetVideoSize().cy;
+ return S_OK;
+}
+
+// IBasicAudio
+STDMETHODIMP CRealMediaGraph::put_Volume(long lVolume)
+{
+ if(!m_pRMP->m_pVolume) return E_UNEXPECTED;
+
+ UINT16 volume = (lVolume == -10000) ? 0 : (int)pow(10.0, ((double)lVolume)/5000+2);
+ volume = max(min(volume, 100), 0);
+
+ return PNR_OK == m_pRMP->m_pVolume->SetVolume(volume) ? S_OK : E_FAIL;
+}
+STDMETHODIMP CRealMediaGraph::get_Volume(long* plVolume)
+{
+ if(!m_pRMP->m_pVolume) return E_UNEXPECTED;
+
+ CheckPointer(plVolume, E_POINTER);
+
+ UINT16 volume = m_pRMP->m_pVolume->GetVolume();
+ volume = (int)((log10(1.0*volume)-2)*5000);
+ volume = max(min(volume, 0), -10000);
+
+ *plVolume = volume;
+
+ return S_OK;
+}
+
+// IAMOpenProgress
+STDMETHODIMP CRealMediaGraph::QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent)
+{
+ *pllTotal = 100;
+ *pllCurrent = m_pRMP->m_unPercentComplete > 0 ? m_pRMP->m_unPercentComplete : 100; // after seeking it drops to 0 and would show annoying "Buffering... (0%)" messages on the status line
+ return S_OK;
+}
+
+// IGraphEngine
+STDMETHODIMP_(engine_t) CRealMediaGraph::GetEngine() {return RealMedia;}
diff --git a/src/apps/mplayerc/RealMediaGraph.h b/src/apps/mplayerc/RealMediaGraph.h
new file mode 100644
index 000000000..3e085f6bb
--- /dev/null
+++ b/src/apps/mplayerc/RealMediaGraph.h
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "BaseGraph.h"
+
+#include "DX7AllocatorPresenter.h"
+#include "DX9AllocatorPresenter.h"
+
+#include "..\..\..\include\RealMedia\pntypes.h"
+#include "..\..\..\include\RealMedia\pnwintyp.h"
+#include "..\..\..\include\RealMedia\pncom.h"
+#include "..\..\..\include\RealMedia\rmapckts.h"
+#include "..\..\..\include\RealMedia\rmacomm.h"
+#include "..\..\..\include\RealMedia\rmamon.h"
+#include "..\..\..\include\RealMedia\rmafiles.h"
+#include "..\..\..\include\RealMedia\rmaengin.h"
+#include "..\..\..\include\RealMedia\rmacore.h"
+#include "..\..\..\include\RealMedia\rmaclsnk.h"
+#include "..\..\..\include\RealMedia\rmaerror.h"
+#include "..\..\..\include\RealMedia\rmaauth.h"
+#include "..\..\..\include\RealMedia\rmawin.h"
+#include "..\..\..\include\RealMedia\rmasite2.h"
+#include "..\..\..\include\RealMedia\rmaausvc.h"
+#include "..\..\..\include\RealMedia\rmavsurf.h"
+
+namespace DSObjects
+{
+
+class CRealMediaGraph;
+
+class CRealMediaPlayer
+ : public CUnknown
+ , public IRMAErrorSink
+ , public IRMAClientAdviseSink
+ , public IRMAAuthenticationManager
+ , public IRMASiteSupplier
+ , public IRMAPassiveSiteWatcher
+ , public IRMAAudioHook
+
+{
+protected:
+ friend class CRealMediaGraph;
+ CRealMediaGraph* m_pRMG; // IMPORTANT: do not ever AddRef on this from here
+
+ HWND m_hWndParent;
+ CSize m_VideoSize;
+ bool m_fVideoSizeChanged;
+
+ //
+
+ DWORD m_wndStyle;
+ CPlayerWindow m_wndWindowFrame, m_wndDestFrame;
+
+ //
+
+ FPRMCREATEENGINE m_fpCreateEngine;
+ FPRMCLOSEENGINE m_fpCloseEngine;
+ FPRMSETDLLACCESSPATH m_fpSetDLLAccessPath;
+ HMODULE m_hRealMediaCore;
+
+ CComPtr<IRMAClientEngine> m_pEngine;
+ CComPtr<IRMAPlayer> m_pPlayer;
+ CComQIPtr<IRMAAudioPlayer, &IID_IRMAAudioPlayer> m_pAudioPlayer;
+ CComPtr<IRMAVolume> m_pVolume;
+ CComQIPtr<IRMASiteManager, &IID_IRMASiteManager> m_pSiteManager;
+ CComQIPtr<IRMACommonClassFactory, &IID_IRMACommonClassFactory> m_pCommonClassFactory;
+
+ CComQIPtr<IRMASite, &IID_IRMASite> m_pTheSite;
+ CComQIPtr<IRMASite2, &IID_IRMASite2> m_pTheSite2;
+ CMap<UINT32, UINT32&, IRMASite*, IRMASite*&> m_CreatedSites;
+
+ //
+
+ OAFilterState m_State, m_UserState;
+ REFERENCE_TIME m_nCurrent, m_nDuration;
+
+ UINT16 m_unPercentComplete;
+
+ //
+
+public:
+ CRealMediaPlayer(HWND hWndParent, CRealMediaGraph* pRMG);
+ virtual ~CRealMediaPlayer();
+
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ bool Init();
+ void Deinit();
+
+ virtual CSize GetVideoSize() {return(m_VideoSize);}
+ virtual void SetWindowRect(CRect r) {}
+ virtual void SetDestRect(CRect r) {}
+ virtual bool CreateSite(IRMASite** pSite) = 0;
+ virtual void DestroySite(IRMASite* pSite) = 0;
+
+ // IRMAErrorSink
+ STDMETHODIMP ErrorOccurred(const UINT8 unSeverity, const UINT32 ulRMACode, const UINT32 ulUserCode, const char* pUserString, const char* pMoreInfoURL);
+
+ // IRMAClientAdviseSink
+ STDMETHODIMP OnPosLength(UINT32 ulPosition, UINT32 ulLength);
+ STDMETHODIMP OnPresentationOpened();
+ STDMETHODIMP OnPresentationClosed();
+ STDMETHODIMP OnStatisticsChanged();
+ STDMETHODIMP OnPreSeek(UINT32 ulOldTime, UINT32 ulNewTime);
+ STDMETHODIMP OnPostSeek(UINT32 ulOldTime, UINT32 ulNewTime);
+ STDMETHODIMP OnStop();
+ STDMETHODIMP OnPause(UINT32 ulTime);
+ STDMETHODIMP OnBegin(UINT32 ulTime);
+ STDMETHODIMP OnBuffering(UINT32 ulFlags, UINT16 unPercentComplete);
+ STDMETHODIMP OnContacting(const char* pHostName);
+
+ // IRMAAuthenticationManager
+ STDMETHODIMP HandleAuthenticationRequest(IRMAAuthenticationManagerResponse* pResponse);
+
+ // IRMASiteSupplier
+ STDMETHODIMP SitesNeeded(UINT32 uRequestID, IRMAValues* pSiteProps);
+ STDMETHODIMP SitesNotNeeded(UINT32 uRequestID);
+ STDMETHODIMP BeginChangeLayout();
+ STDMETHODIMP DoneChangeLayout();
+
+ // IRMAPassiveSiteWatcher
+ STDMETHODIMP PositionChanged(PNxPoint* pos);
+ STDMETHODIMP SizeChanged(PNxSize* size);
+
+ // IRMAAudioHook
+ STDMETHODIMP OnBuffer(RMAAudioData* pAudioInData, RMAAudioData* pAudioOutData);
+ STDMETHODIMP OnInit(RMAAudioFormat* pFormat);
+};
+
+class CRealMediaPlayerWindowed
+ : public CRealMediaPlayer
+{
+public:
+ CRealMediaPlayerWindowed(HWND hWndParent, CRealMediaGraph* pRMG);
+ virtual ~CRealMediaPlayerWindowed();
+
+ void SetWindowRect(CRect r);
+ void SetDestRect(CRect r);
+
+ bool CreateSite(IRMASite** pSite);
+ void DestroySite(IRMASite* pSite);
+};
+
+class CRealMediaPlayerWindowless
+ : public CRealMediaPlayer
+{
+ CComPtr<ISubPicAllocatorPresenter> m_pRMAP;
+
+public:
+ CRealMediaPlayerWindowless(HWND hWndParent, CRealMediaGraph* pRMG);
+ virtual ~CRealMediaPlayerWindowless();
+
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ bool CreateSite(IRMASite** pSite);
+ void DestroySite(IRMASite* pSite);
+
+ STDMETHODIMP SizeChanged(PNxSize* size);
+};
+
+class CRealMediaGraph : public CBaseGraph
+{
+ CRealMediaPlayer* m_pRMP; // TODO: access m_pRMP through a private interface
+
+ CStringW m_fn;
+
+public:
+ CRealMediaGraph(HWND hWndParent, HRESULT& hr); // in windowless mode IVideoWindow::* will return E_NOTIMPL, use ISubPicAllocatorPresenter instead
+ virtual ~CRealMediaGraph();
+
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+protected:
+ // IGraphBuilder
+ STDMETHODIMP RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList);
+
+ // IMediaControl
+ STDMETHODIMP Run();
+ STDMETHODIMP Pause();
+ STDMETHODIMP Stop();
+ STDMETHODIMP GetState(LONG msTimeout, OAFilterState* pfs);
+
+ // IMediaSeeking
+ STDMETHODIMP GetDuration(LONGLONG* pDuration);
+ STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
+ STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
+
+ // IVideoWindow
+ STDMETHODIMP SetWindowPosition(long Left, long Top, long Width, long Height);
+
+ // IBasicVideo
+ STDMETHODIMP SetDestinationPosition(long Left, long Top, long Width, long Height);
+ STDMETHODIMP GetVideoSize(long* pWidth, long* pHeight);
+
+ // IBasicAudio
+ STDMETHODIMP put_Volume(long lVolume);
+ STDMETHODIMP get_Volume(long* plVolume);
+
+ // IAMOpenProgress
+ STDMETHODIMP QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent);
+
+ // IGraphEngine
+ STDMETHODIMP_(engine_t) GetEngine();
+};
+
+}
+using namespace DSObjects; \ No newline at end of file
diff --git a/src/apps/mplayerc/RealMediaWindowlessSite.cpp b/src/apps/mplayerc/RealMediaWindowlessSite.cpp
new file mode 100644
index 000000000..9891f5e71
--- /dev/null
+++ b/src/apps/mplayerc/RealMediaWindowlessSite.cpp
@@ -0,0 +1,710 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include <math.h>
+#include <atlbase.h>
+#include <atlcoll.h>
+#include "realmediawindowlesssite.h"
+#include "..\..\DSUtil\DSUtil.h"
+
+void DSObjects::ExtractRects(REGION* pRegion)
+{
+ LPRGNDATA lpRgnData;
+
+ DWORD sizeNeeed = GetRegionData((HRGN)pRegion->pOSRegion, 0, NULL);
+
+ lpRgnData = (LPRGNDATA)new char[sizeNeeed];
+ DWORD returnValue = GetRegionData((HRGN)pRegion->pOSRegion, sizeNeeed, lpRgnData);
+
+ PN_VECTOR_DELETE(pRegion->rects);
+
+ pRegion->numRects = lpRgnData->rdh.nCount;
+ pRegion->extents.left = lpRgnData->rdh.rcBound.left;
+ pRegion->extents.top = lpRgnData->rdh.rcBound.top;
+ pRegion->extents.right = lpRgnData->rdh.rcBound.right;
+ pRegion->extents.bottom = lpRgnData->rdh.rcBound.bottom;
+
+ if(lpRgnData->rdh.nCount)
+ {
+ pRegion->rects = new PNxRect[lpRgnData->rdh.nCount];
+
+ // now extract the information.
+
+ for(int j = 0; j < (int) lpRgnData->rdh.nCount;j++)
+ {
+ RECT* pRect = (RECT*)lpRgnData->Buffer;
+ pRegion->rects[j].left = pRect[j].left;
+ pRegion->rects[j].top = pRect[j].top;
+ pRegion->rects[j].right = pRect[j].right;
+ pRegion->rects[j].bottom = pRect[j].bottom;
+ }
+ }
+
+ PN_VECTOR_DELETE(lpRgnData);
+}
+REGION* DSObjects::RMACreateRectRegion(int left, int top, int right, int bottom)
+{
+ REGION* retVal = new REGION;
+ retVal->pOSRegion = (void*)CreateRectRgn(left, top, right, bottom);
+ ExtractRects(retVal);
+ return retVal;
+}
+void DSObjects::RMASubtractRegion(REGION* regM, REGION* regS, REGION* regD)
+{
+ CombineRgn((HRGN)regD->pOSRegion, (HRGN)regM->pOSRegion, (HRGN)regS->pOSRegion, RGN_DIFF);
+ ExtractRects(regD);
+}
+void DSObjects::RMAUnionRegion(REGION* reg1, REGION* reg2, REGION* regD)
+{
+ CombineRgn((HRGN)regD->pOSRegion, (HRGN)reg1->pOSRegion, (HRGN)reg2->pOSRegion, RGN_OR);
+ ExtractRects(regD);
+}
+void DSObjects::RMAIntersectRegion(REGION* reg1, REGION* reg2, REGION* regD)
+{
+ CombineRgn((HRGN)regD->pOSRegion, (HRGN)reg1->pOSRegion, (HRGN)reg2->pOSRegion, RGN_AND);
+ ExtractRects(regD);
+}
+BOOL DSObjects::RMAEqualRegion(REGION* reg1, REGION* reg2)
+{
+ return EqualRgn((HRGN)reg1->pOSRegion, (HRGN)reg2->pOSRegion)
+ && !memcmp(&reg1->extents, &reg2->extents, sizeof(PNxRect)) ? TRUE : FALSE;
+}
+void DSObjects::RMADestroyRegion(REGION* reg)
+{
+ if(reg) DeleteObject((HRGN)reg->pOSRegion),
+ PN_VECTOR_DELETE(reg->rects);
+ PN_DELETE(reg);
+}
+REGION* DSObjects::RMACreateRegion()
+{
+ return RMACreateRectRegion(0,0,0,0);
+}
+
+//
+// CRealMediaWindowlessSite
+//
+
+CRealMediaWindowlessSite::CRealMediaWindowlessSite(HRESULT& hr, IUnknown* pContext, CRealMediaWindowlessSite* pParentSite, IUnknown* pUnkOuter)
+ : CUnknown(NAME("CRealMediaWindowlessSite"), pUnkOuter, &hr)
+ , m_pContext(pContext)
+ , m_pParentSite(pParentSite)
+ , m_pCCF(pContext)
+ , m_fDamaged(false), m_fInRedraw(false), m_fIsVisible(true)
+ , m_lZOrder(0)
+ , m_pRegion(NULL), m_pRegionWithoutChildren(NULL)
+{
+ m_size.cx = m_size.cy = 0;
+ m_position.x = m_position.y = 0;
+
+ memset(&m_lastBitmapInfo, 0, sizeof(m_lastBitmapInfo));
+
+ hr = S_OK;
+
+ if(!m_pContext || !m_pCCF)
+ {
+ hr = E_POINTER;
+ return;
+ }
+
+ m_pCCF->CreateInstance(CLSID_IRMAValues, (void**)&m_pValues);
+}
+
+CRealMediaWindowlessSite::~CRealMediaWindowlessSite()
+{
+ POSITION pos = m_pChildren.GetHeadPosition();
+ while(pos) DestroyChild(m_pChildren.GetNext(pos));
+
+ RMADestroyRegion(m_pRegion);
+ RMADestroyRegion(m_pRegionWithoutChildren);
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ return
+ QI2(IRMASite)
+ QI2(IRMASite2)
+ QI2(IRMASiteWindowless)
+ QI2(IRMAVideoSurface)
+ (m_pValues && m_pValues->QueryInterface(riid, ppv) == PNR_OK) ? PNR_OK :
+ CUnknown::NonDelegatingQueryInterface(riid, ppv);
+}
+
+// public
+
+void CRealMediaWindowlessSite::GetTopLeft(PNxPoint* pPoint)
+{
+ pPoint->x += m_position.x;
+ pPoint->y += m_position.y;
+
+ if(m_pParentSite)
+ m_pParentSite->GetTopLeft(pPoint);
+}
+
+REGION* CRealMediaWindowlessSite::GetRegion()
+{
+ return m_pRegion;
+}
+
+// private
+
+void CRealMediaWindowlessSite::RecomputeRegion()
+{
+ if(m_pParentSite) m_pParentSite->RecomputeRegion();
+ else InternalRecomputeRegion();
+}
+
+void CRealMediaWindowlessSite::InternalRecomputeRegion()
+{
+ ComputeRegion();
+
+ POSITION pos = m_pChildren.GetHeadPosition();
+ while(pos)
+ {
+ CRealMediaWindowlessSite* pSite = (CRealMediaWindowlessSite*)(IRMASite*)m_pChildren.GetNext(pos);
+ if(pSite) pSite->InternalRecomputeRegion();
+ }
+}
+
+void CRealMediaWindowlessSite::ComputeRegion()
+{
+ REGION* pTempRegion = NULL;
+
+ if(m_pRegion)
+ {
+ pTempRegion = RMACreateRegion();
+ RMAUnionRegion(pTempRegion, m_pRegion, pTempRegion);
+ RMADestroyRegion(m_pRegion);
+ }
+
+ if(m_pRegionWithoutChildren)
+ {
+ RMADestroyRegion(m_pRegionWithoutChildren);
+ }
+
+ PNxPoint topleft = {0,0};
+ GetTopLeft(&topleft);
+
+ if(IsSiteVisible())
+ {
+ m_pRegionWithoutChildren = RMACreateRectRegion(topleft.x, topleft.y, topleft.x + m_size.cx, topleft.y + m_size.cy);
+
+ if(m_pParentSite)
+ {
+ RMAIntersectRegion(m_pRegionWithoutChildren, m_pParentSite->m_pRegionWithoutChildren, m_pRegionWithoutChildren);
+
+ POSITION pos = m_pParentSite->m_pChildren.GetHeadPosition();
+ while(pos)
+ {
+ CRealMediaWindowlessSite* pSiblingSite = (CRealMediaWindowlessSite*)(IRMASite*)m_pParentSite->m_pChildren.GetNext(pos);
+ if(pSiblingSite != this)
+ {
+ INT32 zOrder;
+ pSiblingSite->GetZOrder(zOrder);
+
+ if(zOrder > m_lZOrder && pSiblingSite->IsSiteVisible())
+ {
+ pSiblingSite->SubtractSite(m_pRegionWithoutChildren);
+ }
+ }
+ }
+ }
+
+ m_pRegion = RMACreateRegion();
+ RMAUnionRegion(m_pRegion, m_pRegionWithoutChildren, m_pRegion);
+
+ POSITION pos = m_pChildren.GetHeadPosition();
+ while(pos)
+ {
+ CRealMediaWindowlessSite* pChildSite = (CRealMediaWindowlessSite*)(IRMASite*)m_pChildren.GetNext(pos);
+ if(pChildSite->IsSiteVisible()) pChildSite->SubtractSite(m_pRegion);
+ }
+ }
+ else
+ {
+ m_pRegionWithoutChildren = RMACreateRectRegion(0,0,0,0);
+ m_pRegion = RMACreateRectRegion(0,0,0,0);
+ }
+
+ if(pTempRegion && !RMAEqualRegion(m_pRegion, pTempRegion))
+ {
+ ForceRedraw();
+ }
+
+ RMADestroyRegion(pTempRegion);
+}
+
+void CRealMediaWindowlessSite::SubtractSite(REGION* pRegion)
+{
+ PNxPoint topLeft;
+ memset(&topLeft, 0, sizeof(PNxPoint));
+ GetTopLeft(&topLeft);
+
+ REGION* pTempRegion = RMACreateRectRegion(topLeft.x, topLeft.y, topLeft.x + m_size.cx, topLeft.y + m_size.cy);
+
+ RMASubtractRegion(pRegion, pTempRegion, pRegion);
+ RMADestroyRegion(pTempRegion);
+}
+
+void CRealMediaWindowlessSite::UpdateZOrder(CRealMediaWindowlessSite* pUpdatedChildSite, INT32 lOldZOrder, INT32 lNewZOrder)
+{
+ POSITION pos = m_pChildren.GetHeadPosition();
+ while(pos)
+ {
+ CRealMediaWindowlessSite* pSite = (CRealMediaWindowlessSite*)(IRMASite*)m_pChildren.GetNext(pos);
+
+ INT32 lItsOldZOrder;
+ pSite->GetZOrder(lItsOldZOrder);
+
+ if(pSite != pUpdatedChildSite)
+ {
+ if(lOldZOrder < lNewZOrder)
+ {
+ if(lItsOldZOrder >= lOldZOrder && lItsOldZOrder < lNewZOrder)
+ {
+ pSite->SetInternalZOrder(lItsOldZOrder-1);
+ }
+ }
+ else
+ {
+ if(lItsOldZOrder >= lNewZOrder && lItsOldZOrder < lOldZOrder)
+ {
+ pSite->SetInternalZOrder(lItsOldZOrder+1);
+ }
+ }
+ }
+ else
+ {
+ pSite->SetInternalZOrder(lNewZOrder);
+ }
+ }
+}
+
+void CRealMediaWindowlessSite::SetInternalZOrder(INT32 lZOrder)
+{
+ m_lZOrder = lZOrder;
+}
+
+// IRMASiteWindowless
+
+STDMETHODIMP CRealMediaWindowlessSite::EventOccurred(PNxEvent* /*IN*/ pEvent)
+{
+ return PNR_NOTIMPL; /* not necessary within our implementation */
+}
+
+STDMETHODIMP_(PNxWindow*) CRealMediaWindowlessSite::GetParentWindow()
+{
+ return NULL;
+}
+
+// IRMASite
+
+STDMETHODIMP CRealMediaWindowlessSite::AttachUser(IRMASiteUser* /*IN*/ pUser)
+{
+ HRESULT hr = PNR_FAIL;
+
+ if(m_pUser) return PNR_UNEXPECTED;
+
+ if(CComQIPtr<IRMASite, &IID_IRMASite> pOuterSite = GetOwner())
+ hr = pUser->AttachSite(pOuterSite);
+
+ if(PNR_OK == hr)
+ m_pUser = pUser;
+
+ return hr;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::DetachUser()
+{
+ HRESULT hr = PNR_OK;
+
+ if(!m_pUser) return PNR_UNEXPECTED;
+
+ hr = m_pUser->DetachSite();
+
+ if(PNR_OK == hr)
+ m_pUser = NULL;
+
+ return hr;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::GetUser(REF(IRMASiteUser*) /*OUT*/ pUser)
+{
+ HRESULT hr = PNR_OK;
+
+ if(!m_pUser) return PNR_UNEXPECTED;
+
+ (pUser = m_pUser)->AddRef();
+
+ return hr;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::CreateChild(REF(IRMASite*) /*OUT*/ pChildSite)
+{
+ HRESULT hr = PNR_OK;
+
+ CComPtr<IRMASite> pSite =
+ (IRMASite*)new CRealMediaWindowlessSite(hr, m_pContext, this);
+
+ if(FAILED(hr) || !pSite)
+ return E_FAIL;
+
+ pChildSite = pSite.Detach();
+
+ m_pChildren.AddTail(pChildSite);
+
+ return hr;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::DestroyChild(IRMASite* /*IN*/ pChildSite)
+{
+ if(POSITION pos = m_pChildren.Find(pChildSite))
+ {
+ m_pChildren.RemoveAt(pos);
+ return PNR_OK;
+ }
+
+ return PNR_UNEXPECTED;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::AttachWatcher(IRMASiteWatcher* /*IN*/ pWatcher)
+{
+ if(m_pWatcher) return PNR_UNEXPECTED;
+
+ if(m_pWatcher = pWatcher)
+ m_pWatcher->AttachSite((IRMASite*)this);
+
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::DetachWatcher()
+{
+ if(!m_pWatcher) return PNR_UNEXPECTED;
+
+ m_pWatcher->DetachSite();
+ m_pWatcher = NULL;
+
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::SetPosition(PNxPoint position)
+{
+ HRESULT hr = PNR_OK;
+
+ if(m_pWatcher)
+ {
+ hr = m_pWatcher->ChangingPosition(m_position, position);
+ }
+
+ if(PNR_OK == hr)
+ {
+ m_position = position;
+
+ POSITION pos = m_pPassiveWatchers.GetHeadPosition();
+ while(pos) m_pPassiveWatchers.GetNext(pos)->PositionChanged(&position);
+
+ RecomputeRegion();
+ }
+
+ return hr;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::GetPosition(REF(PNxPoint) position)
+{
+ position = m_position;
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::SetSize(PNxSize size)
+{
+ HRESULT hr = PNR_OK;
+
+ if(m_pWatcher)
+ {
+ hr = m_pWatcher->ChangingSize(m_size, size);
+ }
+
+ if(PNR_OK == hr && size.cx != 0 && size.cy != 0)
+ {
+ m_size = size;
+
+ POSITION pos = m_pPassiveWatchers.GetHeadPosition();
+ while(pos) m_pPassiveWatchers.GetNext(pos)->SizeChanged(&size);
+
+ RecomputeRegion();
+ }
+
+ return hr;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::GetSize(REF(PNxSize) size)
+{
+ size = m_size;
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::DamageRect(PNxRect rect)
+{
+ m_fDamaged = TRUE;
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::DamageRegion(PNxRegion region)
+{
+ m_fDamaged = TRUE;
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::ForceRedraw()
+{
+ // make sure we have a visible window and are not re-enterering and we have damage
+ if(!m_fInRedraw && m_fDamaged && m_fIsVisible)
+ {
+ m_fInRedraw = TRUE;
+
+ PNxEvent event = {RMA_SURFACE_UPDATE, NULL, (IRMAVideoSurface*)this, NULL, 0, 0};
+ m_pUser->HandleEvent(&event);
+
+ m_fInRedraw = FALSE;
+ m_fDamaged = FALSE;
+ }
+
+ return PNR_OK;
+}
+
+// IRMASite2
+
+STDMETHODIMP CRealMediaWindowlessSite::UpdateSiteWindow(PNxWindow* /*IN*/ pWindow)
+{
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::ShowSite(BOOL bShow)
+{
+ m_fIsVisible = !!bShow;
+ RecomputeRegion();
+ return PNR_OK;
+}
+
+STDMETHODIMP_(BOOL) CRealMediaWindowlessSite::IsSiteVisible()
+{
+ BOOL fIsVisible = m_fIsVisible;
+ if(m_pParentSite) fIsVisible = fIsVisible && m_pParentSite->IsSiteVisible();
+ return fIsVisible;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::SetZOrder(INT32 lZOrder)
+{
+ if(!m_pParentSite) return PNR_UNEXPECTED;
+
+ if(lZOrder == -1 || lZOrder >= (INT32)m_pParentSite->GetNumberOfChildSites())
+ lZOrder = m_pParentSite->GetNumberOfChildSites() - 1;
+
+ if(m_lZOrder != lZOrder)
+ m_pParentSite->UpdateZOrder(this, m_lZOrder, lZOrder);
+
+ m_lZOrder = lZOrder;
+
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::GetZOrder(REF(INT32) lZOrder)
+{
+ if(!m_pParentSite) return PNR_UNEXPECTED;
+ lZOrder = m_lZOrder;
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::MoveSiteToTop()
+{
+ if(!m_pParentSite) return PNR_UNEXPECTED;
+ return PNR_NOTIMPL;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::GetVideoSurface(REF(IRMAVideoSurface*) pSurface)
+{
+ (pSurface = (IRMAVideoSurface*)this)->AddRef();
+ return PNR_OK;
+}
+
+STDMETHODIMP_(UINT32) CRealMediaWindowlessSite::GetNumberOfChildSites()
+{
+ return (UINT32)m_pChildren.GetCount();
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::AddPassiveSiteWatcher(IRMAPassiveSiteWatcher* pWatcher)
+{
+ m_pPassiveWatchers.AddTail(pWatcher);
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::RemovePassiveSiteWatcher(IRMAPassiveSiteWatcher* pWatcher)
+{
+ if(POSITION pos = m_pPassiveWatchers.Find(pWatcher))
+ {
+ m_pPassiveWatchers.RemoveAt(pos);
+ return PNR_OK;
+ }
+
+ return PNR_UNEXPECTED;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::SetCursor(PNxCursor cursor, REF(PNxCursor) oldCursor)
+{
+ return PNR_NOTIMPL;
+}
+
+// private
+
+void CRealMediaWindowlessSite::IntersectRect(PNxRect* pRect, PNxRect* pBox, PNxRect* pRetVal)
+{
+ pRetVal->left = max(pRect->left, pBox->left);
+ pRetVal->top = max(pRect->top, pBox->top);
+ pRetVal->right = min(pRect->right, pBox->right);
+ pRetVal->bottom = min(pRect->bottom, pBox->bottom);
+}
+
+// protected
+
+bool CRealMediaWindowlessSite::GetBltService(IRMAVideoSurface** ppBltService)
+{
+ bool fRet = false;
+
+ if(ppBltService)
+ {
+ if(m_pParentSite)
+ {
+ fRet = m_pParentSite->GetBltService(ppBltService);
+ }
+ else if(m_pBltService)
+ {
+ (*ppBltService = m_pBltService)->AddRef();
+ fRet = true;
+ }
+ }
+
+ return(fRet);
+}
+
+void CRealMediaWindowlessSite::SetBltService(IRMAVideoSurface* pBltService)
+{
+ m_pBltService = pBltService;
+}
+
+// IRMAVideoSurface
+
+STDMETHODIMP CRealMediaWindowlessSite::Blt(UCHAR* /*IN*/ pImageData, RMABitmapInfoHeader* /*IN*/ pBitmapInfo, REF(PNxRect) /*IN*/ inDestRect, REF(PNxRect) /*IN*/ inSrcRect)
+{
+ BeginOptimizedBlt(pBitmapInfo);
+ return OptimizedBlt(pImageData, inDestRect, inSrcRect);
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::BeginOptimizedBlt(RMABitmapInfoHeader* /*IN*/ pBitmapInfo)
+{
+ if(memcmp(&m_bitmapInfo, pBitmapInfo, sizeof(RMABitmapInfoHeader)))
+ {
+ memcpy(&m_bitmapInfo, pBitmapInfo, sizeof(RMABitmapInfoHeader));
+
+ // format of image has changed somehow.
+ // do something here if this affects you.
+ }
+
+/*
+ CComPtr<IRMAVideoSurface> pBltService;
+ GetBltService(&pBltService);
+ if(!pBltService)
+ return PNR_UNEXPECTED;
+
+ RMA_COMPRESSION_TYPE ulType = (RMA_COMPRESSION_TYPE)-1;
+ pBltService->GetPreferredFormat(ulType);
+
+ if(pBitmapInfo->biCompression != ulType)
+ return PNR_UNEXPECTED;
+*/
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::OptimizedBlt(UCHAR* /*IN*/ pImageBits, REF(PNxRect) /*IN*/ rDestRect, REF(PNxRect) /*IN*/ rSrcRect)
+{
+ CComPtr<IRMAVideoSurface> pBltService;
+ GetBltService(&pBltService);
+
+ REGION* pRegion = GetRegion();
+
+ if(!pBltService || !pRegion)
+ return PNR_UNEXPECTED;
+
+ PNxPoint origin;
+ memset(&origin, 0, sizeof(PNxPoint));
+ GetTopLeft(&origin);
+ PNxRect adjustedDestRect;
+ adjustedDestRect.left = rDestRect.left + origin.x;
+ adjustedDestRect.top = rDestRect.top + origin.y;
+ adjustedDestRect.right = rDestRect.right + origin.x;
+ adjustedDestRect.bottom = rDestRect.bottom + origin.y;
+
+ for(int i = 0; i < pRegion->numRects; i++)
+ {
+ PNxRect* pRect = pRegion->rects+i;
+
+ // intersect the dest rect with the rect from the
+ // region to get the final dest rect.
+ PNxRect finalDestRect;
+ IntersectRect(&adjustedDestRect, pRect, &finalDestRect);
+
+ // now compute the src rect for this blt.
+ double xStretch = (double) (rDestRect.right - rDestRect.left) / (double) (rSrcRect.right - rSrcRect.left);
+ double yStretch = (double) (rDestRect.bottom - rDestRect.top) / (double) (rSrcRect.bottom - rSrcRect.top);
+
+ PNxRect finalSrcRect;
+ finalSrcRect.left = (INT32)((double)(finalDestRect.left-origin.x) / xStretch + 0.5);
+ finalSrcRect.top = (INT32)((double)(finalDestRect.top-origin.y) / yStretch + 0.5);
+ finalSrcRect.right = (INT32)((double)(finalDestRect.right-origin.x) / xStretch + 0.5);
+ finalSrcRect.bottom = (INT32)((double)(finalDestRect.bottom-origin.y) / yStretch + 0.5);
+
+ pBltService->Blt(pImageBits, &m_bitmapInfo, finalDestRect, finalSrcRect);
+ }
+
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::EndOptimizedBlt()
+{
+ memset(&m_bitmapInfo, 0, sizeof(m_bitmapInfo));
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::GetOptimizedFormat(REF(RMA_COMPRESSION_TYPE) /*OUT*/ ulType)
+{
+ ulType = m_bitmapInfo.biCompression;
+ return PNR_OK;
+}
+
+STDMETHODIMP CRealMediaWindowlessSite::GetPreferredFormat(REF(RMA_COMPRESSION_TYPE) /*OUT*/ ulType)
+{
+ CComPtr<IRMAVideoSurface> pBltService;
+ GetBltService(&pBltService);
+ if(!pBltService)
+ return PNR_UNEXPECTED;
+
+ return pBltService->GetPreferredFormat(ulType);
+}
diff --git a/src/apps/mplayerc/RealMediaWindowlessSite.h b/src/apps/mplayerc/RealMediaWindowlessSite.h
new file mode 100644
index 000000000..d96f49d94
--- /dev/null
+++ b/src/apps/mplayerc/RealMediaWindowlessSite.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "..\..\..\include\RealMedia\pntypes.h"
+#include "..\..\..\include\RealMedia\pnwintyp.h"
+#include "..\..\..\include\RealMedia\pncom.h"
+#include "..\..\..\include\RealMedia\rmapckts.h"
+#include "..\..\..\include\RealMedia\rmacomm.h"
+#include "..\..\..\include\RealMedia\rmamon.h"
+#include "..\..\..\include\RealMedia\rmafiles.h"
+#include "..\..\..\include\RealMedia\rmaengin.h"
+#include "..\..\..\include\RealMedia\rmacore.h"
+#include "..\..\..\include\RealMedia\rmaclsnk.h"
+#include "..\..\..\include\RealMedia\rmaerror.h"
+#include "..\..\..\include\RealMedia\rmaauth.h"
+#include "..\..\..\include\RealMedia\rmawin.h"
+#include "..\..\..\include\RealMedia\rmasite2.h"
+#include "..\..\..\include\RealMedia\rmaausvc.h"
+#include "..\..\..\include\RealMedia\rmavsurf.h"
+#include "..\..\..\include\RealMedia\rmaevent.h"
+
+namespace DSObjects
+{
+
+struct REGION
+{
+ REGION() : rects(0), pOSRegion(0) {}
+ long size;
+ long numRects;
+ PNxRect* rects;
+ PNxRect extents;
+ void* pOSRegion;
+};
+
+void ExtractRects(REGION* pRegion);
+REGION* RMACreateRectRegion(int left, int top, int right, int bottom);
+void RMASubtractRegion(REGION* regM, REGION* regS, REGION* regD);
+void RMAUnionRegion(REGION* reg1, REGION* reg2, REGION* regD);
+void RMAIntersectRegion(REGION* reg1, REGION* reg2, REGION* regD);
+BOOL RMAEqualRegion(REGION* reg1, REGION* reg2);
+void RMADestroyRegion(REGION* reg);
+REGION* RMACreateRegion();
+
+class CRealMediaWindowlessSite;
+
+//
+// CRealMediaVideoSurface
+//
+
+class CRealMediaWindowlessSite;
+
+class CRealMediaVideoSurface
+ : public CUnknown
+ , public IRMAVideoSurface
+{
+ void IntersectRect(PNxRect* pRect, PNxRect* pBox, PNxRect* pRetVal);
+
+protected:
+ CComPtr<IUnknown> m_pContext;
+ CRealMediaWindowlessSite* m_pSiteWindowless;
+ RMABitmapInfoHeader m_bitmapInfo;
+ RMABitmapInfoHeader m_lastBitmapInfo;
+
+public:
+ CRealMediaVideoSurface(IUnknown* pContext, CRealMediaWindowlessSite* pSiteWindowless);
+ virtual ~CRealMediaVideoSurface();
+
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ // IRMAVideoSurface
+
+ STDMETHODIMP Blt(UCHAR* /*IN*/ pImageData, RMABitmapInfoHeader* /*IN*/ pBitmapInfo, REF(PNxRect) /*IN*/ inDestRect, REF(PNxRect) /*IN*/ inSrcRect);
+ STDMETHODIMP BeginOptimizedBlt(RMABitmapInfoHeader* /*IN*/ pBitmapInfo);
+ STDMETHODIMP OptimizedBlt(UCHAR* /*IN*/ pImageBits, REF(PNxRect) /*IN*/ rDestRect, REF(PNxRect) /*IN*/ rSrcRect);
+ STDMETHODIMP EndOptimizedBlt();
+ STDMETHODIMP GetOptimizedFormat(REF(RMA_COMPRESSION_TYPE) /*OUT*/ ulType);
+ STDMETHODIMP GetPreferredFormat(REF(RMA_COMPRESSION_TYPE) /*OUT*/ ulType);
+};
+
+//
+// CRealMediaWindowlessSite
+//
+
+class CRealMediaWindowlessSite
+ : public CUnknown
+ , public IRMASite
+ , public IRMASite2
+ , public IRMASiteWindowless
+ , public IRMAVideoSurface
+{
+ CComQIPtr<IRMACommonClassFactory, &IID_IRMACommonClassFactory> m_pCCF;
+ CComPtr<IUnknown> m_pContext;
+ CComPtr<IRMAValues> m_pValues;
+
+ CComPtr<IRMASiteUser> m_pUser;
+
+ CRealMediaWindowlessSite* m_pParentSite;
+ CInterfaceList<IRMASite, &IID_IRMASite> m_pChildren;
+
+ CComPtr<IRMASiteWatcher> m_pWatcher;
+ CInterfaceList<IRMAPassiveSiteWatcher, &IID_IRMAPassiveSiteWatcher> m_pPassiveWatchers;
+
+ PNxSize m_size;
+ PNxPoint m_position;
+ bool m_fDamaged, m_fInRedraw, m_fIsVisible;
+ INT32 m_lZOrder;
+
+ //
+
+ REGION* m_pRegion;
+ REGION* m_pRegionWithoutChildren;
+
+ void RecomputeRegion();
+ void InternalRecomputeRegion();
+ void ComputeRegion();
+ void SubtractSite(REGION* pRegion);
+
+ void UpdateZOrder(CRealMediaWindowlessSite* pUpdatedChildSite, INT32 lOldZOrder, INT32 lNewZOrder);
+ void SetInternalZOrder(INT32 lZOrder);
+
+public:
+ CRealMediaWindowlessSite(HRESULT& hr, IUnknown* pContext, CRealMediaWindowlessSite* pParentSite = NULL, IUnknown* pUnkOuter = NULL);
+ virtual ~CRealMediaWindowlessSite();
+
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ void GetTopLeft(PNxPoint* pPoint);
+ REGION* GetRegion();
+
+ // IRMASiteWindowless
+
+ STDMETHODIMP EventOccurred(PNxEvent* /*IN*/ pEvent);
+ STDMETHODIMP_(PNxWindow*) GetParentWindow();
+
+ // IRMASite
+
+ STDMETHODIMP AttachUser(IRMASiteUser* /*IN*/ pUser);
+ STDMETHODIMP DetachUser();
+ STDMETHODIMP GetUser(REF(IRMASiteUser*) /*OUT*/ pUser);
+
+ STDMETHODIMP CreateChild(REF(IRMASite*) /*OUT*/ pChildSite);
+ STDMETHODIMP DestroyChild(IRMASite* /*IN*/ pChildSite);
+
+ STDMETHODIMP AttachWatcher(IRMASiteWatcher* /*IN*/ pWatcher);
+ STDMETHODIMP DetachWatcher();
+
+ STDMETHODIMP SetPosition(PNxPoint position);
+ STDMETHODIMP GetPosition(REF(PNxPoint) position);
+ STDMETHODIMP SetSize(PNxSize size);
+ STDMETHODIMP GetSize(REF(PNxSize) size);
+
+ STDMETHODIMP DamageRect(PNxRect rect);
+ STDMETHODIMP DamageRegion(PNxRegion region);
+ STDMETHODIMP ForceRedraw();
+
+ // IRMASite2
+
+ STDMETHODIMP UpdateSiteWindow(PNxWindow* /*IN*/ pWindow);
+ STDMETHODIMP ShowSite(BOOL bShow);
+ STDMETHODIMP_(BOOL) IsSiteVisible();
+ STDMETHODIMP SetZOrder(INT32 lZOrder);
+ STDMETHODIMP GetZOrder(REF(INT32) lZOrder);
+ STDMETHODIMP MoveSiteToTop();
+ STDMETHODIMP GetVideoSurface(REF(IRMAVideoSurface*) pSurface);
+ STDMETHODIMP_(UINT32) GetNumberOfChildSites();
+
+ STDMETHODIMP AddPassiveSiteWatcher(IRMAPassiveSiteWatcher* pWatcher);
+ STDMETHODIMP RemovePassiveSiteWatcher(IRMAPassiveSiteWatcher* pWatcher);
+
+ STDMETHODIMP SetCursor(PNxCursor cursor, REF(PNxCursor) oldCursor);
+
+private:
+ void IntersectRect(PNxRect* pRect, PNxRect* pBox, PNxRect* pRetVal);
+
+protected:
+ RMABitmapInfoHeader m_bitmapInfo;
+ RMABitmapInfoHeader m_lastBitmapInfo;
+
+ CComPtr<IRMAVideoSurface> m_pBltService;
+
+public:
+ bool GetBltService(IRMAVideoSurface** ppBltService);
+ void SetBltService(IRMAVideoSurface* ppBltService);
+
+ // IRMAVideoSurface
+
+ STDMETHODIMP Blt(UCHAR* /*IN*/ pImageData, RMABitmapInfoHeader* /*IN*/ pBitmapInfo, REF(PNxRect) /*IN*/ inDestRect, REF(PNxRect) /*IN*/ inSrcRect);
+ STDMETHODIMP BeginOptimizedBlt(RMABitmapInfoHeader* /*IN*/ pBitmapInfo);
+ STDMETHODIMP OptimizedBlt(UCHAR* /*IN*/ pImageBits, REF(PNxRect) /*IN*/ rDestRect, REF(PNxRect) /*IN*/ rSrcRect);
+ STDMETHODIMP EndOptimizedBlt();
+ STDMETHODIMP GetOptimizedFormat(REF(RMA_COMPRESSION_TYPE) /*OUT*/ ulType);
+ STDMETHODIMP GetPreferredFormat(REF(RMA_COMPRESSION_TYPE) /*OUT*/ ulType);
+};
+
+}
+using namespace DSObjects;
diff --git a/src/apps/mplayerc/RegFilterChooserDlg.cpp b/src/apps/mplayerc/RegFilterChooserDlg.cpp
new file mode 100644
index 000000000..c9372c87f
--- /dev/null
+++ b/src/apps/mplayerc/RegFilterChooserDlg.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// RegFilterChooserDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include <dmo.h>
+#include "RegFilterChooserDlg.h"
+#include "FGFilter.h"
+#include "..\..\DSUtil\DSUtil.h"
+
+
+// CRegFilterChooserDlg dialog
+
+//IMPLEMENT_DYNAMIC(CRegFilterChooserDlg, CResizableDialog)
+CRegFilterChooserDlg::CRegFilterChooserDlg(CWnd* pParent /*=NULL*/)
+ : CResizableDialog(CRegFilterChooserDlg::IDD, pParent)
+{
+}
+
+CRegFilterChooserDlg::~CRegFilterChooserDlg()
+{
+ POSITION pos = m_filters.GetHeadPosition();
+ while(pos) delete m_filters.GetNext(pos);
+}
+
+void CRegFilterChooserDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_LIST2, m_list);
+}
+
+void CRegFilterChooserDlg::AddToList(IMoniker* pMoniker)
+{
+ CComPtr<IPropertyBag> pPB;
+ if(SUCCEEDED(pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB)))
+ {
+ CComVariant var;
+ if(SUCCEEDED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL)))
+ {
+ m_list.SetItemData(
+ m_list.InsertItem(-1, CString(CStringW(var.bstrVal))),
+ (DWORD_PTR)m_monikers.AddTail(pMoniker));
+ }
+ }
+
+}
+
+
+BEGIN_MESSAGE_MAP(CRegFilterChooserDlg, CResizableDialog)
+ ON_LBN_DBLCLK(IDC_LIST1, OnLbnDblclkList1)
+ ON_UPDATE_COMMAND_UI(IDOK, OnUpdateOK)
+ ON_BN_CLICKED(IDOK, OnBnClickedOk)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+ ON_NOTIFY(NM_DBLCLK, IDC_LIST2, OnNMDblclkList2)
+END_MESSAGE_MAP()
+
+
+// CRegFilterChooserDlg message handlers
+
+BOOL CRegFilterChooserDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ BeginEnumSysDev(CLSID_LegacyAmFilterCategory, pMoniker)
+ {
+ AddToList(pMoniker);
+ }
+ EndEnumSysDev
+
+ BeginEnumSysDev(DMOCATEGORY_VIDEO_EFFECT, pMoniker)
+ {
+ AddToList(pMoniker);
+ }
+ EndEnumSysDev
+
+ BeginEnumSysDev(DMOCATEGORY_AUDIO_EFFECT, pMoniker)
+ {
+ AddToList(pMoniker);
+ }
+ EndEnumSysDev
+
+ AddAnchor(IDC_LIST2, TOP_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_BUTTON1, BOTTOM_LEFT);
+ AddAnchor(IDOK, BOTTOM_RIGHT);
+ AddAnchor(IDCANCEL, BOTTOM_RIGHT);
+
+ SetMinTrackSize(CSize(300,100));
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CRegFilterChooserDlg::OnLbnDblclkList1()
+{
+ SendMessage(WM_COMMAND, IDOK);
+}
+
+void CRegFilterChooserDlg::OnUpdateOK(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(!!m_list.GetFirstSelectedItemPosition());
+}
+
+void CRegFilterChooserDlg::OnBnClickedOk()
+{
+ CComPtr<IMoniker> pMoniker;
+
+ POSITION pos = m_list.GetFirstSelectedItemPosition();
+ if(pos) pos = (POSITION)m_list.GetItemData(m_list.GetNextSelectedItem(pos));
+ if(pos) pMoniker = m_monikers.GetAt(pos);
+ if(pMoniker)
+ {
+ CFGFilterRegistry fgf(pMoniker);
+ FilterOverride* f = new FilterOverride;
+ f->fDisabled = false;
+ f->type = FilterOverride::REGISTERED;
+ f->name = fgf.GetName();
+ f->dispname = fgf.GetDisplayName();
+ f->guids.AddTailList(&fgf.GetTypes());
+ f->backup.AddTailList(&fgf.GetTypes());
+ f->dwMerit = fgf.GetMeritForDirectShow();
+ f->iLoadType = FilterOverride::MERIT;
+ m_filters.AddTail(f);
+ }
+
+ __super::OnOK();
+}
+
+void CRegFilterChooserDlg::OnBnClickedButton1()
+{
+ CFileDialog dlg(TRUE, NULL, NULL,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY,
+ _T("DirectShow Filters (*.dll,*.ax)|*.dll;*.ax|"), this, 0);
+
+ if(dlg.DoModal() == IDOK)
+ {
+ CFilterMapper2 fm2(false);
+ fm2.Register(dlg.GetPathName());
+ m_filters.AddTail(&fm2.m_filters);
+ fm2.m_filters.RemoveAll();
+
+ __super::OnOK();
+ }
+}
+
+void CRegFilterChooserDlg::OnNMDblclkList2(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ if(m_list.GetFirstSelectedItemPosition())
+ {
+ OnBnClickedOk();
+ }
+
+ *pResult = 0;
+}
diff --git a/src/apps/mplayerc/RegFilterChooserDlg.h b/src/apps/mplayerc/RegFilterChooserDlg.h
new file mode 100644
index 000000000..33ab06202
--- /dev/null
+++ b/src/apps/mplayerc/RegFilterChooserDlg.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "afxwin.h"
+
+// CRegFilterChooserDlg dialog
+
+class CRegFilterChooserDlg : public CResizableDialog
+{
+// DECLARE_DYNAMIC(CRegFilterChooserDlg)
+
+ CInterfaceList<IMoniker> m_monikers;
+ void AddToList(IMoniker* pMoniker);
+
+public:
+ CRegFilterChooserDlg(CWnd* pParent = NULL); // standard constructor
+ virtual ~CRegFilterChooserDlg();
+
+ CList<FilterOverride*> m_filters;
+
+// Dialog Data
+ enum { IDD = IDD_ADDREGFILTER };
+ CListCtrl m_list;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnLbnDblclkList1();
+ afx_msg void OnUpdateOK(CCmdUI* pCmdUI);
+ afx_msg void OnBnClickedOk();
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnNMDblclkList2(NMHDR *pNMHDR, LRESULT *pResult);
+};
diff --git a/src/apps/mplayerc/Release Unicode/d3dx9_28.dll b/src/apps/mplayerc/Release Unicode/d3dx9_28.dll
new file mode 100644
index 000000000..fde5bd447
--- /dev/null
+++ b/src/apps/mplayerc/Release Unicode/d3dx9_28.dll
Binary files differ
diff --git a/src/apps/mplayerc/SaveDlg.cpp b/src/apps/mplayerc/SaveDlg.cpp
new file mode 100644
index 000000000..83fa2dcb8
--- /dev/null
+++ b/src/apps/mplayerc/SaveDlg.cpp
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// SaveDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "SaveDlg.h"
+#include "..\..\filters\filters.h"
+
+
+// CSaveDlg dialog
+
+IMPLEMENT_DYNAMIC(CSaveDlg, CCmdUIDialog)
+CSaveDlg::CSaveDlg(CString in, CString out, CWnd* pParent /*=NULL*/)
+ : CCmdUIDialog(CSaveDlg::IDD, pParent)
+ , m_in(in), m_out(out)
+ , m_nIDTimerEvent(-1)
+{
+}
+
+CSaveDlg::~CSaveDlg()
+{
+}
+
+void CSaveDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CCmdUIDialog::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_ANIMATE1, m_anim);
+ DDX_Control(pDX, IDC_PROGRESS1, m_progress);
+ DDX_Control(pDX, IDC_REPORT, m_report);
+ DDX_Control(pDX, IDC_FROMTO, m_fromto);
+}
+
+
+BEGIN_MESSAGE_MAP(CSaveDlg, CCmdUIDialog)
+ ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel)
+ ON_MESSAGE(WM_GRAPHNOTIFY, OnGraphNotify)
+ ON_WM_TIMER()
+END_MESSAGE_MAP()
+
+
+// CSaveDlg message handlers
+
+BOOL CSaveDlg::OnInitDialog()
+{
+ CCmdUIDialog::OnInitDialog();
+
+ m_anim.Open(IDR_AVI_FILECOPY);
+ m_anim.Play(0, -1, -1);
+
+ CString str, in = m_in, out = m_out;
+ if(in.GetLength() > 60) in = in.Left(17) + _T("..") + in.Right(43);
+ if(out.GetLength() > 60) out = out.Left(17) + _T("..") + out.Right(43);
+ str.Format(_T("%s\r\n%s"), in, out);
+ m_fromto.SetWindowText(str);
+
+ m_progress.SetRange(0, 100);
+
+ if(FAILED(pGB.CoCreateInstance(CLSID_FilterGraph)) || !(pMC = pGB) || !(pME = pGB) || !(pMS = pGB)
+ || FAILED(pME->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0)))
+ {
+ m_report.SetWindowText(_T("Error"));
+ return FALSE;
+ }
+
+ HRESULT hr;
+
+ CStringW fnw = m_in;
+ CComPtr<IFileSourceFilter> pReader;
+
+ if(!pReader && m_in.Mid(m_in.ReverseFind('.')+1).MakeLower() == _T("cda"))
+ {
+ hr = S_OK;
+ CComPtr<IUnknown> pUnk = (IUnknown*)(INonDelegatingUnknown*)new CCDDAReader(NULL, &hr);
+ if(FAILED(hr) || !(pReader = pUnk) || FAILED(pReader->Load(fnw, NULL)))
+ pReader.Release();
+ }
+
+ if(!pReader)
+ {
+ hr = S_OK;
+ CComPtr<IUnknown> pUnk = (IUnknown*)(INonDelegatingUnknown*)new CCDXAReader(NULL, &hr);
+ if(FAILED(hr) || !(pReader = pUnk) || FAILED(pReader->Load(fnw, NULL)))
+ pReader.Release();
+ }
+
+ if(!pReader /*&& ext == _T("ifo")*/)
+ {
+ hr = S_OK;
+ CComPtr<IUnknown> pUnk = (IUnknown*)(INonDelegatingUnknown*)new CVTSReader(NULL, &hr);
+ if(FAILED(hr) || !(pReader = pUnk) || FAILED(pReader->Load(fnw, NULL)))
+ pReader.Release();
+ else
+ {
+ CPath pout(m_out);
+ pout.RenameExtension(_T(".ifo"));
+ CopyFile(m_in, pout, FALSE);
+ }
+ }
+
+ if(!pReader)
+ {
+ hr = S_OK;
+ CComPtr<IUnknown> pUnk;
+ pUnk.CoCreateInstance(CLSID_AsyncReader);
+ if(FAILED(hr) || !(pReader = pUnk) || FAILED(pReader->Load(fnw, NULL)))
+ pReader.Release();
+ }
+
+ if(!pReader)
+ {
+ hr = S_OK;
+ CComPtr<IUnknown> pUnk;
+ pUnk.CoCreateInstance(CLSID_URLReader);
+ if(FAILED(hr) || !(pReader = pUnk) || FAILED(hr = pReader->Load(fnw, NULL)))
+ pReader.Release();
+ }
+
+ CComQIPtr<IBaseFilter> pSrc = pReader;
+ if(FAILED(pGB->AddFilter(pSrc, fnw)))
+ {
+ m_report.SetWindowText(_T("Sorry, can't save this file, press cancel"));
+ return FALSE;
+ }
+
+ CComQIPtr<IBaseFilter> pMid = new CStreamDriveThruFilter(NULL, &hr);
+ if(FAILED(pGB->AddFilter(pMid, L"StreamDriveThru")))
+ {
+ m_report.SetWindowText(_T("Error"));
+ return FALSE;
+ }
+
+ CComQIPtr<IBaseFilter> pDst;
+ pDst.CoCreateInstance(CLSID_FileWriter);
+ CComQIPtr<IFileSinkFilter2> pFSF = pDst;
+ pFSF->SetFileName(CStringW(m_out), NULL);
+ pFSF->SetMode(AM_FILE_OVERWRITE);
+ if(FAILED(pGB->AddFilter(pDst, L"File Writer")))
+ {
+ m_report.SetWindowText(_T("Error"));
+ return FALSE;
+ }
+
+ hr = pGB->Connect(
+ GetFirstPin((pSrc), PINDIR_OUTPUT),
+ GetFirstPin((pMid), PINDIR_INPUT));
+
+ hr = pGB->Connect(
+ GetFirstPin((pMid), PINDIR_OUTPUT),
+ GetFirstPin((pDst), PINDIR_INPUT));
+
+pMS = pMid;
+
+ pMC->Run();
+
+ m_nIDTimerEvent = SetTimer(1, 1000, NULL);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CSaveDlg::OnBnClickedCancel()
+{
+ if(pMC) pMC->Stop();
+
+ OnCancel();
+}
+
+LRESULT CSaveDlg::OnGraphNotify(WPARAM wParam, LPARAM lParam)
+{
+ LONG evCode, evParam1, evParam2;
+ while(pME && SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR*)&evParam1, (LONG_PTR*)&evParam2, 0)))
+ {
+ HRESULT hr = pME->FreeEventParams(evCode, evParam1, evParam2);
+
+ if(EC_COMPLETE == evCode)
+ {
+ EndDialog(IDOK);
+ }
+ else if(EC_ERRORABORT == evCode)
+ {
+ TRACE(_T("CSaveDlg::OnGraphNotify / EC_ERRORABORT, hr = %08x\n"), (HRESULT)evParam1);
+ m_report.SetWindowText(_T("Copying unexpectedly terminated!"));
+ }
+ }
+
+ return 0;
+}
+
+void CSaveDlg::OnTimer(UINT nIDEvent)
+{
+ if(nIDEvent == m_nIDTimerEvent && pGB)
+ {
+ if(pMS)
+ {
+ CString str;
+ REFERENCE_TIME pos = 0, dur = 0;
+ pMS->GetCurrentPosition(&pos);
+ pMS->GetDuration(&dur);
+ REFERENCE_TIME time = 0;
+ CComQIPtr<IMediaSeeking>(pGB)->GetCurrentPosition(&time);
+ REFERENCE_TIME speed = time > 0 ? pos*10000000/time / 1024 : 0i64;
+ str.Format(_T("%I64d/%I64d KB, %I64d KB/s, %I64d s"),
+ pos/1024, dur/1024, speed, speed > 0 ? (dur-pos)/1024 / speed : 0);
+ m_report.SetWindowText(str);
+
+ m_progress.SetPos(dur > 0 ? (int)(100*pos/dur) : 0);
+ }
+ }
+
+ CCmdUIDialog::OnTimer(nIDEvent);
+}
diff --git a/src/apps/mplayerc/SaveDlg.h b/src/apps/mplayerc/SaveDlg.h
new file mode 100644
index 000000000..507324e61
--- /dev/null
+++ b/src/apps/mplayerc/SaveDlg.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "afxcmn.h"
+#include "afxwin.h"
+
+// CSaveDlg dialog
+
+class CSaveDlg : public CCmdUIDialog
+{
+ DECLARE_DYNAMIC(CSaveDlg)
+
+private:
+ CString m_in, m_out;
+ CComPtr<IGraphBuilder> pGB;
+ CComQIPtr<IMediaControl> pMC;
+ CComQIPtr<IMediaEventEx> pME;
+ CComQIPtr<IMediaSeeking> pMS;
+ UINT_PTR m_nIDTimerEvent;
+
+public:
+ CSaveDlg(CString in, CString out, CWnd* pParent = NULL); // standard constructor
+ virtual ~CSaveDlg();
+
+// Dialog Data
+ enum { IDD = IDD_SAVE_DLG };
+ CAnimateCtrl m_anim;
+ CProgressCtrl m_progress;
+ CStatic m_report;
+ CStatic m_fromto;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+
+ DECLARE_MESSAGE_MAP()
+public:
+ afx_msg void OnBnClickedCancel();
+ afx_msg void OnTimer(UINT nIDEvent);
+ afx_msg LRESULT OnGraphNotify(WPARAM wParam, LPARAM lParam);
+};
diff --git a/src/apps/mplayerc/SaveTextFileDialog.cpp b/src/apps/mplayerc/SaveTextFileDialog.cpp
new file mode 100644
index 000000000..c4c21a560
--- /dev/null
+++ b/src/apps/mplayerc/SaveTextFileDialog.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// SaveTextFileDialog.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "SaveTextFileDialog.h"
+
+
+// CSaveTextFileDialog
+
+IMPLEMENT_DYNAMIC(CSaveTextFileDialog, CFileDialog)
+CSaveTextFileDialog::CSaveTextFileDialog(
+ CTextFile::enc e,
+ LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
+ LPCTSTR lpszFilter, CWnd* pParentWnd) :
+ CFileDialog(FALSE, lpszDefExt, lpszFileName,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST,
+ lpszFilter, pParentWnd, 0),
+ m_e(e)
+{
+ if(m_ofn.lStructSize == sizeof(OPENFILENAME))
+ {
+ SetTemplate(0, IDD_SAVETEXTFILEDIALOGTEMPL);
+ }
+ else /*if(m_ofn.lStructSize == OPENFILENAME_SIZE_VERSION_400)*/
+ {
+ SetTemplate(0, IDD_SAVETEXTFILEDIALOGTEMPL_400);
+ }
+}
+
+CSaveTextFileDialog::~CSaveTextFileDialog()
+{
+}
+
+void CSaveTextFileDialog::DoDataExchange(CDataExchange* pDX)
+{
+ DDX_Control(pDX, IDC_COMBO1, m_encoding);
+ __super::DoDataExchange(pDX);
+}
+
+BOOL CSaveTextFileDialog::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ m_encoding.SetItemData(m_encoding.AddString(_T("ANSI")), CTextFile::ASCII);
+ m_encoding.SetItemData(m_encoding.AddString(_T("Unicode 16-LE")), CTextFile::LE16);
+ m_encoding.SetItemData(m_encoding.AddString(_T("Unicode 16-BE")), CTextFile::BE16);
+ m_encoding.SetItemData(m_encoding.AddString(_T("UTF-8")), CTextFile::UTF8);
+
+ switch(m_e)
+ {
+ default:
+ case CTextFile::ASCII: m_encoding.SetCurSel(0); break;
+ case CTextFile::LE16: m_encoding.SetCurSel(1); break;
+ case CTextFile::BE16: m_encoding.SetCurSel(2); break;
+ case CTextFile::UTF8: m_encoding.SetCurSel(3); break;
+ }
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BEGIN_MESSAGE_MAP(CSaveTextFileDialog, CFileDialog)
+END_MESSAGE_MAP()
+
+// CSaveTextFileDialog message handlers
+
+BOOL CSaveTextFileDialog::OnFileNameOK()
+{
+ m_e = (CTextFile::enc)m_encoding.GetItemData(m_encoding.GetCurSel());
+ return __super::OnFileNameOK();
+}
diff --git a/src/apps/mplayerc/SaveTextFileDialog.h b/src/apps/mplayerc/SaveTextFileDialog.h
new file mode 100644
index 000000000..a6b9d24a1
--- /dev/null
+++ b/src/apps/mplayerc/SaveTextFileDialog.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "..\..\subtitles\TextFile.h"
+
+// CSaveTextFileDialog
+
+class CSaveTextFileDialog : public CFileDialog
+{
+ DECLARE_DYNAMIC(CSaveTextFileDialog)
+
+private:
+ CTextFile::enc m_e;
+
+public:
+ CSaveTextFileDialog(
+ CTextFile::enc e,
+ LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL,
+ LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL);
+ virtual ~CSaveTextFileDialog();
+
+ CComboBox m_encoding;
+
+ CTextFile::enc GetEncoding() {return(m_e);}
+
+protected:
+ DECLARE_MESSAGE_MAP()
+ virtual void DoDataExchange(CDataExchange* pDX);
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnFileNameOK();
+
+public:
+ afx_msg void OnEncodingChange();
+};
+
+
diff --git a/src/apps/mplayerc/SaveThumbnailsDialog.cpp b/src/apps/mplayerc/SaveThumbnailsDialog.cpp
new file mode 100644
index 000000000..66723d716
--- /dev/null
+++ b/src/apps/mplayerc/SaveThumbnailsDialog.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// SaveThumbnailsDialog.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "SaveThumbnailsDialog.h"
+
+
+// CSaveThumbnailsDialog
+
+IMPLEMENT_DYNAMIC(CSaveThumbnailsDialog, CFileDialog)
+CSaveThumbnailsDialog::CSaveThumbnailsDialog(
+ int rows, int cols, int width,
+ LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
+ LPCTSTR lpszFilter, CWnd* pParentWnd) :
+ CFileDialog(FALSE, lpszDefExt, lpszFileName,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST,
+ lpszFilter, pParentWnd, 0),
+ m_rows(rows), m_cols(cols), m_width(width)
+{
+ if(m_ofn.lStructSize == sizeof(OPENFILENAME))
+ {
+ SetTemplate(0, IDD_SAVETHUMBSDIALOGTEMPL);
+ }
+ else /*if(m_ofn.lStructSize == OPENFILENAME_SIZE_VERSION_400)*/
+ {
+ SetTemplate(0, IDD_SAVETHUMBSDIALOGTEMPL_400);
+ }
+}
+
+CSaveThumbnailsDialog::~CSaveThumbnailsDialog()
+{
+}
+
+void CSaveThumbnailsDialog::DoDataExchange(CDataExchange* pDX)
+{
+ DDX_Control(pDX, IDC_SPIN1, m_rowsctrl);
+ DDX_Control(pDX, IDC_SPIN2, m_colsctrl);
+ DDX_Control(pDX, IDC_SPIN3, m_widthctrl);
+ __super::DoDataExchange(pDX);
+}
+
+BOOL CSaveThumbnailsDialog::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ m_rowsctrl.SetRange(0, 8);
+ m_colsctrl.SetRange(0, 8);
+ m_widthctrl.SetRange(256, 2048);
+ m_rowsctrl.SetPos(m_rows);
+ m_colsctrl.SetPos(m_cols);
+ m_widthctrl.SetPos(m_width);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+BEGIN_MESSAGE_MAP(CSaveThumbnailsDialog, CFileDialog)
+END_MESSAGE_MAP()
+
+// CSaveThumbnailsDialog message handlers
+
+BOOL CSaveThumbnailsDialog::OnFileNameOK()
+{
+ m_rows = m_rowsctrl.GetPos();
+ m_cols = m_colsctrl.GetPos();
+ m_width = m_widthctrl.GetPos();
+
+ return __super::OnFileNameOK();
+}
diff --git a/src/apps/mplayerc/SaveThumbnailsDialog.h b/src/apps/mplayerc/SaveThumbnailsDialog.h
new file mode 100644
index 000000000..646be2103
--- /dev/null
+++ b/src/apps/mplayerc/SaveThumbnailsDialog.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+// CSaveThumbnailsDialog
+
+class CSaveThumbnailsDialog : public CFileDialog
+{
+ DECLARE_DYNAMIC(CSaveThumbnailsDialog)
+
+public:
+ CSaveThumbnailsDialog(
+ int rows, int cols, int width,
+ LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL,
+ LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL);
+ virtual ~CSaveThumbnailsDialog();
+
+protected:
+ DECLARE_MESSAGE_MAP()
+ virtual void DoDataExchange(CDataExchange* pDX);
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnFileNameOK();
+
+public:
+ int m_rows, m_cols, m_width;
+ CSpinButtonCtrl m_rowsctrl;
+ CSpinButtonCtrl m_colsctrl;
+ CSpinButtonCtrl m_widthctrl;
+};
+
+
diff --git a/src/apps/mplayerc/SelectMediaType.cpp b/src/apps/mplayerc/SelectMediaType.cpp
new file mode 100644
index 000000000..d0e40197e
--- /dev/null
+++ b/src/apps/mplayerc/SelectMediaType.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// SelectMediaType.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "SelectMediaType.h"
+#include "..\..\DSUtil\DSUtil.h"
+
+
+// CSelectMediaType dialog
+
+IMPLEMENT_DYNAMIC(CSelectMediaType, CCmdUIDialog)
+CSelectMediaType::CSelectMediaType(CAtlArray<GUID>& guids, GUID guid, CWnd* pParent /*=NULL*/)
+ : CCmdUIDialog(CSelectMediaType::IDD, pParent)
+ , m_guids(guids), m_guid(guid)
+{
+ m_guidstr = CStringFromGUID(guid);
+}
+
+CSelectMediaType::~CSelectMediaType()
+{
+}
+
+void CSelectMediaType::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_CBString(pDX, IDC_COMBO1, m_guidstr);
+ DDX_Control(pDX, IDC_COMBO1, m_guidsctrl);
+}
+
+
+BEGIN_MESSAGE_MAP(CSelectMediaType, CCmdUIDialog)
+ ON_CBN_EDITCHANGE(IDC_COMBO1, OnCbnEditchangeCombo1)
+ ON_UPDATE_COMMAND_UI(IDOK, OnUpdateOK)
+END_MESSAGE_MAP()
+
+
+// CSelectMediaType message handlers
+
+BOOL CSelectMediaType::OnInitDialog()
+{
+ CCmdUIDialog::OnInitDialog();
+
+ for(int i = 0; i < m_guids.GetCount(); i++)
+ {
+ m_guidsctrl.AddString(GetMediaTypeName(m_guids[i]));
+ }
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CSelectMediaType::OnCbnEditchangeCombo1()
+{
+ UpdateData();
+ int i = m_guidsctrl.FindStringExact(0, m_guidstr);
+ if(i >= 0)
+ {
+ DWORD sel = m_guidsctrl.GetEditSel();
+ m_guidsctrl.SetCurSel(i);
+ m_guidsctrl.SetEditSel(sel,sel);
+ }
+}
+
+void CSelectMediaType::OnUpdateOK(CCmdUI* pCmdUI)
+{
+ UpdateData();
+
+ pCmdUI->Enable(!m_guidstr.IsEmpty() && (m_guidsctrl.GetCurSel() >= 0 || GUIDFromCString(m_guidstr) != GUID_NULL));
+}
+
+void CSelectMediaType::OnOK()
+{
+ UpdateData();
+
+ int i = m_guidsctrl.GetCurSel();
+ m_guid = i >= 0 ? m_guids[i] : GUIDFromCString(m_guidstr);
+
+ CCmdUIDialog::OnOK();
+}
diff --git a/src/apps/mplayerc/SelectMediaType.h b/src/apps/mplayerc/SelectMediaType.h
new file mode 100644
index 000000000..e3f71139f
--- /dev/null
+++ b/src/apps/mplayerc/SelectMediaType.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "afxwin.h"
+
+// CSelectMediaType dialog
+
+class CSelectMediaType : public CCmdUIDialog
+{
+ DECLARE_DYNAMIC(CSelectMediaType)
+
+private:
+ CAtlArray<GUID>& m_guids;
+
+public:
+ CSelectMediaType(CAtlArray<GUID>& guids, GUID guid, CWnd* pParent = NULL); // standard constructor
+ virtual ~CSelectMediaType();
+
+ GUID m_guid;
+
+// Dialog Data
+ enum { IDD = IDD_SELECTMEDIATYPE };
+ CString m_guidstr;
+ CComboBox m_guidsctrl;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+
+ DECLARE_MESSAGE_MAP()
+public:
+ afx_msg void OnCbnEditchangeCombo1();
+ afx_msg void OnUpdateOK(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/ShaderAutoCompleteDlg.cpp b/src/apps/mplayerc/ShaderAutoCompleteDlg.cpp
new file mode 100644
index 000000000..04655cd33
--- /dev/null
+++ b/src/apps/mplayerc/ShaderAutoCompleteDlg.cpp
@@ -0,0 +1,179 @@
+// ShaderAutoCompleteDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "ShaderAutoCompleteDlg.h"
+
+
+// CShaderAutoCompleteDlg dialog
+
+CShaderAutoCompleteDlg::CShaderAutoCompleteDlg(CWnd* pParent /*=NULL*/)
+ : CResizableDialog(CShaderAutoCompleteDlg::IDD, pParent)
+{
+ m_text[0] = 0;
+
+ m_inst[_T("abs")] = _T("abs(value a)|Absolute value (per component). ");
+ m_inst[_T("acos")] = _T("acos(x)|Returns the arccosine of each component of x. Each component should be in the range [-1, 1]. ");
+ m_inst[_T("all")] = _T("all(x)|Test if all components of x are nonzero. ");
+ m_inst[_T("any")] = _T("any(x)|Test is any component of x is nonzero. ");
+ m_inst[_T("asin")] = _T("asin(x)|Returns the arcsine of each component of x. Each component should be in the range [-pi/2, pi/2]. ");
+ m_inst[_T("atan")] = _T("atan(x)|Returns the arctangent of x. The return values are in the range [-pi/2, pi/2]. ");
+ m_inst[_T("atan2")] = _T("atan2(y, x)|Returns the arctangent of y/x. The signs of y and x are used to determine the quadrant of the return values in the range [-pi, pi]. atan2 is well-defined for every point other than the origin, even if x equals 0 and y does not equal 0. ");
+ m_inst[_T("ceil")] = _T("ceil(x)|Returns the smallest integer which is greater than or equal to x. ");
+ m_inst[_T("clamp")] = _T("clamp(x, min, max)|Clamps x to the range [min, max]. ");
+ m_inst[_T("clip")] = _T("clip(x)|Discards the current pixel, if any component of x is less than zero. This can be used to simulate clip planes, if each component of x represents the distance from a plane. ");
+ m_inst[_T("cos")] = _T("cos(x)|Returns the cosine of x. ");
+ m_inst[_T("cosh")] = _T("cosh(x)|Returns the hyperbolic cosine of x. ");
+ m_inst[_T("cross")] = _T("cross(a, b)|Returns the cross product of two 3-D vectors a and b. ");
+ m_inst[_T("d3dcolortoubyte4")] = _T("D3DCOLORtoUBYTE4(x)|Swizzles and scales components of the 4-D vector x to compensate for the lack of UBYTE4 support in some hardware. ");
+ m_inst[_T("ddx")] = _T("ddx(x)|Returns the partial derivative of x with respect to the screen-space x-coordinate. ");
+ m_inst[_T("ddy")] = _T("ddy(x)|Returns the partial derivative of x with respect to the screen-space y-coordinate. ");
+ m_inst[_T("degrees")] = _T("degrees(x)|Converts x from radians to degrees. ");
+ m_inst[_T("determinant")] = _T("determinant(m)|Returns the determinant of the square matrix m. ");
+ m_inst[_T("distance")] = _T("distance(a, b)|Returns the distance between two points a and b. ");
+ m_inst[_T("dot")] = _T("dot(a, b)|Returns the dot product of two vectors a and b. ");
+ m_inst[_T("exp")] = _T("exp(x)|Returns the base-e exponent ex. ");
+ m_inst[_T("exp2")] = _T("exp2(value a)|Base 2 Exp (per component). ");
+ m_inst[_T("faceforward")] = _T("faceforward(n, i, ng)|Returns -n * sign(dot(i, ng)). ");
+ m_inst[_T("floor")] = _T("floor(x)|Returns the greatest integer which is less than or equal to x. ");
+ m_inst[_T("fmod")] = _T("fmod(a, b)|Returns the floating point remainder f of a / b such that a = i * b + f, where i is an integer, f has the same sign as x, and the absolute value of f is less than the absolute value of b. ");
+ m_inst[_T("frac")] = _T("frac(x)|Returns the fractional part f of x, such that f is a value greater than or equal to 0, and less than 1. ");
+ m_inst[_T("frc")] = _T("frc(value a)|Fractional part (per component). ");
+ m_inst[_T("frexp")] = _T("frexp(x, out exp)|Returns the mantissa and exponent of x. frexp returns the mantissa, and the exponent is stored in the output parameter exp. If x is 0, the function returns 0 for both the mantissa and the exponent. ");
+ m_inst[_T("fwidth")] = _T("fwidth(x)|Returns abs(ddx(x))+abs(ddy(x)). ");
+ m_inst[_T("isfinite")] = _T("isfinite(x)|Returns true if x is finite, false otherwise. ");
+ m_inst[_T("isinf")] = _T("isinf(x)|Returns true if x is +INF or -INF, false otherwise. ");
+ m_inst[_T("isnan")] = _T("isnan(x)|Returns true if x is NAN or QNAN, false otherwise. ");
+ m_inst[_T("ldexp")] = _T("ldexp(x, exp)|Returns x * 2exp. ");
+ m_inst[_T("len")] = _T("len(value a)|Vector length. ");
+ m_inst[_T("length")] = _T("length(v)|Returns the length of the vector v. ");
+ m_inst[_T("lerp")] = _T("lerp(a, b, s)|Returns a + s(b - a). This linearly interpolates between a and b, such that the return value is a when s is 0, and b when s is 1. ");
+ m_inst[_T("lit")] = _T("lit(ndotl, ndoth, m)|Returns a lighting vector (ambient, diffuse, specular, 1): ambient = 1; diffuse = (ndotl < 0) ? 0 : ndotl; specular = (ndotl < 0) || (ndoth < 0) ? 0 : (ndoth * m); ");
+ m_inst[_T("log")] = _T("log(x)|Returns the base-e logarithm of x. If x is negative, the function returns indefinite. If x is 0, the function returns +INF. ");
+ m_inst[_T("log10")] = _T("log10(x)|Returns the base-10 logarithm of x. If x is negative, the function returns indefinite. If x is 0, the function returns +INF. ");
+ m_inst[_T("log2")] = _T("log2(x)|Returns the base-2 logarithm of x. If x is negative, the function returns indefinite. If x is 0, the function returns +INF. ");
+ m_inst[_T("max")] = _T("max(a, b)|Selects the greater of a and b. ");
+ m_inst[_T("min")] = _T("min(a, b)|Selects the lesser of a and b. ");
+ m_inst[_T("modf")] = _T("modf(x, out ip)|Splits the value x into fractional and integer parts, each of which has the same sign and x. The signed fractional portion of x is returned. The integer portion is stored in the output parameter ip. ");
+ m_inst[_T("mul")] = _T("mul(a, b)|Performs matrix multiplication between a and b. If a is a vector, it treated as a row vector. If b is a vector, it is treated as a column vector. The inner dimension acolumns and brows must be equal. The result has the dimension arows x bcolumns. ");
+ m_inst[_T("noise")] = _T("noise(x)|Not yet implemented. ");
+ m_inst[_T("normalize")] = _T("normalize(v)|Returns the normalized vector v / length(v). If the length of v is 0, the result is indefinite. ");
+ m_inst[_T("pow")] = _T("pow(x, y)|Returns xy. ");
+ m_inst[_T("radians")] = _T("radians(x)|Converts x from degrees to radians. ");
+ m_inst[_T("reflect")] = _T("reflect(i, n)|Returns the reflection vector v, given the entering ray direction i, and the surface normal n. Such that v = i - 2 * dot(i, n) * n ");
+ m_inst[_T("refract")] = _T("refract(i, n, eta)|Returns the refraction vector v, given the entering ray direction i, the surface normal n, and the relative index of refraction eta. If the angle between i and n is too great for a given eta, refract returns (0,0,0). ");
+ m_inst[_T("round")] = _T("round(x)|Rounds x to the nearest integer. ");
+ m_inst[_T("rsqrt")] = _T("rsqrt(x)|Returns 1 / sqrt(x). ");
+ m_inst[_T("saturate")] = _T("saturate(x)|Clamps x to the range [0, 1]. ");
+ m_inst[_T("sign")] = _T("sign(x)|Computes the sign of x. Returns -1 if x is less than 0, 0 if x equals 0, and 1 if x is greater than zero. ");
+ m_inst[_T("sin")] = _T("sin(x)|Returns the sine of x. ");
+ m_inst[_T("sincos")] = _T("sincos(x, out s, out c)|Returns the sine and cosine of x. sin(x) is stored in the output parameter s. cos(x) is stored in the output parameter c. ");
+ m_inst[_T("sinh")] = _T("sinh(x)|Returns the hyperbolic sine of x. ");
+ m_inst[_T("smoothstep")] = _T("smoothstep(min, max, x)|Returns 0 if x < min. Returns 1 if x > max. Returns a smooth Hermite interpolation between 0 and 1, if x is in the range [min, max]. ");
+ m_inst[_T("sqrt")] = _T("sqrt(value a)|Square root (per component). ");
+ m_inst[_T("step")] = _T("step(a, x)|Returns (x >= a) ? 1 : 0. ");
+ m_inst[_T("tan")] = _T("tan(x)|Returns the tangent of x. ");
+ m_inst[_T("tanh")] = _T("tanh(x)|Returns the hyperbolic tangent of x. ");
+ m_inst[_T("tex1d")] = _T("tex1D(s, t)|1-D texture lookup. s is a sampler or a sampler1D object. t is a scalar. ");
+ m_inst[_T("tex1d(")] = _T("tex1D(s, t, ddx, ddy)|1-D texture lookup, with derivatives. s is a sampler or sampler1D object. t, ddx, and ddy are scalars. ");
+ m_inst[_T("tex1dproj")] = _T("tex1Dproj(s, t)|1-D projective texture lookup. s is a sampler or sampler1D object. t is a 4-D vector. t is divided by its last component before the lookup takes place. ");
+ m_inst[_T("tex1dbias")] = _T("tex1Dbias(s, t)|1-D biased texture lookup. s is a sampler or sampler1D object. t is a 4-D vector. The mip level is biased by t.w before the lookup takes place. ");
+ m_inst[_T("tex2d")] = _T("tex2D(s, t)|2-D texture lookup. s is a sampler or a sampler2D object. t is a 2-D texture coordinate. ");
+ m_inst[_T("tex2d(")] = _T("tex2D(s, t, ddx, ddy)|2-D texture lookup, with derivatives. s is a sampler or sampler2D object. t, ddx, and ddy are 2-D vectors. ");
+ m_inst[_T("tex2dproj")] = _T("tex2Dproj(s, t)|2-D projective texture lookup. s is a sampler or sampler2D object. t is a 4-D vector. t is divided by its last component before the lookup takes place. ");
+ m_inst[_T("tex2dbias")] = _T("tex2Dbias(s, t)|2-D biased texture lookup. s is a sampler or sampler2D object. t is a 4-D vector. The mip level is biased by t.w before the lookup takes place. ");
+ m_inst[_T("tex3d")] = _T("tex3D(s, t)|3-D volume texture lookup. s is a sampler or a sampler3D object. t is a 3-D texture coordinate. ");
+ m_inst[_T("tex3d(")] = _T("tex3D(s, t, ddx, ddy)|3-D volume texture lookup, with derivatives. s is a sampler or sampler3D object. t, ddx, and ddy are 3-D vectors. ");
+ m_inst[_T("tex3dproj")] = _T("tex3Dproj(s, t)|3-D projective volume texture lookup. s is a sampler or sampler3D object. t is a 4-D vector. t is divided by its last component before the lookup takes place. ");
+ m_inst[_T("tex3dbias")] = _T("tex3Dbias(s, t)|3-D biased texture lookup. s is a sampler or sampler3D object. t is a 4-D vector. The mip level is biased by t.w before the lookup takes place. ");
+ m_inst[_T("texcube")] = _T("texCUBE(s, t)|3-D cube texture lookup. s is a sampler or a samplerCUBE object. t is a 3-D texture coordinate. ");
+ m_inst[_T("texcube(")] = _T("texCUBE(s, t, ddx, ddy)|3-D cube texture lookup, with derivatives. s is a sampler or samplerCUBE object. t, ddx, and ddy are 3-D vectors. ");
+ m_inst[_T("texcubeproj")] = _T("texCUBEproj(s, t)|3-D projective cube texture lookup. s is a sampler or samplerCUBE object. t is a 4-D vector. t is divided by its last component before the lookup takes place. ");
+ m_inst[_T("texcubebias")] = _T("texCUBEbias(s, t)|3-D biased cube texture lookup. s is a sampler or samplerCUBE object. t is a 4-dimensional vector. The mip level is biased by t.w before the lookup takes place. ");
+ m_inst[_T("transpose")] = _T("transpose(m)|Returns the transpose of the matrix m. If the source is dimension mrows x mcolumns, the result is dimension mcolumns x mrows. ");
+}
+
+CShaderAutoCompleteDlg::~CShaderAutoCompleteDlg()
+{
+}
+
+void CShaderAutoCompleteDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_LIST1, m_list);
+}
+
+
+BEGIN_MESSAGE_MAP(CShaderAutoCompleteDlg, CResizableDialog)
+ ON_WM_SETFOCUS()
+ ON_LBN_SELCHANGE(IDC_LIST1, OnLbnSelchangeList1)
+ ON_WM_SHOWWINDOW()
+END_MESSAGE_MAP()
+
+
+// CShaderAutoCompleteDlg message handlers
+
+BOOL CShaderAutoCompleteDlg::OnInitDialog()
+{
+ CResizableDialog::OnInitDialog();
+
+ AddAnchor(IDC_LIST1, TOP_LEFT, BOTTOM_RIGHT);
+
+ m_hToolTipWnd = CreateWindowEx(
+ WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, TTS_NOPREFIX | TTS_ALWAYSTIP,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ NULL, NULL, NULL, NULL);
+
+ memset(&m_ti, 0, sizeof(m_ti));
+ m_ti.cbSize = sizeof(TOOLINFO);
+ m_ti.uFlags = TTF_ABSOLUTE|TTF_TRACK;
+ m_ti.hwnd = m_hWnd;
+ m_ti.lpszText = m_text;
+
+ ::SendMessage(m_hToolTipWnd, TTM_ADDTOOL, 0, (LPARAM)&m_ti);
+ ::SendMessage(m_hToolTipWnd, TTM_SETMAXTIPWIDTH, 0, (LPARAM)400);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CShaderAutoCompleteDlg::OnSetFocus(CWnd* pOldWnd)
+{
+ __super::OnSetFocus(pOldWnd);
+
+ GetParent()->SetFocus();
+}
+
+void CShaderAutoCompleteDlg::OnLbnSelchangeList1()
+{
+ ::SendMessage(m_hToolTipWnd, TTM_TRACKACTIVATE, FALSE, (LPARAM)&m_ti);
+
+ int i = m_list.GetCurSel();
+ if(i < 0) return;
+
+ if(POSITION pos = (POSITION)m_list.GetItemData(i))
+ {
+ CString str, desc;
+ m_inst.GetNextAssoc(pos, str, desc);
+ CAtlList<CString> sl;
+ Explode(desc, sl, '|', 2);
+ if(sl.GetCount() != 2) return;
+ _tcscpy(m_ti.lpszText, sl.RemoveTail());
+ CRect r;
+ GetWindowRect(r);
+ ::SendMessage(m_hToolTipWnd, TTM_UPDATETIPTEXT, 0, (LPARAM)&m_ti);
+ ::SendMessage(m_hToolTipWnd, TTM_TRACKPOSITION, 0, (LPARAM)MAKELONG(r.left, r.bottom+1));
+ ::SendMessage(m_hToolTipWnd, TTM_TRACKACTIVATE, TRUE, (LPARAM)&m_ti);
+ }
+}
+
+void CShaderAutoCompleteDlg::OnShowWindow(BOOL bShow, UINT nStatus)
+{
+ CResizableDialog::OnShowWindow(bShow, nStatus);
+
+ if(!bShow)
+ {
+ ::SendMessage(m_hToolTipWnd, TTM_TRACKACTIVATE, FALSE, (LPARAM)&m_ti);
+ }
+}
diff --git a/src/apps/mplayerc/ShaderAutoCompleteDlg.h b/src/apps/mplayerc/ShaderAutoCompleteDlg.h
new file mode 100644
index 000000000..ede767438
--- /dev/null
+++ b/src/apps/mplayerc/ShaderAutoCompleteDlg.h
@@ -0,0 +1,33 @@
+#pragma once
+#include "resource.h"
+
+
+// CShaderAutoCompleteDlg dialog
+
+class CShaderAutoCompleteDlg : public CResizableDialog
+{
+ TOOLINFO m_ti;
+ HWND m_hToolTipWnd;
+ TCHAR m_text[1024];
+
+public:
+ CShaderAutoCompleteDlg(CWnd* pParent = NULL); // standard constructor
+ virtual ~CShaderAutoCompleteDlg();
+
+ CMap<CString, LPCTSTR, CString, CString> m_inst;
+
+// Dialog Data
+ enum { IDD = IDD_SHADERAUTOCOMPLETE_DLG };
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ CListBox m_list;
+ virtual BOOL OnInitDialog();
+ afx_msg void OnSetFocus(CWnd* pOldWnd);
+ afx_msg void OnLbnSelchangeList1();
+ afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
+};
diff --git a/src/apps/mplayerc/ShaderCombineDlg.cpp b/src/apps/mplayerc/ShaderCombineDlg.cpp
new file mode 100644
index 000000000..190c4acb5
--- /dev/null
+++ b/src/apps/mplayerc/ShaderCombineDlg.cpp
@@ -0,0 +1,131 @@
+// ShaderCombineDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "ShaderCombineDlg.h"
+
+// CShaderCombineDlg dialog
+
+CShaderCombineDlg::CShaderCombineDlg(CAtlList<CString>& labels, CWnd* pParent /*=NULL*/)
+ : CResizableDialog(CShaderCombineDlg::IDD, pParent)
+ , m_labels(labels)
+{
+}
+
+CShaderCombineDlg::~CShaderCombineDlg()
+{
+}
+
+void CShaderCombineDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_LIST1, m_list);
+ DDX_Control(pDX, IDC_COMBO1, m_combo);
+}
+
+BEGIN_MESSAGE_MAP(CShaderCombineDlg, CResizableDialog)
+ ON_BN_CLICKED(IDC_BUTTON2, &CShaderCombineDlg::OnBnClickedButton12)
+ ON_BN_CLICKED(IDC_BUTTON3, &CShaderCombineDlg::OnBnClickedButton13)
+ ON_BN_CLICKED(IDC_BUTTON1, &CShaderCombineDlg::OnBnClickedButton1)
+ ON_BN_CLICKED(IDC_BUTTON4, &CShaderCombineDlg::OnBnClickedButton11)
+END_MESSAGE_MAP()
+
+// CShaderCombineDlg message handlers
+
+BOOL CShaderCombineDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+ AddAnchor(IDC_LIST1, TOP_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_COMBO1, BOTTOM_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_STATIC1, BOTTOM_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_BUTTON2, BOTTOM_RIGHT);
+ AddAnchor(IDC_BUTTON3, BOTTOM_RIGHT);
+ AddAnchor(IDC_BUTTON1, TOP_RIGHT);
+ AddAnchor(IDC_BUTTON4, TOP_RIGHT);
+ AddAnchor(IDOK, TOP_RIGHT);
+ AddAnchor(IDCANCEL, TOP_RIGHT);
+
+ AppSettings& s = AfxGetAppSettings();
+
+ CString str = s.m_shadercombine.Trim();
+
+ CAtlList<CString> sl;
+ if(!str.IsEmpty()) Explode(str, sl, '|');
+
+ POSITION pos = sl.GetHeadPosition();
+ while(pos) m_list.AddString(sl.GetNext(pos));
+
+ pos = s.m_shaders.GetHeadPosition();
+ while(pos) m_combo.AddString(s.m_shaders.GetNext(pos).label);
+ if(m_combo.GetCount()) m_combo.SetCurSel(0);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CShaderCombineDlg::OnOK()
+{
+ m_labels.RemoveAll();
+
+ CAtlList<CString> sl;
+
+ for(int i = 0, j = m_list.GetCount(); i < j; i++)
+ {
+ CString label;
+ m_list.GetText(i, label);
+ sl.AddTail(label);
+ m_labels.AddTail(label);
+ }
+
+ AfxGetAppSettings().m_shadercombine = Implode(sl, '|');
+
+ __super::OnOK();
+}
+
+void CShaderCombineDlg::OnBnClickedButton12()
+{
+ int i = m_combo.GetCurSel();
+ if(i < 0) return;
+
+ CString label;
+ m_combo.GetLBText(i, label);
+ m_list.SetCurSel(m_list.AddString(label));
+}
+
+void CShaderCombineDlg::OnBnClickedButton13()
+{
+ int i = m_list.GetCurSel();
+ if(i < 0) return;
+
+ m_list.DeleteString(i);
+ if(i == m_list.GetCount()) i--;
+ if(i >= 0) m_list.SetCurSel(i);
+}
+
+void CShaderCombineDlg::OnBnClickedButton1()
+{
+ int i = m_list.GetCurSel();
+ if(i < 1) return;
+
+ CString label;
+ m_list.GetText(i, label);
+ m_list.DeleteString(i);
+ i--;
+ m_list.InsertString(i, label);
+ m_list.SetCurSel(i);
+}
+
+void CShaderCombineDlg::OnBnClickedButton11()
+{
+ int i = m_list.GetCurSel();
+ if(i < 0 || i >= m_list.GetCount()-1) return;
+
+ CString label;
+ m_list.GetText(i, label);
+ m_list.DeleteString(i);
+ if(++i == m_list.GetCount()) m_list.AddString(label);
+ else m_list.InsertString(i, label);
+ m_list.SetCurSel(i);
+}
diff --git a/src/apps/mplayerc/ShaderCombineDlg.h b/src/apps/mplayerc/ShaderCombineDlg.h
new file mode 100644
index 000000000..a2ce42620
--- /dev/null
+++ b/src/apps/mplayerc/ShaderCombineDlg.h
@@ -0,0 +1,38 @@
+#pragma once
+#include "afxwin.h"
+
+
+// CShaderCombineDlg dialog
+
+class CShaderCombineDlg : public CResizableDialog
+{
+ CAtlList<CString>& m_labels;
+
+public:
+ CShaderCombineDlg(CAtlList<CString>& labels, CWnd* pParent = NULL); // standard constructor
+ virtual ~CShaderCombineDlg();
+
+// Dialog Data
+ enum { IDD = IDD_SHADERCOMBINE_DLG };
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+ DECLARE_MESSAGE_MAP()
+public:
+ virtual BOOL OnInitDialog();
+protected:
+ virtual void OnOK();
+public:
+ CListBox m_list;
+public:
+ CComboBox m_combo;
+public:
+ afx_msg void OnBnClickedButton12();
+public:
+ afx_msg void OnBnClickedButton13();
+public:
+ afx_msg void OnBnClickedButton1();
+public:
+ afx_msg void OnBnClickedButton11();
+};
diff --git a/src/apps/mplayerc/ShaderEditorDlg.cpp b/src/apps/mplayerc/ShaderEditorDlg.cpp
new file mode 100644
index 000000000..4880f47e9
--- /dev/null
+++ b/src/apps/mplayerc/ShaderEditorDlg.cpp
@@ -0,0 +1,482 @@
+// ShaderEditorDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "PixelShaderCompiler.h"
+#include "ShaderEditorDlg.h"
+#include "MainFrm.h"
+
+#undef SubclassWindow
+
+// CShaderLabelComboBox
+
+BEGIN_MESSAGE_MAP(CShaderLabelComboBox, CComboBox)
+ ON_WM_CTLCOLOR()
+ ON_WM_DESTROY()
+END_MESSAGE_MAP()
+
+HBRUSH CShaderLabelComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+ if(nCtlColor == CTLCOLOR_EDIT)
+ {
+ if(m_edit.GetSafeHwnd() == NULL)
+ m_edit.SubclassWindow(pWnd->GetSafeHwnd());
+ }
+
+ return __super::OnCtlColor(pDC, pWnd, nCtlColor);
+}
+
+void CShaderLabelComboBox::OnDestroy()
+{
+ if(m_edit.GetSafeHwnd() != NULL)
+ m_edit.UnsubclassWindow();
+
+ __super::OnDestroy();
+}
+
+// CShaderEdit
+
+CShaderEdit::CShaderEdit()
+{
+ m_acdlg.Create(CShaderAutoCompleteDlg::IDD, NULL);
+
+ m_nEndChar = -1;
+ m_nIDEvent = -1;
+}
+
+CShaderEdit::~CShaderEdit()
+{
+ m_acdlg.DestroyWindow();
+}
+
+BOOL CShaderEdit::PreTranslateMessage(MSG* pMsg)
+{
+ if(m_acdlg.IsWindowVisible()
+ && pMsg->message == WM_KEYDOWN
+ && (pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN
+ || pMsg->wParam == VK_PRIOR || pMsg->wParam == VK_NEXT
+ || pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE))
+ {
+ int i = m_acdlg.m_list.GetCurSel();
+
+ if(pMsg->wParam == VK_RETURN && i >= 0)
+ {
+ CString str;
+ m_acdlg.m_list.GetText(i, str);
+ i = str.Find('(')+1;
+ if(i > 0) str = str.Left(i);
+
+ int nStartChar = 0, nEndChar = -1;
+ GetSel(nStartChar, nEndChar);
+
+ CString text;
+ GetWindowText(text);
+ while(nStartChar > 0 && _istalnum(text.GetAt(nStartChar-1)))
+ nStartChar--;
+
+ SetSel(nStartChar, nEndChar);
+ ReplaceSel(str, TRUE);
+ }
+ else if(pMsg->wParam == VK_ESCAPE)
+ {
+ m_acdlg.ShowWindow(SW_HIDE);
+ }
+ else
+ {
+ m_acdlg.m_list.SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
+ }
+
+ return TRUE;
+ }
+
+ return __super::PreTranslateMessage(pMsg);
+}
+
+BEGIN_MESSAGE_MAP(CShaderEdit, CLineNumberEdit)
+ ON_CONTROL_REFLECT(EN_UPDATE, OnUpdate)
+ ON_WM_KILLFOCUS()
+ ON_WM_TIMER()
+END_MESSAGE_MAP()
+
+void CShaderEdit::OnUpdate()
+{
+ if(m_nIDEvent == -1)
+ {
+ m_nIDEvent = SetTimer(1, 100, NULL);
+ }
+
+ CString text;
+ int nStartChar = 0, nEndChar = -1;
+ GetSel(nStartChar, nEndChar);
+
+ if(nStartChar == nEndChar)
+ {
+ GetWindowText(text);
+ while(nStartChar > 0 && _istalnum(text.GetAt(nStartChar-1)))
+ nStartChar--;
+ }
+
+ if(nStartChar < nEndChar)
+ {
+ text = text.Mid(nStartChar, nEndChar - nStartChar);
+ text.TrimRight('(');
+ text.MakeLower();
+
+ m_acdlg.m_list.ResetContent();
+
+ CString key, value;
+ POSITION pos = m_acdlg.m_inst.GetStartPosition();
+ while(pos)
+ {
+ POSITION cur = pos;
+ m_acdlg.m_inst.GetNextAssoc(pos, key, value);
+
+ if(key.Find(text) == 0)
+ {
+ CAtlList<CString> sl;
+ Explode(value, sl, '|', 2);
+ if(sl.GetCount() != 2) continue;
+ CString name = sl.RemoveHead();
+ CString description = sl.RemoveHead();
+ int i = m_acdlg.m_list.AddString(name);
+ m_acdlg.m_list.SetItemDataPtr(i, cur);
+ }
+ }
+
+ if(m_acdlg.m_list.GetCount() > 0)
+ {
+ int lineheight = GetLineHeight();
+
+ CPoint p = PosFromChar(nStartChar);
+ p.y += lineheight;
+ ClientToScreen(&p);
+ CRect r(p, CSize(100, 100));
+
+ m_acdlg.MoveWindow(r);
+ m_acdlg.SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
+ m_acdlg.ShowWindow(SW_SHOWNOACTIVATE);
+
+ m_nEndChar = nEndChar;
+
+ return;
+ }
+ }
+
+ m_acdlg.ShowWindow(SW_HIDE);
+}
+
+void CShaderEdit::OnKillFocus(CWnd* pNewWnd)
+{
+ CString text;
+ GetWindowText(text);
+ __super::OnKillFocus(pNewWnd);
+ GetWindowText(text);
+
+ m_acdlg.ShowWindow(SW_HIDE);
+}
+
+void CShaderEdit::OnTimer(UINT nIDEvent)
+{
+ if(m_nIDEvent == nIDEvent)
+ {
+ int nStartChar = 0, nEndChar = -1;
+ GetSel(nStartChar, nEndChar);
+ if(nStartChar != nEndChar || m_nEndChar != nEndChar)
+ m_acdlg.ShowWindow(SW_HIDE);
+ }
+
+ __super::OnTimer(nIDEvent);
+}
+
+// CShaderEditorDlg dialog
+
+CShaderEditorDlg::CShaderEditorDlg()
+ : CResizableDialog(CShaderEditorDlg::IDD, NULL)
+ , m_fSplitterGrabbed(false)
+ , m_pPSC(NULL)
+ , m_pShader(NULL)
+{
+}
+
+CShaderEditorDlg::~CShaderEditorDlg()
+{
+ delete m_pPSC;
+}
+
+BOOL CShaderEditorDlg::Create(CWnd* pParent)
+{
+ if(!__super::Create(IDD, pParent))
+ return FALSE;
+
+ AddAnchor(IDC_COMBO1, TOP_LEFT, TOP_RIGHT);
+ AddAnchor(IDC_COMBO2, TOP_RIGHT);
+ AddAnchor(IDC_EDIT1, TOP_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_EDIT2, BOTTOM_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_BUTTON1, TOP_RIGHT);
+
+ m_srcdata.SetTabStops(16);
+
+ SetMinTrackSize(CSize(250, 40));
+
+ m_targets.AddString(_T("ps_1_1"));
+ m_targets.AddString(_T("ps_1_2"));
+ m_targets.AddString(_T("ps_1_3"));
+ m_targets.AddString(_T("ps_1_4"));
+ m_targets.AddString(_T("ps_2_0"));
+ m_targets.AddString(_T("ps_2_a"));
+ m_targets.AddString(_T("ps_2_sw"));
+ m_targets.AddString(_T("ps_3_0"));
+ m_targets.AddString(_T("ps_3_sw"));
+
+ POSITION pos = AfxGetAppSettings().m_shaders.GetHeadPosition();
+ while(pos)
+ {
+ const AppSettings::Shader& s = AfxGetAppSettings().m_shaders.GetNext(pos);
+ m_labels.SetItemDataPtr(m_labels.AddString(s.label), (void*)&s);
+ }
+
+ m_nIDEventShader = SetTimer(1, 1000, NULL);
+
+ return TRUE;
+}
+
+void CShaderEditorDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_COMBO1, m_labels);
+ DDX_Control(pDX, IDC_COMBO2, m_targets);
+ DDX_Control(pDX, IDC_EDIT1, m_srcdata);
+ DDX_Control(pDX, IDC_EDIT2, m_output);
+}
+
+bool CShaderEditorDlg::HitTestSplitter(CPoint p)
+{
+ CRect r, rs, ro;
+ m_srcdata.GetWindowRect(&rs);
+ m_output.GetWindowRect(&ro);
+ ScreenToClient(&rs);
+ ScreenToClient(&ro);
+ GetClientRect(&r);
+ r.left = ro.left;
+ r.right = ro.right;
+ r.top = rs.bottom;
+ r.bottom = ro.top;
+ return !!r.PtInRect(p);
+}
+
+BEGIN_MESSAGE_MAP(CShaderEditorDlg, CResizableDialog)
+ ON_CBN_SELCHANGE(IDC_COMBO1, OnCbnSelchangeCombo1)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton2)
+ ON_WM_TIMER()
+ ON_WM_LBUTTONDOWN()
+ ON_WM_LBUTTONUP()
+ ON_WM_MOUSEMOVE()
+ ON_WM_SETCURSOR()
+END_MESSAGE_MAP()
+
+// CShaderEditorDlg message handlers
+
+BOOL CShaderEditorDlg::PreTranslateMessage(MSG* pMsg)
+{
+ if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN
+ && pMsg->hwnd == m_labels.m_edit.GetSafeHwnd())
+ {
+ OnCbnSelchangeCombo1();
+
+ return TRUE;
+ }
+ else if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB
+ && pMsg->hwnd == m_srcdata.GetSafeHwnd())
+ {
+ int nStartChar, nEndChar;
+ m_srcdata.GetSel(nStartChar, nEndChar);
+ if(nStartChar == nEndChar) m_srcdata.ReplaceSel(_T("\t"));
+ return TRUE;
+ }
+ else if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
+ {
+ return TRUE;
+ }
+
+ return __super::PreTranslateMessage(pMsg);
+}
+
+void CShaderEditorDlg::OnCbnSelchangeCombo1()
+{
+ int i = m_labels.GetCurSel();
+
+ if(i < 0)
+ {
+ CString label;
+ m_labels.GetWindowText(label);
+ label.Trim();
+
+ if(label.IsEmpty()) return;
+
+ CStringA srcdata;
+ LoadResource(IDF_SHADER_EMPTY, srcdata, _T("FILE"));
+
+ AppSettings::Shader s;
+ s.label = label;
+ s.target = _T("ps_2_0");
+ s.srcdata = CString(srcdata);
+
+ POSITION pos = AfxGetAppSettings().m_shaders.AddTail(s);
+
+ i = m_labels.AddString(s.label);
+ m_labels.SetCurSel(i);
+ m_labels.SetItemDataPtr(i, (void*)&AfxGetAppSettings().m_shaders.GetAt(pos));
+ }
+
+ m_pShader = (AppSettings::Shader*)m_labels.GetItemDataPtr(i);
+
+ m_targets.SetWindowText(m_pShader->target);
+
+ CString srcdata = m_pShader->srcdata;
+ srcdata.Replace(_T("\n"), _T("\r\n"));
+ m_srcdata.SetWindowText(srcdata);
+
+ ((CMainFrame*)AfxGetMainWnd())->UpdateShaders(m_pShader->label);
+}
+
+void CShaderEditorDlg::OnBnClickedButton2()
+{
+ if(!m_pShader) return;
+
+ if(IDYES != AfxMessageBox(_T("Are you sure you want to delete this shader?"), MB_YESNO))
+ return;
+
+ AppSettings& s = AfxGetAppSettings();
+
+ for(POSITION pos = s.m_shaders.GetHeadPosition(); pos; s.m_shaders.GetNext(pos))
+ {
+ if(m_pShader == &s.m_shaders.GetAt(pos))
+ {
+ m_pShader = NULL;
+ s.m_shaders.RemoveAt(pos);
+ int i = m_labels.GetCurSel();
+ if(i >= 0) m_labels.DeleteString(i);
+ m_labels.SetWindowText(_T(""));
+ m_targets.SetWindowText(_T(""));
+ m_srcdata.SetWindowText(_T(""));
+ m_output.SetWindowText(_T(""));
+ ((CMainFrame*)AfxGetMainWnd())->UpdateShaders(_T(""));
+ break;
+ }
+ }
+}
+
+void CShaderEditorDlg::OnTimer(UINT nIDEvent)
+{
+ if(nIDEvent == m_nIDEventShader && IsWindowVisible() && m_pShader)
+ {
+ CString srcdata;
+ m_srcdata.GetWindowText(srcdata);
+ srcdata.Replace(_T("\r"), _T(""));
+ srcdata.Trim();
+
+ CString target;
+ m_targets.GetWindowText(target);
+ target.Trim();
+
+ if(!srcdata.IsEmpty() && !target.IsEmpty() && (m_pShader->srcdata != srcdata || m_pShader->target != target))
+ {
+ KillTimer(m_nIDEventShader);
+
+ m_pShader->srcdata = srcdata;
+ m_pShader->target = target;
+
+ if(!m_pPSC) m_pPSC = new CPixelShaderCompiler(NULL);
+
+ CString disasm, errmsg;
+ HRESULT hr = m_pPSC->CompileShader(CStringA(srcdata), "main", CStringA(target), D3DXSHADER_DEBUG, NULL, &disasm, &errmsg);
+
+ if(SUCCEEDED(hr))
+ {
+ errmsg = _T("D3DXCompileShader succeeded\n");
+ errmsg += _T("\n");
+ errmsg += disasm;
+
+ ((CMainFrame*)AfxGetMainWnd())->UpdateShaders(m_pShader->label);
+ }
+
+ errmsg.Replace(_T("\n"), _T("\r\n"));
+
+ m_output.SetWindowText(errmsg);
+
+ // TODO: autosave
+
+ m_nIDEventShader = SetTimer(1, 1000, NULL);
+ }
+ }
+
+ __super::OnTimer(nIDEvent);
+}
+
+void CShaderEditorDlg::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ if(HitTestSplitter(point))
+ {
+ m_fSplitterGrabbed = true;
+ SetCapture();
+ }
+
+ __super::OnLButtonDown(nFlags, point);
+}
+
+void CShaderEditorDlg::OnLButtonUp(UINT nFlags, CPoint point)
+{
+ if(m_fSplitterGrabbed)
+ {
+ ReleaseCapture();
+ m_fSplitterGrabbed = false;
+ }
+
+ __super::OnLButtonUp(nFlags, point);
+}
+
+void CShaderEditorDlg::OnMouseMove(UINT nFlags, CPoint point)
+{
+ if(m_fSplitterGrabbed)
+ {
+ CRect r, rs, ro;
+ GetClientRect(&r);
+ m_srcdata.GetWindowRect(&rs);
+ m_output.GetWindowRect(&ro);
+ ScreenToClient(&rs);
+ ScreenToClient(&ro);
+
+ int dist = ro.top - rs.bottom;
+ int avgdist = dist / 2;
+
+ rs.bottom = min(max(point.y, rs.top + 40), ro.bottom - 40) - avgdist;
+ ro.top = rs.bottom + dist;
+ m_srcdata.MoveWindow(&rs);
+ m_output.MoveWindow(&ro);
+
+ int div = 100 * ((rs.bottom + ro.top) / 2) / (ro.bottom - rs.top);
+
+ RemoveAnchor(IDC_EDIT1);
+ RemoveAnchor(IDC_EDIT2);
+ AddAnchor(IDC_EDIT1, TOP_LEFT, CSize(100, div)/*BOTTOM_RIGHT*/);
+ AddAnchor(IDC_EDIT2, CSize(0, div)/*BOTTOM_LEFT*/, BOTTOM_RIGHT);
+ }
+
+ __super::OnMouseMove(nFlags, point);
+}
+
+BOOL CShaderEditorDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
+{
+ CPoint p;
+ GetCursorPos(&p);
+ ScreenToClient(&p);
+ if(HitTestSplitter(p))
+ {
+ ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
+ return TRUE;
+ }
+
+ return __super::OnSetCursor(pWnd, nHitTest, message);
+}
+
diff --git a/src/apps/mplayerc/ShaderEditorDlg.h b/src/apps/mplayerc/ShaderEditorDlg.h
new file mode 100644
index 000000000..7950819ce
--- /dev/null
+++ b/src/apps/mplayerc/ShaderEditorDlg.h
@@ -0,0 +1,81 @@
+#pragma once
+
+#include "..\..\subpic\ISubPic.h"
+#include "LineNumberEdit.h"
+#include "ShaderAutoCompleteDlg.h"
+#include "mplayerc.h"
+
+// Q174667
+
+class CShaderLabelComboBox : public CComboBox
+{
+public:
+ CEdit m_edit;
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+ afx_msg void OnDestroy();
+};
+
+class CShaderEdit : public CLineNumberEdit
+{
+ int m_nEndChar;
+ UINT m_nIDEvent;
+
+public:
+ CShaderEdit();
+ ~CShaderEdit();
+
+ CShaderAutoCompleteDlg m_acdlg;
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnUpdate();
+ afx_msg void OnKillFocus(CWnd* pNewWnd);
+ afx_msg void OnTimer(UINT nIDEvent);
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+};
+
+// CShaderEditorDlg dialog
+
+class CPixelShaderCompiler;
+
+class CShaderEditorDlg : public CResizableDialog
+{
+private:
+ UINT m_nIDEventShader;
+
+ bool m_fSplitterGrabbed;
+ bool HitTestSplitter(CPoint p);
+
+ CPixelShaderCompiler* m_pPSC;
+ AppSettings::Shader* m_pShader;
+
+public:
+ CShaderEditorDlg(); // standard constructor
+ virtual ~CShaderEditorDlg();
+
+ BOOL Create(CWnd* pParent = NULL);
+
+// Dialog Data
+ enum { IDD = IDD_SHADEREDITOR_DLG };
+ CShaderLabelComboBox m_labels;
+ CComboBox m_targets;
+ CShaderEdit m_srcdata;
+ CEdit m_output;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnCbnSelchangeCombo1();
+ afx_msg void OnBnClickedButton2();
+ afx_msg void OnTimer(UINT nIDEvent);
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+ afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
+ afx_msg void OnKillFocus(CWnd* pNewWnd);
+};
diff --git a/src/apps/mplayerc/ShockwaveGraph.cpp b/src/apps/mplayerc/ShockwaveGraph.cpp
new file mode 100644
index 000000000..5530b04ac
--- /dev/null
+++ b/src/apps/mplayerc/ShockwaveGraph.cpp
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include "shockwavegraph.h"
+#include "resource.h"
+#include "..\..\DSUtil\DSUtil.h"
+
+CShockwaveGraph::CShockwaveGraph(HWND hParent, HRESULT& hr)
+ : m_fs(State_Stopped)
+{
+ hr = S_OK;
+
+ if(!m_wndWindowFrame.Create(NULL, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
+ CRect(0, 0, 0, 0), CWnd::FromHandle(hParent), 0, NULL))
+ {
+ hr = E_FAIL;
+ return;
+ }
+
+ if(!m_wndDestFrame.Create(NULL, WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
+ CRect(0, 0, 0, 0), &m_wndWindowFrame, 0))
+ {
+ hr = E_FAIL;
+ return;
+ }
+}
+
+CShockwaveGraph::~CShockwaveGraph()
+{
+ m_wndDestFrame.DestroyWindow();
+ m_wndWindowFrame.DestroyWindow();
+}
+
+// IGraphBuilder
+STDMETHODIMP CShockwaveGraph::RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList)
+{
+ try {m_wndDestFrame.LoadMovie(0, CString(lpcwstrFile));}
+ catch(CException* e) {e->Delete(); return E_FAIL;}
+ return S_OK;
+}
+
+// IMediaControl
+STDMETHODIMP CShockwaveGraph::Run()
+{
+ try {if(m_fs != State_Running) m_wndDestFrame.Play();}
+ catch(CException* e) {e->Delete(); return E_FAIL;}
+ m_fs = State_Running;
+ m_wndWindowFrame.EnableWindow();
+// m_wndDestFrame.EnableWindow();
+ return S_OK;
+}
+STDMETHODIMP CShockwaveGraph::Pause()
+{
+ try {if(m_fs == State_Running) m_wndDestFrame.Stop();}
+ catch(CException* e) {e->Delete(); return E_FAIL;}
+ m_fs = State_Paused;
+ return S_OK;
+}
+STDMETHODIMP CShockwaveGraph::Stop()
+{
+ try {m_wndDestFrame.Stop();}
+ catch(CException* e) {e->Delete(); return E_FAIL;}
+ m_fs = State_Stopped;
+ return S_OK;
+}
+STDMETHODIMP CShockwaveGraph::GetState(LONG msTimeout, OAFilterState* pfs)
+{
+ OAFilterState fs = m_fs;
+
+ try
+ {
+ if(m_wndDestFrame.IsPlaying() && m_fs == State_Stopped) m_fs = State_Running;
+ else if(!m_wndDestFrame.IsPlaying() && m_fs == State_Running) m_fs = State_Stopped;
+ fs = m_fs;
+ }
+ catch(CException* e)
+ {
+ e->Delete();
+ return E_FAIL;
+ }
+
+ return pfs ? *pfs = fs, S_OK : E_POINTER;
+}
+
+// IMediaSeeking
+STDMETHODIMP CShockwaveGraph::IsFormatSupported(const GUID* pFormat)
+{
+ return !pFormat ? E_POINTER : *pFormat == TIME_FORMAT_FRAME ? S_OK : S_FALSE;
+}
+STDMETHODIMP CShockwaveGraph::GetTimeFormat(GUID* pFormat)
+{
+ return pFormat ? *pFormat = TIME_FORMAT_FRAME, S_OK : E_POINTER;
+}
+STDMETHODIMP CShockwaveGraph::GetDuration(LONGLONG* pDuration)
+{
+ CheckPointer(pDuration, E_POINTER);
+ *pDuration = 0;
+ try {if(m_wndDestFrame.get_ReadyState() >= READYSTATE_COMPLETE) *pDuration = m_wndDestFrame.get_TotalFrames();}
+ catch(CException* e) {e->Delete(); return E_FAIL;}
+ return S_OK;
+}
+STDMETHODIMP CShockwaveGraph::GetCurrentPosition(LONGLONG* pCurrent)
+{
+ CheckPointer(pCurrent, E_POINTER);
+ *pCurrent = 0;
+ try {if(m_wndDestFrame.get_ReadyState() >= READYSTATE_COMPLETE) *pCurrent = m_wndDestFrame.get_FrameNum();}
+ catch(CException* e) {e->Delete(); return E_FAIL;}
+ return S_OK;
+}
+STDMETHODIMP CShockwaveGraph::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)
+{
+ if(dwCurrentFlags&AM_SEEKING_AbsolutePositioning)
+ {
+ m_wndDestFrame.put_FrameNum(*pCurrent);
+
+ if(m_fs == State_Running && !m_wndDestFrame.IsPlaying())
+ m_wndDestFrame.Play();
+ else if((m_fs == State_Paused || m_fs == State_Stopped) && m_wndDestFrame.IsPlaying())
+ m_wndDestFrame.Stop();
+
+ m_wndDestFrame.put_Quality(1); // 0=Low, 1=High, 2=AutoLow, 3=AutoHigh
+
+ return S_OK;
+ }
+
+ return E_INVALIDARG;
+}
+
+// IVideoWindow
+STDMETHODIMP CShockwaveGraph::put_Visible(long Visible)
+{
+ if(IsWindow(m_wndDestFrame.m_hWnd))
+ m_wndDestFrame.ShowWindow(Visible == OATRUE ? SW_SHOWNORMAL : SW_HIDE);
+ return S_OK;
+}
+STDMETHODIMP CShockwaveGraph::get_Visible(long* pVisible)
+{
+ return pVisible ? *pVisible = (m_wndDestFrame.IsWindowVisible() ? OATRUE : OAFALSE), S_OK : E_POINTER;
+}
+STDMETHODIMP CShockwaveGraph::SetWindowPosition(long Left, long Top, long Width, long Height)
+{
+ if(IsWindow(m_wndWindowFrame.m_hWnd))
+ m_wndWindowFrame.MoveWindow(Left, Top, Width, Height);
+
+ return S_OK;
+}
+
+// IBasicVideo
+STDMETHODIMP CShockwaveGraph::SetDestinationPosition(long Left, long Top, long Width, long Height)// {return E_NOTIMPL;}
+{
+ if(IsWindow(m_wndDestFrame.m_hWnd))
+ m_wndDestFrame.MoveWindow(Left, Top, Width, Height);
+
+ return S_OK;
+}
+STDMETHODIMP CShockwaveGraph::GetVideoSize(long* pWidth, long* pHeight)
+{
+ if(!pWidth || !pHeight) return E_POINTER;
+
+ CRect r;
+ m_wndWindowFrame.GetWindowRect(r);
+ if(!r.IsRectEmpty())
+ {
+ *pWidth = r.Width();
+ *pHeight = r.Height();
+ }
+ else
+ {
+ // no call exists to determine these...
+ *pWidth = 384;//m_wndDestFrame.get_;
+ *pHeight = 288;
+
+ NotifyEvent(EC_BG_AUDIO_CHANGED, 2, 0);
+ }
+
+ return S_OK;
+}
+
+#include <math.h>
+
+// IBasicAudio
+STDMETHODIMP CShockwaveGraph::put_Volume(long lVolume)
+{
+ lVolume = (lVolume == -10000) ? 0 : (int)pow(10.0, ((double)lVolume)/5000+2);
+ lVolume = lVolume*0x10000/100;
+ lVolume = max(min(lVolume, 0xffff), 0);
+ waveOutSetVolume(0, (lVolume<<16)|lVolume);
+
+ return S_OK;
+}
+STDMETHODIMP CShockwaveGraph::get_Volume(long* plVolume)
+{
+ CheckPointer(plVolume, E_POINTER);
+
+ waveOutGetVolume(0, (DWORD*)plVolume);
+ *plVolume = (*plVolume&0xffff + ((*plVolume>>16)&0xffff)) / 2;
+ *plVolume = *plVolume*100/0x10000;
+ *plVolume = (int)((log10(1.0*(*plVolume))-2)*5000);
+ *plVolume = max(min(*plVolume, 0), -10000);
+
+ return S_OK;
+}
+
+// IAMOpenProgress
+STDMETHODIMP CShockwaveGraph::QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent)
+{
+ *pllTotal = 100;
+ *pllCurrent = m_wndDestFrame.PercentLoaded();
+ return S_OK;
+}
+
+// IGraphEngine
+STDMETHODIMP_(engine_t) CShockwaveGraph::GetEngine() {return ShockWave;}
diff --git a/src/apps/mplayerc/ShockwaveGraph.h b/src/apps/mplayerc/ShockwaveGraph.h
new file mode 100644
index 000000000..66acf56ca
--- /dev/null
+++ b/src/apps/mplayerc/ShockwaveGraph.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "BaseGraph.h"
+#include "CShockwaveFlash.h"
+
+namespace DSObjects
+{
+
+class CShockwaveGraph : public CBaseGraph
+{
+ CPlayerWindow m_wndWindowFrame;
+ CShockwaveFlash m_wndDestFrame;
+
+ FILTER_STATE m_fs;
+
+public:
+ CShockwaveGraph(HWND hParent, HRESULT& hr);
+ virtual ~CShockwaveGraph();
+
+protected:
+ // IGraphBuilder
+ STDMETHODIMP RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList);
+
+ // IMediaControl
+ STDMETHODIMP Run();
+ STDMETHODIMP Pause();
+ STDMETHODIMP Stop();
+ STDMETHODIMP GetState(LONG msTimeout, OAFilterState* pfs);
+
+ // IMediaSeeking
+ STDMETHODIMP IsFormatSupported(const GUID* pFormat);
+ STDMETHODIMP GetTimeFormat(GUID* pFormat);
+ STDMETHODIMP GetDuration(LONGLONG* pDuration);
+ STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
+ STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
+
+ // IVideoWindow
+ STDMETHODIMP put_Visible(long Visible);
+ STDMETHODIMP get_Visible(long* pVisible);
+ STDMETHODIMP SetWindowPosition(long Left, long Top, long Width, long Height);
+
+ // IBasicVideo
+ STDMETHODIMP SetDestinationPosition(long Left, long Top, long Width, long Height);
+ STDMETHODIMP GetVideoSize(long* pWidth, long* pHeight);
+
+ // IBasicAudio
+ STDMETHODIMP put_Volume(long lVolume);
+ STDMETHODIMP get_Volume(long* plVolume);
+
+ // IAMOpenProgress
+ STDMETHODIMP QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent);
+
+ // IGraphEngine
+ STDMETHODIMP_(engine_t) GetEngine();
+};
+
+}
+using namespace DSObjects; \ No newline at end of file
diff --git a/src/apps/mplayerc/StaticLink.cpp b/src/apps/mplayerc/StaticLink.cpp
new file mode 100644
index 000000000..eefc883ce
--- /dev/null
+++ b/src/apps/mplayerc/StaticLink.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// StaticLink.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "StaticLink.h"
+
+
+// CStaticLink
+
+COLORREF CStaticLink::g_colorUnvisited = RGB(0,0,255); // blue
+COLORREF CStaticLink::g_colorVisited = RGB(128,0,128); // purple
+
+HCURSOR CStaticLink::g_hCursorLink = NULL;
+
+IMPLEMENT_DYNAMIC(CStaticLink, CStatic)
+
+BEGIN_MESSAGE_MAP(CStaticLink, CStatic)
+ ON_WM_NCHITTEST()
+ ON_WM_CTLCOLOR_REFLECT()
+ ON_WM_LBUTTONDOWN()
+ ON_WM_SETCURSOR()
+END_MESSAGE_MAP()
+
+///////////////////
+// Constructor sets default colors = blue/purple.
+// bDeleteOnDestroy is used internally by PixieLib in CPixieDlg.
+//
+CStaticLink::CStaticLink(LPCTSTR lpText, BOOL bDeleteOnDestroy)
+{
+ m_link = lpText; // link text (NULL ==> window text)
+ m_color = g_colorUnvisited; // not visited yet
+ m_bDeleteOnDestroy = bDeleteOnDestroy; // delete object with window?
+}
+
+//////////////////
+// Normally, a static control does not get mouse events unless it has
+// SS_NOTIFY. This achieves the same effect as SS_NOTIFY, but it's fewer
+// lines of code and more reliable than turning on SS_NOTIFY in OnCtlColor
+// because Windows doesn't send WM_CTLCOLOR to bitmap static controls.
+//
+UINT CStaticLink::OnNcHitTest(CPoint point)
+{
+ return HTCLIENT;
+}
+
+//////////////////
+// Handle reflected WM_CTLCOLOR to set custom control color.
+// For a text control, use visited/unvisited colors and underline font.
+// For non-text controls, do nothing. Also ensures SS_NOTIFY is on.
+//
+HBRUSH CStaticLink::CtlColor(CDC* pDC, UINT nCtlColor)
+{
+ ASSERT(nCtlColor == CTLCOLOR_STATIC);
+ DWORD dwStyle = GetStyle();
+
+ HBRUSH hbr = NULL;
+ if ((dwStyle & 0xFF) <= SS_RIGHT) {
+
+ // this is a text control: set up font and colors
+ if (!(HFONT)m_font) {
+ // first time init: create font
+ LOGFONT lf;
+ GetFont()->GetObject(sizeof(lf), &lf);
+ lf.lfUnderline = TRUE;
+ m_font.CreateFontIndirect(&lf);
+ }
+
+ // use underline font and visited/unvisited colors
+ pDC->SelectObject(&m_font);
+ pDC->SetTextColor(m_color);
+ pDC->SetBkMode(TRANSPARENT);
+
+ // return hollow brush to preserve parent background color
+ hbr = (HBRUSH)::GetStockObject(HOLLOW_BRUSH);
+ }
+ return hbr;
+}
+
+/////////////////
+// Handle mouse click: navigate link
+//
+void CStaticLink::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ if (m_link.IsEmpty()) {
+ // no link: try to load from resource string or window text
+ m_link.LoadString(GetDlgCtrlID()) || (GetWindowText(m_link),1);
+ if (m_link.IsEmpty())
+ return;
+ }
+
+ // Call ShellExecute to run the file.
+ // For an URL, this means opening it in the browser.
+ //
+ HINSTANCE h = m_link.Navigate();
+ if ((UINT)h > 32) { // success!
+ m_color = g_colorVisited; // change color
+ Invalidate(); // repaint
+ } else {
+ MessageBeep(0); // unable to execute file!
+ TRACE(_T("*** WARNING: CStaticLink: unable to navigate link %s\n"),
+ (LPCTSTR)m_link);
+ }
+}
+
+//////////////////
+// Set "hand" cursor to cue user that this is a link. If app has not set
+// g_hCursorLink, then try to get the cursor from winhlp32.exe,
+// resource 106, which is a pointing finger. This is a bit of a kludge,
+// but it works.
+//
+BOOL CStaticLink::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
+{
+ if (g_hCursorLink == NULL) {
+ static BOOL bTriedOnce = FALSE;
+ if (!bTriedOnce) {
+ CString windir;
+ GetWindowsDirectory(windir.GetBuffer(MAX_PATH), MAX_PATH);
+ windir.ReleaseBuffer();
+ windir += _T("\\winhlp32.exe");
+ HMODULE hModule = LoadLibrary(windir);
+ if (hModule) {
+ g_hCursorLink =
+ CopyCursor(::LoadCursor(hModule, MAKEINTRESOURCE(106)));
+ }
+ FreeLibrary(hModule);
+ bTriedOnce = TRUE;
+ }
+ }
+ if (g_hCursorLink) {
+ ::SetCursor(g_hCursorLink);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//////////////////
+// Normally, a control class is not destoyed when the window is;
+// however, CPixieDlg creates static controls with "new" instead of
+// as class members, so it's convenient to allow the option of destroying
+// object with window. In applications where you want the object to be
+// destoyed along with the window, you can call constructor with
+// bDeleteOnDestroy=TRUE.
+//
+void CStaticLink::PostNcDestroy()
+{
+ if (m_bDeleteOnDestroy)
+ delete this;
+}
+
diff --git a/src/apps/mplayerc/StaticLink.h b/src/apps/mplayerc/StaticLink.h
new file mode 100644
index 000000000..55742a1df
--- /dev/null
+++ b/src/apps/mplayerc/StaticLink.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+// CHyperlink
+
+class CHyperlink : public CString {
+public:
+ CHyperlink(LPCTSTR lpLink = NULL) : CString(lpLink) { }
+ ~CHyperlink() { }
+ const CHyperlink& operator=(LPCTSTR lpsz) {
+ CString::operator=(lpsz);
+ return *this;
+ }
+ operator LPCTSTR() {
+ return CString::operator LPCTSTR();
+ }
+ virtual HINSTANCE Navigate() {
+ return IsEmpty() ? NULL :
+ ShellExecute(0, _T("open"), *this, 0, 0, SW_SHOWNORMAL);
+ }
+};
+
+// CStaticLink
+
+class CStaticLink : public CStatic
+{
+public:
+ DECLARE_DYNAMIC(CStaticLink)
+ CStaticLink(LPCTSTR lpText = NULL, BOOL bDeleteOnDestroy=FALSE);
+ ~CStaticLink() { }
+
+ // Hyperlink contains URL/filename. If NULL, I will use the window text.
+ // (GetWindowText) to get the target.
+ CHyperlink m_link;
+ COLORREF m_color;
+
+ // Default colors you can change
+ // These are global, so they're the same for all links.
+ static COLORREF g_colorUnvisited;
+ static COLORREF g_colorVisited;
+
+ // Cursor used when mouse is on a link--you can set, or
+ // it will default to the standard hand with pointing finger.
+ // This is global, so it's the same for all links.
+ static HCURSOR g_hCursorLink;
+
+protected:
+ CFont m_font; // underline font for text control
+ BOOL m_bDeleteOnDestroy; // delete object when window destroyed?
+
+ virtual void PostNcDestroy();
+
+ // message handlers
+ DECLARE_MESSAGE_MAP()
+ afx_msg UINT OnNcHitTest(CPoint point);
+ afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
+};
+
+
diff --git a/src/apps/mplayerc/StatusLabel.cpp b/src/apps/mplayerc/StatusLabel.cpp
new file mode 100644
index 000000000..a6d19d071
--- /dev/null
+++ b/src/apps/mplayerc/StatusLabel.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// StatusLabel.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "StatusLabel.h"
+
+
+// CStatusLabel
+
+IMPLEMENT_DYNAMIC(CStatusLabel, CStatic)
+CStatusLabel::CStatusLabel(bool fRightAlign, bool fAddEllipses)
+ : m_fRightAlign(fRightAlign)
+ , m_fAddEllipses(fAddEllipses)
+{
+ HDC hdc = ::GetDC(NULL);
+ double scale = 1.0*GetDeviceCaps(hdc, LOGPIXELSY) / 96.0;
+ ::ReleaseDC(0, hdc);
+
+ m_font.m_hObject = NULL;
+
+ if(!(::GetVersion()&0x80000000))
+ m_font.CreateFont(int(14.0 * scale), 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE,
+ _T("Microsoft Sans Serif"));
+ if(!m_font.m_hObject)
+ m_font.CreateFont(int(14.0 * scale), 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE,
+ _T("MS Sans Serif"));
+}
+
+CStatusLabel::~CStatusLabel()
+{
+}
+
+BEGIN_MESSAGE_MAP(CStatusLabel, CStatic)
+ ON_WM_ERASEBKGND()
+END_MESSAGE_MAP()
+
+// CStatusLabel message handlers
+
+void CStatusLabel::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
+{
+ CDC dc;
+ dc.Attach(lpDrawItemStruct->hDC);
+ CString str;
+ GetWindowText(str);
+ CRect r;
+ GetClientRect(&r);
+ CFont* old = dc.SelectObject(&m_font);
+ dc.SetTextColor(0xffffff);
+ dc.SetBkColor(0);
+ CSize size = dc.GetTextExtent(str);
+ CPoint p = CPoint(m_fRightAlign ? r.Width() - size.cx : 0, (r.Height()-size.cy)/2);
+
+ if(m_fAddEllipses)
+ while(size.cx > r.Width()-3 && str.GetLength() > 3)
+ {
+ str = str.Left(str.GetLength()-4) + _T("...");
+ size = dc.GetTextExtent(str);
+ }
+
+ dc.TextOut(p.x, p.y, str);
+ dc.ExcludeClipRect(CRect(p, size));
+ dc.SelectObject(&old);
+ dc.FillSolidRect(&r, 0);
+ dc.Detach();
+}
+
+BOOL CStatusLabel::OnEraseBkgnd(CDC* pDC)
+{
+ CRect r;
+ GetClientRect(&r);
+ pDC->FillSolidRect(&r, 0);
+ return TRUE;
+}
+
diff --git a/src/apps/mplayerc/StatusLabel.h b/src/apps/mplayerc/StatusLabel.h
new file mode 100644
index 000000000..0f31b7ddc
--- /dev/null
+++ b/src/apps/mplayerc/StatusLabel.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+// CStatusLabel
+
+class CStatusLabel : public CStatic
+{
+ DECLARE_DYNAMIC(CStatusLabel)
+
+private:
+ bool m_fRightAlign, m_fAddEllipses;
+ CFont m_font;
+
+public:
+ CStatusLabel(bool fRightAlign, bool fAddEllipses);
+ virtual ~CStatusLabel();
+
+ CFont& GetFont() {return m_font;}
+
+ void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
+
+protected:
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+};
diff --git a/src/apps/mplayerc/StdAfx.cpp b/src/apps/mplayerc/StdAfx.cpp
new file mode 100644
index 000000000..f8ecc6014
--- /dev/null
+++ b/src/apps/mplayerc/StdAfx.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// stdafx.cpp : source file that includes just the standard includes
+// mplayerc.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
diff --git a/src/apps/mplayerc/StdAfx.h b/src/apps/mplayerc/StdAfx.h
new file mode 100644
index 000000000..c4535f2c6
--- /dev/null
+++ b/src/apps/mplayerc/StdAfx.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__C76533D6_6242_4BEB_8FD3_C6BE58F07224__INCLUDED_)
+#define AFX_STDAFX_H__C76533D6_6242_4BEB_8FD3_C6BE58F07224__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+#include <afxdisp.h> // MFC Automation classes
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+#include <afxdlgs.h>
+
+#define ResStr(id) CString(MAKEINTRESOURCE(id))
+
+#include <afxdisp.h>
+#include <afxole.h>
+
+#include <Shlwapi.h>
+
+#include <atlcoll.h>
+#include <atlpath.h>
+
+#include <streams.h>
+#include <dvdmedia.h>
+#include <mpconfig.h>
+#include "..\..\..\include\qt\qt.h"
+#include "..\..\ui\ui.h"
+#include "..\..\DSUtil\DSUtil.h"
+
+template <class T = CString, class S = CString>
+class CAtlStringMap : public CAtlMap<S, T, CStringElementTraits<S> > {};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__C76533D6_6242_4BEB_8FD3_C6BE58F07224__INCLUDED_)
diff --git a/src/apps/mplayerc/SubtitleDlDlg.cpp b/src/apps/mplayerc/SubtitleDlDlg.cpp
new file mode 100644
index 000000000..bdf4d0609
--- /dev/null
+++ b/src/apps/mplayerc/SubtitleDlDlg.cpp
@@ -0,0 +1,153 @@
+// SubtitleDlDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "SubtitleDlDlg.h"
+
+
+// CSubtitleDlDlg dialog
+
+//IMPLEMENT_DYNAMIC(CSubtitleDlDlg, CResizableDialog)
+CSubtitleDlDlg::CSubtitleDlDlg(CList<isdb_movie>& movies, CWnd* pParent /*=NULL*/)
+ : CResizableDialog(CSubtitleDlDlg::IDD, pParent)
+{
+ m_movies.AddTail(&movies);
+}
+
+CSubtitleDlDlg::~CSubtitleDlDlg()
+{
+}
+
+int CSubtitleDlDlg::GetChecked(int iItem)
+{
+ LVITEM lvi;
+ lvi.iItem = iItem;
+ lvi.iSubItem = 0;
+ lvi.mask = LVIF_IMAGE;
+ m_list.GetItem(&lvi);
+ return(lvi.iImage);
+}
+
+void CSubtitleDlDlg::SetChecked(int iItem, int iChecked)
+{
+ LVITEM lvi;
+ lvi.iItem = iItem;
+ lvi.iSubItem = 0;
+ lvi.mask = LVIF_IMAGE;
+ lvi.iImage = iChecked;
+ m_list.SetItem(&lvi);
+}
+
+void CSubtitleDlDlg::DoDataExchange(CDataExchange* pDX)
+{
+ __super::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_LIST1, m_list);
+}
+
+
+BEGIN_MESSAGE_MAP(CSubtitleDlDlg, CResizableDialog)
+ ON_NOTIFY(NM_CLICK, IDC_LIST1, OnNMClickList1)
+ ON_UPDATE_COMMAND_UI(IDOK, OnUpdateOk)
+END_MESSAGE_MAP()
+
+// CSubtitleDlDlg message handlers
+
+BOOL CSubtitleDlDlg::OnInitDialog()
+{
+ __super::OnInitDialog();
+
+
+ AddAnchor(IDC_LIST1, TOP_LEFT, BOTTOM_RIGHT);
+ AddAnchor(IDC_CHECK1, BOTTOM_LEFT);
+ AddAnchor(IDOK, BOTTOM_RIGHT);
+
+ CSize s(200, 150);
+ SetMinTrackSize(s);
+
+
+ m_list.SetExtendedStyle(m_list.GetExtendedStyle()|LVS_EX_FULLROWSELECT);
+
+ m_list.InsertColumn(COL_FILENAME, _T("File"), LVCFMT_LEFT, 160);
+ m_list.InsertColumn(COL_LANGUAGE, _T("Language"), LVCFMT_CENTER, 80);
+ m_list.InsertColumn(COL_FORMAT, _T("Format"), LVCFMT_CENTER, 50);
+ m_list.InsertColumn(COL_DISC, _T("Disc"), LVCFMT_CENTER, 50);
+ m_list.InsertColumn(COL_TITLES, _T("Title(s)"), LVCFMT_LEFT, 300);
+
+ m_onoff.Create(IDB_ONOFF, 12, 3, 0xffffff);
+ m_list.SetImageList(&m_onoff, LVSIL_SMALL);
+
+
+ int i = 0;
+
+ POSITION pos = m_movies.GetHeadPosition();
+ while(pos)
+ {
+ isdb_movie& m = m_movies.GetNext(pos);
+
+ CStringA titlesA = Implode(m.titles, '|');
+ titlesA.Replace("|", ", ");
+ CString titles = UTF8To16(titlesA);
+
+ POSITION pos2 = m.subs.GetHeadPosition();
+ while(pos2)
+ {
+ isdb_subtitle& s = m.subs.GetNext(pos2);
+ CString name = UTF8To16(s.name);
+ CString language = s.language;
+ CString format = s.format;
+ CString disc;
+ disc.Format(_T("%d/%d"), s.disc_no, s.discs);
+
+ int iItem = m_list.InsertItem(i++, _T(""));
+ m_list.SetItemData(iItem, (DWORD_PTR)&s);
+ m_list.SetItemText(iItem, COL_FILENAME, name);
+ m_list.SetItemText(iItem, COL_LANGUAGE, language);
+ m_list.SetItemText(iItem, COL_FORMAT, format);
+ m_list.SetItemText(iItem, COL_DISC, disc);
+ m_list.SetItemText(iItem, COL_TITLES, titles);
+ }
+ }
+
+ m_selsubs.RemoveAll();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CSubtitleDlDlg::OnOK()
+{
+ for(int i = 0; i < m_list.GetItemCount(); i++)
+ if(GetChecked(i))
+ m_selsubs.AddTail(*(isdb_subtitle*)m_list.GetItemData(i));
+
+ m_fReplaceSubs = IsDlgButtonChecked(IDC_CHECK1) == BST_CHECKED;
+
+ __super::OnOK();
+}
+
+void CSubtitleDlDlg::OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)pNMHDR;
+
+ if(lpnmlv->iItem >= 0)
+ {
+ CRect r;
+ m_list.GetItemRect(lpnmlv->iItem, r, LVIR_ICON);
+ if(r.PtInRect(lpnmlv->ptAction))
+ {
+ SetChecked(lpnmlv->iItem, (GetChecked(lpnmlv->iItem)&1) == 0 ? 1 : 0);
+ }
+ }
+
+ *pResult = 0;
+}
+
+void CSubtitleDlDlg::OnUpdateOk(CCmdUI* pCmdUI)
+{
+ bool fEnable = false;
+ for(int i = 0; !fEnable && i < m_list.GetItemCount(); i++)
+ fEnable = !!GetChecked(i);
+
+ pCmdUI->Enable(fEnable);
+}
diff --git a/src/apps/mplayerc/SubtitleDlDlg.h b/src/apps/mplayerc/SubtitleDlDlg.h
new file mode 100644
index 000000000..fcf3f057e
--- /dev/null
+++ b/src/apps/mplayerc/SubtitleDlDlg.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include "ISDb.h"
+#include "afxwin.h"
+
+// CSubtitleDlDlg dialog
+
+class CSubtitleDlDlg : public CResizableDialog
+{
+// DECLARE_DYNAMIC(CSubtitleDlDlg)
+
+private:
+ CList<isdb_movie> m_movies;
+
+ enum {COL_FILENAME, COL_LANGUAGE, COL_FORMAT, COL_DISC, COL_TITLES};
+
+ CImageList m_onoff;
+ int GetChecked(int iItem);
+ void SetChecked(int iItem, int iChecked);
+
+public:
+ CSubtitleDlDlg(CList<isdb_movie>& movies, CWnd* pParent = NULL); // standard constructor
+ virtual ~CSubtitleDlDlg();
+
+ bool m_fReplaceSubs;
+ CList<isdb_subtitle> m_selsubs;
+
+// Dialog Data
+ enum { IDD = IDD_SUBTITLEDL_DLG };
+ CListCtrl m_list;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnUpdateOk(CCmdUI* pCmdUI);
+};
diff --git a/src/apps/mplayerc/TextPassThruFilter.cpp b/src/apps/mplayerc/TextPassThruFilter.cpp
new file mode 100644
index 000000000..842b23c9a
--- /dev/null
+++ b/src/apps/mplayerc/TextPassThruFilter.cpp
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include <windows.h>
+#include <commdlg.h>
+#include "mplayerc.h"
+#include "mainfrm.h"
+#include "TextPassThruFilter.h"
+#include "..\..\..\include\moreuuids.h"
+#include "..\..\DSUtil\DSUtil.h"
+#include "..\..\subtitles\SubtitleInputPin.h"
+
+//
+// CTextPassThruInputPin
+//
+
+class CTextPassThruInputPin : public CSubtitleInputPin
+{
+ CTextPassThruFilter* m_pTPTFilter;
+ CComPtr<ISubStream> m_pSubStreamOld;
+
+protected:
+ void AddSubStream(ISubStream* pSubStream)
+ {
+ if(m_pSubStreamOld)
+ {
+ if(pSubStream) m_pTPTFilter->m_pMainFrame->ReplaceSubtitle(m_pSubStreamOld, pSubStream);
+ m_pSubStreamOld = NULL;
+ }
+ }
+
+ void RemoveSubStream(ISubStream* pSubStream)
+ {
+ m_pSubStreamOld = pSubStream;
+ }
+
+ void InvalidateSubtitle(REFERENCE_TIME rtStart, ISubStream* pSubStream)
+ {
+ m_pTPTFilter->m_pMainFrame->InvalidateSubtitle((DWORD_PTR)pSubStream, rtStart);
+ }
+
+public:
+ CTextPassThruInputPin(CTextPassThruFilter* pTPTFilter, CCritSec* pLock, CCritSec* pSubLock, HRESULT* phr);
+ STDMETHODIMP NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
+ STDMETHODIMP Receive(IMediaSample* pSample);
+ STDMETHODIMP EndOfStream();
+ STDMETHODIMP BeginFlush();
+ STDMETHODIMP EndFlush();
+};
+
+//
+// CTextPassThruOutputPin
+//
+
+class CTextPassThruOutputPin : public CBaseOutputPin
+{
+ CTextPassThruFilter* m_pTPTFilter;
+
+public:
+ CTextPassThruOutputPin(CTextPassThruFilter* pTPTFilter, CCritSec* pLock, HRESULT* phr);
+
+ HRESULT CheckMediaType(const CMediaType* mtOut);
+ HRESULT DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties);
+ HRESULT GetMediaType(int iPosition, CMediaType* pmt);
+ STDMETHODIMP Notify(IBaseFilter* pSender, Quality q) {return S_OK;}
+};
+
+///////////
+
+CTextPassThruInputPin::CTextPassThruInputPin(CTextPassThruFilter* pTPTFilter, CCritSec* pLock, CCritSec* pSubLock, HRESULT* phr)
+ : CSubtitleInputPin(pTPTFilter, pLock, pSubLock, phr)
+ , m_pTPTFilter(pTPTFilter)
+{
+}
+
+STDMETHODIMP CTextPassThruInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
+{
+ HRESULT hr = __super::NewSegment(tStart, tStop, dRate);
+ if(FAILED(hr)) return hr;
+ return m_pTPTFilter->m_pOutput->DeliverNewSegment(tStart, tStop, dRate);
+}
+
+STDMETHODIMP CTextPassThruInputPin::Receive(IMediaSample* pSample)
+{
+ HRESULT hr = __super::Receive(pSample);
+ if(FAILED(hr)) return hr;
+ return m_pTPTFilter->m_pOutput->Deliver(pSample);
+}
+
+STDMETHODIMP CTextPassThruInputPin::EndOfStream()
+{
+ HRESULT hr = __super::EndOfStream();
+ if(FAILED(hr)) return hr;
+ return m_pTPTFilter->m_pOutput->DeliverEndOfStream();
+}
+
+STDMETHODIMP CTextPassThruInputPin::BeginFlush()
+{
+ HRESULT hr = __super::BeginFlush();
+ if(FAILED(hr)) return hr;
+ return m_pTPTFilter->m_pOutput->DeliverBeginFlush();
+}
+
+STDMETHODIMP CTextPassThruInputPin::EndFlush()
+{
+ HRESULT hr = __super::EndFlush();
+ if(FAILED(hr)) return hr;
+ return m_pTPTFilter->m_pOutput->DeliverEndFlush();
+}
+
+//
+
+CTextPassThruOutputPin::CTextPassThruOutputPin(CTextPassThruFilter* pTPTFilter, CCritSec* pLock, HRESULT* phr)
+ : CBaseOutputPin(NAME(""), pTPTFilter, pLock, phr, L"Out")
+ , m_pTPTFilter(pTPTFilter)
+{
+}
+
+HRESULT CTextPassThruOutputPin::CheckMediaType(const CMediaType* mtOut)
+{
+ CMediaType mt;
+ return S_OK == m_pTPTFilter->m_pInput->ConnectionMediaType(&mt) && mt == *mtOut
+ ? S_OK
+ : E_FAIL;
+}
+
+HRESULT CTextPassThruOutputPin::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
+{
+ if(m_pTPTFilter->m_pInput->IsConnected() == FALSE)
+ return E_UNEXPECTED;
+
+ CComPtr<IMemAllocator> pAllocatorIn;
+ m_pTPTFilter->m_pInput->GetAllocator(&pAllocatorIn);
+ if(!pAllocatorIn) return E_UNEXPECTED;
+
+ pAllocatorIn->GetProperties(pProperties);
+
+ HRESULT hr;
+ ALLOCATOR_PROPERTIES Actual;
+ if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual)))
+ return hr;
+
+ return(pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
+ ? E_FAIL
+ : NOERROR);
+}
+
+HRESULT CTextPassThruOutputPin::GetMediaType(int iPosition, CMediaType* pmt)
+{
+ if(m_pTPTFilter->m_pInput->IsConnected() == FALSE)
+ return E_UNEXPECTED;
+
+ if(iPosition < 0) return E_INVALIDARG;
+ if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
+
+ m_pTPTFilter->m_pInput->ConnectionMediaType(pmt);
+
+ return S_OK;
+}
+
+//
+// CTextPassThruFilter
+//
+
+CTextPassThruFilter::CTextPassThruFilter(CMainFrame* pMainFrame)
+ : CBaseFilter(NAME("CTextPassThruFilter"), NULL, this, __uuidof(this))
+ , m_pMainFrame(pMainFrame)
+{
+ HRESULT hr;
+ m_pInput = new CTextPassThruInputPin(this, this, &m_pMainFrame->m_csSubLock, &hr);
+ m_pOutput = new CTextPassThruOutputPin(this, this, &hr);
+}
+
+CTextPassThruFilter::~CTextPassThruFilter()
+{
+ delete m_pInput; m_pInput = NULL;
+ delete m_pOutput; m_pOutput = NULL;
+}
+
+STDMETHODIMP CTextPassThruFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ if(m_pInput && riid == __uuidof(ISubStream))
+ {
+ if(CComPtr<ISubStream> pSubStream = m_pInput->GetSubStream())
+ {
+ *ppv = pSubStream.Detach();
+ return S_OK;
+ }
+ }
+
+ return __super::NonDelegatingQueryInterface(riid, ppv);
+}
+
+int CTextPassThruFilter::GetPinCount()
+{
+ return 2;
+}
+
+CBasePin* CTextPassThruFilter::GetPin(int n)
+{
+ if(n == 0) return m_pInput;
+ else if(n == 1) return m_pOutput;
+ return NULL;
+}
+
+/*
+void CTextPassThruFilter::SetName()
+{
+ CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pRTS;
+
+ CAutoLock cAutoLock(&m_pMainFrame->m_csSubLock);
+
+ if(CComQIPtr<IPropertyBag> pPB = m_pTPTInput->GetConnected())
+ {
+ CComVariant var;
+ if(SUCCEEDED(pPB->Read(L"LANGUAGE", &var, NULL)))
+ {
+ pRTS->m_name = CString(var.bstrVal) + _T(" (embeded)");
+ }
+ }
+
+ if(pRTS->m_name.IsEmpty())
+ {
+ CPinInfo pi;
+ m_pTPTInput->GetConnected()->QueryPinInfo(&pi);
+ pRTS->m_name = CString(CStringW(pi.achName)) + _T(" (embeded)");
+
+ }
+}
+*/
diff --git a/src/apps/mplayerc/TextPassThruFilter.h b/src/apps/mplayerc/TextPassThruFilter.h
new file mode 100644
index 000000000..5cbfdcdad
--- /dev/null
+++ b/src/apps/mplayerc/TextPassThruFilter.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+class CTextPassThruInputPin;
+
+[uuid("E2BA9B7B-B65D-4804-ACB2-89C3E55511DB")]
+class CTextPassThruFilter : public CBaseFilter, public CCritSec
+{
+ friend class CTextPassThruInputPin;
+ friend class CTextPassThruOutputPin;
+
+ CTextPassThruInputPin* m_pInput;
+ CTextPassThruOutputPin* m_pOutput;
+
+ CMainFrame* m_pMainFrame;
+
+public:
+ CTextPassThruFilter(CMainFrame* pMainFrame);
+ virtual ~CTextPassThruFilter();
+
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
+
+ int GetPinCount();
+ CBasePin* GetPin(int n);
+};
diff --git a/src/apps/mplayerc/VMROSD.cpp b/src/apps/mplayerc/VMROSD.cpp
new file mode 100644
index 000000000..6c62554ab
--- /dev/null
+++ b/src/apps/mplayerc/VMROSD.cpp
@@ -0,0 +1,302 @@
+#include "stdafx.h"
+#include ".\vmrosd.h"
+
+
+#define SEEKBAR_HEIGHT 60
+#define SLIDER_BAR_HEIGHT 10
+#define SLIDER_CURSOR_HEIGHT 30
+#define SLIDER_CURSOR_WIDTH 15
+
+
+CVMROSD::CVMROSD(void)
+{
+ m_Color[OSD_TRANSPARENT] = RGB( 0, 0, 0);
+ m_Color[OSD_BACKGROUND] = RGB( 0, 96, 183);
+ m_Color[OSD_BORDER] = RGB(255, 255, 255);
+ m_Color[OSD_TEXT] = RGB(255, 255, 255);
+ m_Color[OSD_BAR] = RGB( 4, 200, 12);
+ m_Color[OSD_CURSOR] = RGB( 23, 50, 247);
+
+ m_penBorder.CreatePen(PS_SOLID, 1, m_Color[OSD_BORDER]);
+ m_penCursor.CreatePen(PS_SOLID, 4, m_Color[OSD_CURSOR]);
+ m_brushBack.CreateSolidBrush(m_Color[OSD_BACKGROUND]);
+ m_brushBar.CreateSolidBrush (m_Color[OSD_BAR]);
+ m_MainFont.CreatePointFont (200, _T("Arial"));
+
+ m_nMessagePos = OSD_NOMESSAGE;
+}
+
+CVMROSD::~CVMROSD(void)
+{
+}
+
+
+void CVMROSD::OnSize(UINT nType, int cx, int cy)
+{
+ // TODO : gérer le changement de taille de fenêtre
+}
+
+void CVMROSD::Start (CWnd* pWnd, CComQIPtr<IVMRMixerBitmap9> pVMB)
+{
+ CRect rc;
+ CWindowDC dc (pWnd);
+
+ m_pWnd = pWnd;
+ m_bCursorMoving = false;
+ m_bSeekBarVisible = false;
+
+ CalcRect();
+
+ m_MemDC.DeleteDC();
+ m_Bitmap.DeleteObject();
+
+ if (m_MemDC.CreateCompatibleDC (&dc))
+ {
+ BITMAPINFO bmi = {0};
+ HBITMAP hbmpRender;
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = m_rectWnd.Width();
+ bmi.bmiHeader.biHeight = - (int) m_rectWnd.Height(); // top-down
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ hbmpRender = CreateDIBSection( m_MemDC, &bmi, DIB_RGB_COLORS, NULL, NULL, NULL );
+ m_MemDC.SelectObject (hbmpRender);
+
+ if (::GetObject(hbmpRender, sizeof(BITMAP), &m_BitmapInfo) != 0)
+ {
+ // Configure the VMR's bitmap structure
+ ZeroMemory(&m_VMR9AlphaBitmap, sizeof(m_VMR9AlphaBitmap) );
+ m_VMR9AlphaBitmap.dwFlags = VMRBITMAP_HDC | VMRBITMAP_SRCCOLORKEY;
+ m_VMR9AlphaBitmap.hdc = m_MemDC;
+ m_VMR9AlphaBitmap.rSrc = m_rectWnd;
+ m_VMR9AlphaBitmap.rDest.left = 0;
+ m_VMR9AlphaBitmap.rDest.top = 0;
+ m_VMR9AlphaBitmap.rDest.right = 1.0;
+ m_VMR9AlphaBitmap.rDest.bottom = 1.0;
+ m_VMR9AlphaBitmap.fAlpha = 1.0;
+ m_VMR9AlphaBitmap.clrSrcKey = m_Color[OSD_TRANSPARENT];
+
+ m_MemDC.SelectObject(m_MainFont);
+ m_MemDC.SetTextColor(RGB(255, 255, 255));
+ m_MemDC.SetBkMode(TRANSPARENT);
+
+ m_pVMB = pVMB;
+ }
+ }
+}
+
+
+void CVMROSD::Stop()
+{
+ m_pVMB.Release();
+}
+
+void CVMROSD::CalcRect()
+{
+ m_pWnd->GetClientRect(&m_rectWnd);
+
+ m_rectSeekBar.left = m_rectWnd.left + 10;
+ m_rectSeekBar.right = m_rectWnd.right - 10;
+ m_rectSeekBar.top = m_rectWnd.bottom - SEEKBAR_HEIGHT;
+ m_rectSeekBar.bottom = m_rectSeekBar.top + SEEKBAR_HEIGHT;
+
+ m_rectSeekBar.left = m_rectSeekBar.left;
+ m_rectSeekBar.right = m_rectSeekBar.right;
+ m_rectSeekBar.top = m_rectSeekBar.top;
+ m_rectSeekBar.bottom = m_rectSeekBar.bottom;
+}
+
+void CVMROSD::DrawRect(CRect* rect, CBrush* pBrush, CPen* pPen)
+{
+ if (pPen)
+ m_MemDC.SelectObject (pPen);
+ else
+ m_MemDC.SelectStockObject(NULL_PEN);
+
+ if (pBrush)
+ m_MemDC.SelectObject (pBrush);
+ else
+ m_MemDC.SelectStockObject(HOLLOW_BRUSH);
+
+ m_MemDC.Rectangle (rect);
+}
+
+void CVMROSD::DrawSlider(CRect* rect, __int64 llMin, __int64 llMax, __int64 llPos)
+{
+ m_rectBar.left = rect->left + 10;
+ m_rectBar.right = rect->right - 10;
+ m_rectBar.top = rect->top + (rect->Height() - SLIDER_BAR_HEIGHT) / 2;
+ m_rectBar.bottom = m_rectBar.top + SLIDER_BAR_HEIGHT;
+
+ if (llMax == llMin)
+ m_rectCursor.left = m_rectBar.left;
+ else
+ m_rectCursor.left = m_rectBar.left + (m_rectBar.Width() - SLIDER_CURSOR_WIDTH) * llPos / (llMax-llMin);
+ m_rectCursor.right = m_rectCursor.left + SLIDER_CURSOR_WIDTH;
+ m_rectCursor.top = rect->top + (rect->Height() - SLIDER_CURSOR_HEIGHT) / 2;
+ m_rectCursor.bottom = m_rectCursor.top + SLIDER_CURSOR_HEIGHT;
+
+ DrawRect (rect, &m_brushBack, &m_penBorder);
+ DrawRect (&m_rectBar, &m_brushBar);
+ DrawRect (&m_rectCursor, NULL, &m_penCursor);
+}
+
+
+void CVMROSD::DrawMessage()
+{
+ if (m_nMessagePos != OSD_NOMESSAGE)
+ {
+ CRect rectText (0,0,0,0);
+ CRect rectMessages;
+
+ m_MemDC.DrawText (m_strMessage, &rectText, DT_CALCRECT);
+ rectText.InflateRect(20, 10);
+ switch (m_nMessagePos)
+ {
+ case OSD_TOPLEFT :
+ rectMessages = CRect (10, 10, rectText.right + 10, rectText.bottom + 10);
+ break;
+ case OSD_TOPRIGHT :
+ default :
+ rectMessages = CRect (m_rectWnd.right-10-rectText.Width(), 10, m_rectWnd.right-10, rectText.bottom + 10);
+ break;
+ }
+ DrawRect (&rectMessages, &m_brushBack, &m_penBorder);
+ m_MemDC.DrawText (m_strMessage, &rectMessages, DT_SINGLELINE |DT_CENTER|DT_VCENTER);
+ }
+}
+
+void CVMROSD::Invalidate()
+{
+ memsetd(m_BitmapInfo.bmBits, 0xff000000, m_BitmapInfo.bmWidth*m_BitmapInfo.bmHeight*(m_BitmapInfo.bmBitsPixel/8));
+
+ if (m_bSeekBarVisible) DrawSlider(&m_rectSeekBar, m_llSeekMin, m_llSeekMax, m_llSeekPos);
+ DrawMessage();
+
+ m_VMR9AlphaBitmap.dwFlags &= ~VMRBITMAP_DISABLE;
+ if (m_pVMB) m_pVMB->SetAlphaBitmap(&m_VMR9AlphaBitmap);
+}
+
+void CVMROSD::UpdateSeekBarPos(CPoint point)
+{
+ m_llSeekPos = (point.x - m_rectBar.left) * (m_llSeekMax-m_llSeekMin) / (m_rectBar.Width() - SLIDER_CURSOR_WIDTH);
+ m_llSeekPos = max (m_llSeekPos, m_llSeekMin);
+ m_llSeekPos = min (m_llSeekPos, m_llSeekMax);
+
+ AfxGetApp()->GetMainWnd()->PostMessage(WM_HSCROLL, MAKEWPARAM((short)m_llSeekPos, SB_THUMBTRACK), (LPARAM)m_pWnd->m_hWnd);
+}
+
+bool CVMROSD::OnMouseMove(UINT nFlags, CPoint point)
+{
+ bool bRet = true;
+
+ if (m_pVMB)
+ {
+ if (m_bCursorMoving)
+ {
+ UpdateSeekBarPos(point);
+ Invalidate();
+ }
+ else if (!m_bSeekBarVisible && m_rectSeekBar.PtInRect(point))
+ {
+ m_bSeekBarVisible = true;
+ Invalidate();
+ }
+ else if (m_bSeekBarVisible && !m_rectSeekBar.PtInRect(point))
+ {
+ m_bSeekBarVisible = false;
+ Invalidate();
+ }
+ else
+ bRet = false;
+ }
+
+ return bRet;
+}
+
+bool CVMROSD::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ bool bRet = true;
+ if (m_pVMB)
+ {
+ if (m_rectCursor.PtInRect (point))
+ {
+ m_bCursorMoving = true;
+ }
+ else if (m_rectSeekBar.PtInRect(point))
+ {
+ UpdateSeekBarPos(point);
+ Invalidate();
+ }
+ else bRet = false;
+ }
+
+ return bRet;
+}
+
+bool CVMROSD::OnLButtonUp(UINT nFlags, CPoint point)
+{
+ bool bRet = true;
+
+ if (m_pVMB)
+ {
+ m_bCursorMoving = false;
+
+ bRet = (m_rectCursor.PtInRect (point) || m_rectSeekBar.PtInRect(point));
+ }
+ return bRet;
+}
+
+__int64 CVMROSD::GetPos()
+{
+ return m_llSeekPos;
+}
+
+void CVMROSD::SetPos(__int64 pos)
+{
+ m_llSeekPos = pos;
+}
+
+void CVMROSD::SetRange(__int64 start, __int64 stop)
+{
+ m_llSeekMin = start;
+ m_llSeekMax = stop;
+}
+
+void CVMROSD::GetRange(__int64& start, __int64& stop)
+{
+ start = m_llSeekMin;
+ stop = m_llSeekMax;
+}
+
+void CVMROSD::TimerFunc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
+{
+ CVMROSD* pVMROSD = (CVMROSD*) nIDEvent;
+ if (pVMROSD)
+ {
+ pVMROSD->ClearMessage();
+ }
+}
+
+void CVMROSD::ClearMessage()
+{
+ if (m_pVMB)
+ {
+ m_VMR9AlphaBitmap.dwFlags |= VMRBITMAP_DISABLE;
+ m_nMessagePos = OSD_NOMESSAGE;
+ if (m_pVMB) m_pVMB->SetAlphaBitmap(&m_VMR9AlphaBitmap);
+ }
+}
+
+void CVMROSD::DisplayMessage (OSD_MESSAGEPOS nPos, LPCTSTR strMsg, int nDuration)
+{
+ if (m_pVMB)
+ {
+ m_nMessagePos = nPos;
+ m_strMessage = strMsg;
+ KillTimer(m_pWnd->m_hWnd, (long)this);
+ if (nDuration != -1) SetTimer(m_pWnd->m_hWnd, (long)this, nDuration, TimerFunc);
+ Invalidate();
+ }
+}
diff --git a/src/apps/mplayerc/VMROSD.h b/src/apps/mplayerc/VMROSD.h
new file mode 100644
index 000000000..20d83c324
--- /dev/null
+++ b/src/apps/mplayerc/VMROSD.h
@@ -0,0 +1,89 @@
+#pragma once
+
+#include <atlbase.h>
+#include <D3d9.h>
+#include <Vmr9.h>
+
+typedef enum
+{
+ OSD_TRANSPARENT,
+ OSD_BACKGROUND,
+ OSD_BORDER,
+ OSD_TEXT,
+ OSD_BAR,
+ OSD_CURSOR,
+ OSD_LAST
+} OSD_COLORS;
+
+typedef enum
+{
+ OSD_NOMESSAGE,
+ OSD_TOPLEFT,
+ OSD_TOPRIGHT,
+} OSD_MESSAGEPOS;
+
+
+class CVMROSD
+{
+public:
+ CVMROSD(void);
+ ~CVMROSD(void);
+
+ void Start (CWnd* pWnd, CComQIPtr<IVMRMixerBitmap9> pVMB);
+ void Stop();
+
+ void DisplayMessage (OSD_MESSAGEPOS nPos, LPCTSTR strMsg, int nDuration = 5000);
+ void ClearMessage();
+
+ __int64 GetPos();
+ void SetPos(__int64 pos);
+ void SetRange(__int64 start, __int64 stop);
+ void GetRange(__int64& start, __int64& stop);
+
+ void OnSize(UINT nType, int cx, int cy);
+ bool OnMouseMove(UINT nFlags, CPoint point);
+ bool OnLButtonDown(UINT nFlags, CPoint point);
+ bool OnLButtonUp(UINT nFlags, CPoint point);
+
+private :
+ CComQIPtr<IVMRMixerBitmap9> m_pVMB;
+ CWnd* m_pWnd;
+
+ CBitmap m_Bitmap;
+ CDC m_MemDC;
+ VMR9AlphaBitmap m_VMR9AlphaBitmap;
+ BITMAP m_BitmapInfo;
+
+ CFont m_MainFont;
+ CPen m_penBorder;
+ CPen m_penCursor;
+ CBrush m_brushBack;
+ CBrush m_brushBar;
+
+ CRect m_rectWnd;
+ COLORREF m_Color[OSD_LAST];
+
+ // Curseur de calage
+ CRect m_rectSeekBar;
+ CRect m_rectCursor;
+ CRect m_rectBar;
+ bool m_bCursorMoving;
+ bool m_bSeekBarVisible;
+ __int64 m_llSeekMin;
+ __int64 m_llSeekMax;
+ __int64 m_llSeekPos;
+
+ // Messages
+ CString m_strMessage;
+ OSD_MESSAGEPOS m_nMessagePos;
+
+ void CalcRect();
+ void UpdateSeekBarPos(CPoint point);
+ void DrawSlider(CRect* rect, __int64 llMin, __int64 llMax, __int64 llPos);
+ void DrawRect(CRect* rect, CBrush* pBrush = NULL, CPen* pPen = NULL);
+ void Invalidate();
+ void DrawMessage();
+
+ static void CALLBACK TimerFunc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime);
+
+};
diff --git a/src/apps/mplayerc/VolumeCtrl.cpp b/src/apps/mplayerc/VolumeCtrl.cpp
new file mode 100644
index 000000000..5d9decfa3
--- /dev/null
+++ b/src/apps/mplayerc/VolumeCtrl.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// VolumeCtrl.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "VolumeCtrl.h"
+
+
+// CVolumeCtrl
+
+IMPLEMENT_DYNAMIC(CVolumeCtrl, CSliderCtrl)
+CVolumeCtrl::CVolumeCtrl(bool fSelfDrawn) : m_fSelfDrawn(fSelfDrawn)
+{
+}
+
+CVolumeCtrl::~CVolumeCtrl()
+{
+}
+
+bool CVolumeCtrl::Create(CWnd* pParentWnd)
+{
+ if(!CSliderCtrl::Create(WS_CHILD|WS_VISIBLE|TBS_NOTICKS|TBS_HORZ, CRect(0,0,0,0), pParentWnd, IDC_SLIDER1))
+ return(false);
+
+ SetRange(1, 100);
+ SetPosInternal(AfxGetAppSettings().nVolume);
+ SetPageSize(8);
+ SetLineSize(0);
+
+ return(true);
+}
+
+void CVolumeCtrl::SetPosInternal(int pos)
+{
+ SetPos(pos);
+ GetParent()->PostMessage(WM_HSCROLL, MAKEWPARAM((short)pos, SB_THUMBPOSITION), (LPARAM)m_hWnd); // this will be reflected back on us
+}
+
+void CVolumeCtrl::IncreaseVolume()
+{
+ SetPosInternal(GetPos() + GetPageSize());
+}
+
+void CVolumeCtrl::DecreaseVolume()
+{
+ SetPosInternal(GetPos() - GetPageSize());
+}
+
+BEGIN_MESSAGE_MAP(CVolumeCtrl, CSliderCtrl)
+ ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNMCustomdraw)
+ ON_WM_LBUTTONDOWN()
+ ON_WM_SETFOCUS()
+ ON_WM_HSCROLL_REFLECT()
+END_MESSAGE_MAP()
+
+// CVolumeCtrl message handlers
+
+
+void CVolumeCtrl::OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
+
+ LRESULT lr = CDRF_DODEFAULT;
+
+ if(m_fSelfDrawn)
+ switch(pNMCD->dwDrawStage)
+ {
+ case CDDS_PREPAINT:
+ lr = CDRF_NOTIFYITEMDRAW;
+ break;
+
+ case CDDS_ITEMPREPAINT:
+ if(pNMCD->dwItemSpec == TBCD_CHANNEL)
+ {
+ CDC dc;
+ dc.Attach(pNMCD->hdc);
+
+ CRect r;
+ GetClientRect(r);
+ r.DeflateRect(8, 4, 10, 6);
+ CopyRect(&pNMCD->rc, &r);
+ CPen shadow(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW));
+ CPen light(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT));
+ CPen* old = dc.SelectObject(&light);
+ dc.MoveTo(pNMCD->rc.right, pNMCD->rc.top);
+ dc.LineTo(pNMCD->rc.right, pNMCD->rc.bottom);
+ dc.LineTo(pNMCD->rc.left, pNMCD->rc.bottom);
+ dc.SelectObject(&shadow);
+ dc.LineTo(pNMCD->rc.right, pNMCD->rc.top);
+ dc.SelectObject(old);
+
+ dc.Detach();
+ lr = CDRF_SKIPDEFAULT;
+ }
+ else if(pNMCD->dwItemSpec == TBCD_THUMB)
+ {
+ CDC dc;
+ dc.Attach(pNMCD->hdc);
+ pNMCD->rc.bottom--;
+ CRect r(pNMCD->rc);
+ r.DeflateRect(0, 0, 1, 0);
+
+ COLORREF shadow = GetSysColor(COLOR_3DSHADOW);
+ COLORREF light = GetSysColor(COLOR_3DHILIGHT);
+ dc.Draw3dRect(&r, light, 0);
+ r.DeflateRect(0, 0, 1, 1);
+ dc.Draw3dRect(&r, light, shadow);
+ r.DeflateRect(1, 1, 1, 1);
+ dc.FillSolidRect(&r, GetSysColor(COLOR_BTNFACE));
+ dc.SetPixel(r.left+7, r.top-1, GetSysColor(COLOR_BTNFACE));
+
+ dc.Detach();
+ lr = CDRF_SKIPDEFAULT;
+ }
+
+ break;
+ };
+
+ pNMCD->uItemState &= ~CDIS_FOCUS;
+
+ *pResult = lr;
+}
+
+void CVolumeCtrl::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ CRect r;
+ GetChannelRect(&r);
+
+ if(r.left >= r.right) return;
+
+ int start, stop;
+ GetRange(start, stop);
+
+ int pos = GetPos();
+
+ r.left += 3;
+ r.right -= 4;
+
+ if(point.x < r.left) SetPos(start);
+ else if(point.x >= r.right) SetPos(stop);
+ else
+ {
+ int w = r.right - r.left;
+ if(start < stop)
+ SetPosInternal(start + ((stop - start) * (point.x - r.left) + (w/2)) / w);
+ }
+
+ CSliderCtrl::OnLButtonDown(nFlags, point);
+}
+
+void CVolumeCtrl::OnSetFocus(CWnd* pOldWnd)
+{
+ CSliderCtrl::OnSetFocus(pOldWnd);
+
+ AfxGetMainWnd()->SetFocus(); // don't focus on us, parents will take care of our positioning
+}
+
+void CVolumeCtrl::HScroll(UINT nSBCode, UINT nPos)
+{
+ AfxGetAppSettings().nVolume = GetPos();
+
+ CFrameWnd* pFrame = GetParentFrame();
+ if(pFrame && pFrame != GetParent())
+ pFrame->PostMessage(WM_HSCROLL, MAKEWPARAM((short)nPos, nSBCode), (LPARAM)m_hWnd);
+}
diff --git a/src/apps/mplayerc/VolumeCtrl.h b/src/apps/mplayerc/VolumeCtrl.h
new file mode 100644
index 000000000..13d1fd098
--- /dev/null
+++ b/src/apps/mplayerc/VolumeCtrl.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+// CVolumeCtrl
+
+class CVolumeCtrl : public CSliderCtrl
+{
+ DECLARE_DYNAMIC(CVolumeCtrl)
+
+private:
+ bool m_fSelfDrawn;
+
+public:
+ CVolumeCtrl(bool fSelfDrawn = true);
+ virtual ~CVolumeCtrl();
+
+ bool Create(CWnd* pParentWnd);
+
+ void IncreaseVolume(), DecreaseVolume();
+
+ void SetPosInternal(int pos);
+
+protected:
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnSetFocus(CWnd* pOldWnd);
+ afx_msg void HScroll(UINT nSBCode, UINT nPos);
+};
diff --git a/src/apps/mplayerc/WebClientSocket.cpp b/src/apps/mplayerc/WebClientSocket.cpp
new file mode 100644
index 000000000..510bd7060
--- /dev/null
+++ b/src/apps/mplayerc/WebClientSocket.cpp
@@ -0,0 +1,727 @@
+#include "stdafx.h"
+#include <atlisapi.h>
+#include "mplayerc.h"
+#include "resource.h"
+#include "MainFrm.h"
+#include "..\..\subtitles\TextFile.h"
+#include ".\webserver.h"
+#include ".\webclientsocket.h"
+
+CWebClientSocket::CWebClientSocket(CWebServer* pWebServer, CMainFrame* pMainFrame)
+ : m_pWebServer(pWebServer)
+ , m_pMainFrame(pMainFrame)
+{
+}
+
+CWebClientSocket::~CWebClientSocket()
+{
+}
+
+bool CWebClientSocket::SetCookie(CString name, CString value, __time64_t expire, CString path, CString domain)
+{
+ if(name.IsEmpty()) return(false);
+ if(value.IsEmpty()) {m_cookie.RemoveKey(name); return true;}
+
+ m_cookie[name] = value;
+
+ m_cookieattribs[name].path = path;
+ m_cookieattribs[name].domain = domain;
+
+ if(expire >= 0)
+ {
+ CTime t(expire);
+ SYSTEMTIME st;
+ t.GetAsSystemTime(st);
+ CStringA str;
+ SystemTimeToHttpDate(st, str);
+ m_cookieattribs[name].expire = str;
+ }
+
+ return true;
+}
+
+void CWebClientSocket::Clear()
+{
+ m_hdr.Empty();
+ m_hdrlines.RemoveAll();
+ m_data.Empty();
+
+ m_cmd.Empty();
+ m_path.Empty();
+ m_ver.Empty();
+ m_get.RemoveAll();
+ m_post.RemoveAll();
+ m_cookie.RemoveAll();
+ m_request.RemoveAll();
+}
+
+void CWebClientSocket::Header()
+{
+ if(m_cmd.IsEmpty())
+ {
+ if(m_hdr.IsEmpty()) return;
+
+ CAtlList<CString> lines;
+ Explode(m_hdr, lines, '\n');
+ CString str = lines.RemoveHead();
+
+ CAtlList<CString> sl;
+ ExplodeMin(str, sl, ' ', 3);
+ m_cmd = sl.RemoveHead().MakeUpper();
+ m_path = sl.RemoveHead();
+ m_ver = sl.RemoveHead().MakeUpper();
+ ASSERT(sl.GetCount() == 0);
+
+ POSITION pos = lines.GetHeadPosition();
+ while(pos)
+ {
+ Explode(lines.GetNext(pos), sl, ':', 2);
+ if(sl.GetCount() == 2)
+ m_hdrlines[sl.GetHead().MakeLower()] = sl.GetTail();
+ }
+ }
+
+ // remember new cookies
+
+ POSITION pos = m_hdrlines.GetStartPosition();
+ while(pos)
+ {
+ CString key, value;
+ m_hdrlines.GetNextAssoc(pos, key, value);
+
+ if(key == _T("cookie"))
+ {
+ CAtlList<CString> sl;
+ Explode(value, sl, ';');
+ POSITION pos2 = sl.GetHeadPosition();
+ while(pos2)
+ {
+ CAtlList<CString> sl2;
+ Explode(sl.GetNext(pos2), sl2, '=', 2);
+ m_cookie[sl2.GetHead()] = sl2.GetCount() == 2 ? sl2.GetTail() : _T("");
+ }
+ }
+ }
+
+ // start new session
+
+ if(!m_cookie.Lookup(_T("MPCSESSIONID"), m_sessid))
+ {
+ srand((unsigned int)time(NULL));
+ m_sessid.Format(_T("%08x"), rand()*0x12345678);
+ SetCookie(_T("MPCSESSIONID"), m_sessid);
+ }
+ else
+ {
+ // TODO: load session
+ }
+
+ CStringA reshdr, resbody;
+
+ if(m_cmd == _T("POST"))
+ {
+ CString str;
+ if(m_hdrlines.Lookup(_T("content-length"), str))
+ {
+ int len = _tcstol(str, NULL, 10);
+ str.Empty();
+
+ int err;
+ char c;
+
+ int timeout = 1000;
+
+ do
+ {
+ for(; len > 0 && (err = Receive(&c, 1)) > 0; len--)
+ {
+ m_data += c;
+ if(c == '\r') continue;
+ str += c;
+ if(c == '\n' || len == 1)
+ {
+ CAtlList<CString> sl;
+ Explode(AToT(UrlDecode(TToA(str))), sl, '&'); // FIXME
+ POSITION pos = sl.GetHeadPosition();
+ while(pos)
+ {
+ CAtlList<CString> sl2;
+ Explode(sl.GetNext(pos), sl2, '=', 2);
+ m_post[sl2.GetHead().MakeLower()] = sl2.GetCount() == 2 ? sl2.GetTail() : _T("");
+ }
+ str.Empty();
+ }
+ }
+
+ if(err == SOCKET_ERROR)
+ Sleep(1);
+ }
+ while(err == SOCKET_ERROR && GetLastError() == WSAEWOULDBLOCK
+ && timeout-- > 0); // FIXME: this is just a dirty fix now
+
+ // FIXME: with IE it will only work if I read +2 bytes (?), btw Receive will just return -1
+ Receive(&c, 1);
+ Receive(&c, 1);
+ }
+ }
+
+ if(m_cmd == _T("GET") || m_cmd == _T("HEAD") || m_cmd == _T("POST"))
+ {
+ CAtlList<CString> sl;
+
+ Explode(m_path, sl, '?', 2);
+ m_path = sl.RemoveHead();
+ m_query.Empty();
+
+ if(!sl.IsEmpty())
+ {
+ m_query = sl.GetTail();
+
+ Explode(Explode(m_query, sl, '#', 2), sl, '&'); // oh yeah
+ // Explode(AToT(UrlDecode(TToA(Explode(m_query, sl, '#', 2)))), sl, '&'); // oh yeah
+ POSITION pos = sl.GetHeadPosition();
+ while(pos)
+ {
+ CAtlList<CString> sl2;
+ Explode(AToT(UrlDecode(TToA(sl.GetNext(pos)))), sl2, '=', 2);
+ // Explode(sl.GetNext(pos), sl2, '=', 2);
+ m_get[sl2.GetHead()] = sl2.GetCount() == 2 ? sl2.GetTail() : _T("");
+ }
+ }
+
+ // m_request <-- m_get+m_post+m_cookie
+ {
+ CString key, value;
+ POSITION pos;
+ pos = m_get.GetStartPosition();
+ while(pos) {m_get.GetNextAssoc(pos, key, value); m_request[key] = value;}
+ pos = m_post.GetStartPosition();
+ while(pos) {m_post.GetNextAssoc(pos, key, value); m_request[key] = value;}
+ pos = m_cookie.GetStartPosition();
+ while(pos) {m_cookie.GetNextAssoc(pos, key, value); m_request[key] = value;}
+ }
+
+ m_pWebServer->OnRequest(this, reshdr, resbody);
+ }
+ else
+ {
+ reshdr = "HTTP/1.0 400 Bad Request\r\n";
+ }
+
+ if(!reshdr.IsEmpty())
+ {
+ // cookies
+ {
+ POSITION pos = m_cookie.GetStartPosition();
+ while(pos)
+ {
+ CString key, value;
+ m_cookie.GetNextAssoc(pos, key, value);
+ reshdr += "Set-Cookie: " + key + "=" + value;
+ POSITION pos2 = m_cookieattribs.GetStartPosition();
+ while(pos2)
+ {
+ CString key;
+ cookie_attribs value;
+ m_cookieattribs.GetNextAssoc(pos2, key, value);
+ if(!value.path.IsEmpty()) reshdr += " path=" + value.path;
+ if(!value.expire.IsEmpty()) reshdr += " expire=" + value.expire;
+ if(!value.domain.IsEmpty()) reshdr += " domain=" + value.domain;
+ }
+ reshdr += "\r\n";
+ }
+ }
+
+ reshdr +=
+ "Server: MPC WebServer\r\n"
+ "Connection: close\r\n"
+ "\r\n";
+
+ Send(reshdr, reshdr.GetLength());
+
+ if(m_cmd != _T("HEAD") && reshdr.Find("HTTP/1.0 200 OK") == 0 && !resbody.IsEmpty())
+ {
+ Send(resbody, resbody.GetLength());
+ }
+
+ CString connection = _T("close");
+ m_hdrlines.Lookup(_T("connection"), connection);
+
+ Clear();
+
+ // TODO
+ // if(connection == _T("close"))
+ OnClose(0);
+ }
+}
+
+//
+
+void CWebClientSocket::OnReceive(int nErrorCode)
+{
+ if(nErrorCode == 0)
+ {
+ char c;
+ while(Receive(&c, 1) > 0)
+ {
+ if(c == '\r') continue;
+ else m_hdr += c;
+
+ int len = m_hdr.GetLength();
+ if(len >= 2 && m_hdr[len-2] == '\n' && m_hdr[len-1] == '\n')
+ {
+ Header();
+ return;
+ }
+ }
+ }
+
+ __super::OnReceive(nErrorCode);
+}
+
+void CWebClientSocket::OnClose(int nErrorCode)
+{
+ // TODO: save session
+ m_pWebServer->OnClose(this);
+ __super::OnClose(nErrorCode);
+}
+
+////////////////////
+
+bool CWebClientSocket::OnCommand(CStringA& hdr, CStringA& body, CStringA& mime)
+{
+ CString arg;
+ if(m_request.Lookup(_T("wm_command"), arg))
+ {
+ int id = _ttol(arg);
+
+ if(id > 0)
+ {
+ if(id == ID_FILE_EXIT) m_pMainFrame->PostMessage(WM_COMMAND, id);
+ else m_pMainFrame->SendMessage(WM_COMMAND, id);
+ }
+ else
+ {
+ if(arg == CMD_SETPOS && m_request.Lookup(_T("position"), arg))
+ {
+ int h, m, s, ms = 0;
+ TCHAR c;
+ if(_stscanf(arg, _T("%d%c%d%c%d%c%d"), &h, &c, &m, &c, &s, &c, &ms) >= 5)
+ {
+ REFERENCE_TIME rtPos = 10000i64*(((h*60+m)*60+s)*1000+ms);
+ m_pMainFrame->SeekTo(rtPos);
+ for(int retries = 20; retries-- > 0; Sleep(50))
+ {
+ if(abs((int)((rtPos - m_pMainFrame->GetPos())/10000)) < 100)
+ break;
+ }
+ }
+ }
+ else if(arg == CMD_SETPOS && m_request.Lookup(_T("percent"), arg))
+ {
+ float percent = 0;
+ if(_stscanf(arg, _T("%f"), &percent) == 1)
+ m_pMainFrame->SeekTo((REFERENCE_TIME)(percent / 100 * m_pMainFrame->GetDur()));
+ }
+ else if(arg == CMD_SETVOLUME && m_request.Lookup(_T("volume"), arg))
+ {
+ int volume = _tcstol(arg, NULL, 10);
+ m_pMainFrame->m_wndToolBar.Volume = min(max(volume, 1), 100);
+ m_pMainFrame->OnPlayVolume(0);
+ }
+ }
+ }
+
+ CString ref;
+ if(!m_hdrlines.Lookup(_T("referer"), ref))
+ return true;
+
+ hdr =
+ "HTTP/1.0 302 Found\r\n"
+ "Location: " + CStringA(ref) + "\r\n";
+
+ return true;
+}
+
+bool CWebClientSocket::OnIndex(CStringA& hdr, CStringA& body, CStringA& mime)
+{
+ CStringA wmcoptions;
+
+ // generate page
+
+ AppSettings& s = AfxGetAppSettings();
+ POSITION pos = s.wmcmds.GetHeadPosition();
+ while(pos)
+ {
+ wmcmd& wc = s.wmcmds.GetNext(pos);
+ CStringA str;
+ str.Format("%d", wc.cmd);
+ wmcoptions += "<option value=\"" + str + "\">"
+ + CStringA(wc.name) + "\r\n";
+ }
+
+ m_pWebServer->LoadPage(IDR_HTML_INDEX, body, m_path);
+ body.Replace("[wmcoptions]", wmcoptions);
+
+ return true;
+}
+
+bool CWebClientSocket::OnBrowser(CStringA& hdr, CStringA& body, CStringA& mime)
+{
+ CAtlList<CStringA> rootdrives;
+ for(TCHAR drive[] = _T("A:"); drive[0] <= 'Z'; drive[0]++)
+ if(GetDriveType(drive) != DRIVE_NO_ROOT_DIR)
+ rootdrives.AddTail(CStringA(drive) + '\\');
+
+ // process GET
+
+ CString path;
+ CFileStatus fs;
+ if(m_get.Lookup(_T("path"), path))
+ {
+ path = WToT(UTF8To16(TToA(path)));
+
+ if(CFileGetStatus(path, fs) && !(fs.m_attribute&CFile::directory))
+ {
+ // TODO: make a new message for just opening files, this is a bit overkill now...
+
+ CAtlList<CString> cmdln;
+
+ cmdln.AddTail(path);
+
+ CString focus;
+ if(m_get.Lookup(_T("focus"), focus) && !focus.CompareNoCase(_T("no")))
+ cmdln.AddTail(_T("/nofocus"));
+
+ int len = 0;
+
+ POSITION pos = cmdln.GetHeadPosition();
+ while(pos)
+ {
+ CString& str = cmdln.GetNext(pos);
+ len += (str.GetLength()+1)*sizeof(TCHAR);
+ }
+
+ CAutoVectorPtr<BYTE> buff;
+ if(buff.Allocate(4+len))
+ {
+ BYTE* p = buff;
+ *(DWORD*)p = cmdln.GetCount();
+ p += sizeof(DWORD);
+
+ POSITION pos = cmdln.GetHeadPosition();
+ while(pos)
+ {
+ CString& str = cmdln.GetNext(pos);
+ len = (str.GetLength()+1)*sizeof(TCHAR);
+ memcpy(p, (LPCTSTR)str, len);
+ p += len;
+ }
+
+ COPYDATASTRUCT cds;
+ cds.dwData = 0x6ABE51;
+ cds.cbData = p - buff;
+ cds.lpData = (void*)(BYTE*)buff;
+ m_pMainFrame->SendMessage(WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds);
+ }
+
+ CPath p(path);
+ p.RemoveFileSpec();
+ path = (LPCTSTR)p;
+ }
+ }
+ else
+ {
+ path = m_pMainFrame->m_wndPlaylistBar.GetCur();
+
+ if(CFileGetStatus(path, fs) && !(fs.m_attribute&CFile::directory))
+ {
+ CPath p(path);
+ p.RemoveFileSpec();
+ path = (LPCTSTR)p;
+ }
+ }
+
+ if(path.Find(_T("://")) >= 0)
+ path.Empty();
+
+ if(CFileGetStatus(path, fs) && (fs.m_attribute&CFile::directory)
+ || path.Find(_T("\\")) == 0) // FIXME
+ {
+ CPath p(path);
+ p.Canonicalize();
+ p.MakePretty();
+ p.AddBackslash();
+ path = (LPCTSTR)p;
+ }
+
+ CStringA files;
+
+ if(path.IsEmpty())
+ {
+ POSITION pos = rootdrives.GetHeadPosition();
+ while(pos)
+ {
+ CStringA& drive = rootdrives.GetNext(pos);
+
+ files += "<tr>\r\n";
+ files +=
+ "<td><a href=\"[path]?path=" + UrlEncode(drive) + "\">" + drive + "</a></td>"
+ "<td>Directory</td>"
+ "<td>&nbsp</td>\r\n"
+ "<td>&nbsp</td>";
+ files += "</tr>\r\n";
+ }
+
+ path = "Root";
+ }
+ else
+ {
+ CString parent;
+
+ if(path.GetLength() > 3)
+ {
+ CPath p(path + "..");
+ p.Canonicalize();
+ p.AddBackslash();
+ parent = (LPCTSTR)p;
+ }
+
+ files += "<tr>\r\n";
+ files +=
+ "<td><a href=\"[path]?path=" + parent + "\">..</a></td>"
+ "<td>Directory</td>"
+ "<td>&nbsp</td>\r\n"
+ "<td>&nbsp</td>";
+ files += "</tr>\r\n";
+
+ WIN32_FIND_DATA fd = {0};
+
+ HANDLE hFind = FindFirstFile(path + "*.*", &fd);
+ if(hFind != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if(!(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) || fd.cFileName[0] == '.')
+ continue;
+
+ CString fullpath = path + fd.cFileName;
+
+ files += "<tr>\r\n";
+ files +=
+ "<td><a href=\"[path]?path=" + UTF8Arg(fullpath) + "\">" + UTF8(fd.cFileName) + "</a></td>"
+ "<td>Directory</td>"
+ "<td>&nbsp</td>\r\n"
+ "<td><nobr>" + CStringA(CTime(fd.ftLastWriteTime).Format(_T("%Y.%m.%d %H:%M"))) + "</nobr></td>";
+ files += "</tr>\r\n";
+ }
+ while(FindNextFile(hFind, &fd));
+
+ FindClose(hFind);
+ }
+
+ hFind = FindFirstFile(path + "*.*", &fd);
+ if(hFind != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
+ continue;
+
+ CString fullpath = path + fd.cFileName;
+
+ CStringA size;
+ size.Format("%I64dK", ((UINT64)fd.nFileSizeHigh<<22)|(fd.nFileSizeLow>>10));
+
+ CString type(_T("&nbsp"));
+ LoadType(fullpath, type);
+
+ files += "<tr>\r\n";
+ files +=
+ "<td><a href=\"[path]?path=" + UTF8Arg(fullpath) + "\">" + UTF8(fd.cFileName) + "</a></td>"
+ "<td><nobr>" + UTF8(type) + "</nobr></td>"
+ "<td align=\"right\"><nobr>" + size + "</nobr></td>\r\n"
+ "<td><nobr>" + CStringA(CTime(fd.ftLastWriteTime).Format(_T("%Y.%m.%d %H:%M"))) + "</nobr></td>";
+ files += "</tr>\r\n";
+ }
+ while(FindNextFile(hFind, &fd));
+
+ FindClose(hFind);
+ }
+ }
+
+ m_pWebServer->LoadPage(IDR_HTML_BROWSER, body, m_path);
+ body.Replace("[charset]", "UTF-8"); // FIXME: win9x build...
+ body.Replace("[currentdir]", UTF8(path));
+ body.Replace("[currentfiles]", files);
+
+ return true;
+}
+
+bool CWebClientSocket::OnControls(CStringA& hdr, CStringA& body, CStringA& mime)
+{
+ CString path = m_pMainFrame->m_wndPlaylistBar.GetCur();
+ CString dir;
+
+ if(!path.IsEmpty())
+ {
+ CPath p(path);
+ p.RemoveFileSpec();
+ dir = (LPCTSTR)p;
+ }
+
+ OAFilterState fs = m_pMainFrame->GetMediaState();
+ CString state;
+ state.Format(_T("%d"), fs);
+ CString statestring;
+ switch(fs)
+ {
+ case State_Stopped: statestring = ResStr(IDS_CONTROLS_STOPPED); break;
+ case State_Paused: statestring = ResStr(IDS_CONTROLS_PAUSED); break;
+ case State_Running: statestring = ResStr(IDS_CONTROLS_PLAYING); break;
+ default: statestring = _T("n/a"); break;
+ }
+
+ int pos = (int)(m_pMainFrame->GetPos()/10000);
+ int dur = (int)(m_pMainFrame->GetDur()/10000);
+
+ CString position, duration;
+ position.Format(_T("%d"), pos);
+ duration.Format(_T("%d"), dur);
+
+ CString positionstring, durationstring, playbackrate;
+// positionstring.Format(_T("%02d:%02d:%02d.%03d"), (pos/3600000), (pos/60000)%60, (pos/1000)%60, pos%1000);
+// durationstring.Format(_T("%02d:%02d:%02d.%03d"), (dur/3600000), (dur/60000)%60, (dur/1000)%60, dur%1000);
+ positionstring.Format(_T("%02d:%02d:%02d"), (pos/3600000), (pos/60000)%60, (pos/1000)%60);
+ durationstring.Format(_T("%02d:%02d:%02d"), (dur/3600000), (dur/60000)%60, (dur/1000)%60);
+ playbackrate = _T("1"); // TODO
+
+ CString volumelevel, muted;
+ volumelevel.Format(_T("%d"), m_pMainFrame->m_wndToolBar.m_volctrl.GetPos());
+ muted.Format(_T("%d"), m_pMainFrame->m_wndToolBar.Volume == -10000 ? 1 : 0);
+
+ CString reloadtime(_T("0")); // TODO
+
+ m_pWebServer->LoadPage(IDR_HTML_CONTROLS, body, m_path);
+ body.Replace("[charset]", "UTF-8"); // FIXME: win9x build...
+ body.Replace("[filepatharg]", UTF8Arg(path));
+ body.Replace("[filepath]", UTF8(path));
+ body.Replace("[filedirarg]", UTF8Arg(dir));
+ body.Replace("[filedir]", UTF8(dir));
+ body.Replace("[state]", UTF8(state));
+ body.Replace("[statestring]", UTF8(statestring));
+ body.Replace("[position]", UTF8(position));
+ body.Replace("[positionstring]", UTF8(positionstring));
+ body.Replace("[duration]", UTF8(duration));
+ body.Replace("[durationstring]", UTF8(durationstring));
+ body.Replace("[volumelevel]", UTF8(volumelevel));
+ body.Replace("[muted]", UTF8(muted));
+ body.Replace("[playbackrate]", UTF8(playbackrate));
+ body.Replace("[reloadtime]", UTF8(reloadtime));
+
+ return true;
+}
+
+bool CWebClientSocket::OnStatus(CStringA& hdr, CStringA& body, CStringA& mime)
+{
+/*
+ CString path = m_pMainFrame->m_wndPlaylistBar.GetCur(), dir;
+ if(!path.IsEmpty()) {CPath p(path); p.RemoveFileSpec(); dir = (LPCTSTR)p;}
+ path.Replace(_T("'"), _T("\\'"));
+ dir.Replace(_T("'"), _T("\\'"));
+
+ CString volumelevel, muted;
+ volumelevel.Format(_T("%d"), m_pMainFrame->m_wndToolBar.m_volctrl.GetPos());
+ muted.Format(_T("%d"), m_pMainFrame->m_wndToolBar.Volume == -10000 ? 1 : 0);
+ body.Replace("[volumelevel]", UTF8(volumelevel));
+ body.Replace("[muted]", UTF8(muted));
+*/
+ CString title;
+ m_pMainFrame->GetWindowText(title);
+
+ CString status = m_pMainFrame->GetStatusMessage();
+
+ int pos = (int)(m_pMainFrame->GetPos()/10000);
+ int dur = (int)(m_pMainFrame->GetDur()/10000);
+
+ CString posstr, durstr;
+ posstr.Format(_T("%02d:%02d:%02d"), (pos/3600000), (pos/60000)%60, (pos/1000)%60);
+ durstr.Format(_T("%02d:%02d:%02d"), (dur/3600000), (dur/60000)%60, (dur/1000)%60);
+
+ title.Replace(_T("'"), _T("\\'"));
+ status.Replace(_T("'"), _T("\\'"));
+
+ body.Format("OnStatus('%s', '%s', %d, '%s', %d, '%s', %d, %d)", // , '%s', '%s'
+ UTF8(title), UTF8(status),
+ pos, UTF8(posstr), dur, UTF8(durstr),
+ m_pMainFrame->IsMuted(), m_pMainFrame->GetVolume()
+ /*, UTF8(path), UTF8(dir)*/);
+
+ return true;
+}
+
+bool CWebClientSocket::OnError404(CStringA& hdr, CStringA& body, CStringA& mime)
+{
+ m_pWebServer->LoadPage(IDR_HTML_404, body, m_path);
+ return true;
+}
+
+bool CWebClientSocket::OnPlayer(CStringA& hdr, CStringA& body, CStringA& mime)
+{
+ m_pWebServer->LoadPage(IDR_HTML_PLAYER, body, m_path);
+ return true;
+}
+
+#include "jpeg.h"
+
+bool CWebClientSocket::OnSnapShotJpeg(CStringA& hdr, CStringA& body, CStringA& mime)
+{
+ // TODO: add quality control and return logo when nothing is loaded
+
+ bool fRet = false;
+
+ BYTE* pData = NULL;
+ long size = 0;
+ CAtlArray<BYTE> jpeg;
+ if(m_pMainFrame->GetDIB(&pData, size, true))
+ {
+ if(CJpegEncoderMem().Encode(pData, jpeg))
+ {
+ hdr +=
+ "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n"
+ "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n"
+ "Pragma: no-cache\r\n";
+ body = CStringA((char*)jpeg.GetData(), jpeg.GetCount());
+ mime = "image/jpeg";
+ fRet = true;
+ }
+
+ delete [] pData;
+ }
+
+ return fRet;
+}
+
+#include "ConvertDlg.h"
+
+bool CWebClientSocket::OnConvRes(CStringA& hdr, CStringA& body, CStringA& mime)
+{
+ CString id;
+ if(!m_get.Lookup(_T("id"), id))
+ return false;
+
+ DWORD key = 0;
+ if(1 != _stscanf(id, _T("%x"), &key) || key == 0)
+ return false;
+
+ CAutoLock cAutoLock(&CDSMResource::m_csResources);
+
+ CDSMResource* res = NULL;
+ if(!CDSMResource::m_resources.Lookup(key, res) || !res)
+ return false;
+
+ body = CStringA((const char*)res->data.GetData(), res->data.GetCount());
+ mime = CString(res->mime);
+
+ return true;
+}
diff --git a/src/apps/mplayerc/WebClientSocket.h b/src/apps/mplayerc/WebClientSocket.h
new file mode 100644
index 000000000..d08dafe97
--- /dev/null
+++ b/src/apps/mplayerc/WebClientSocket.h
@@ -0,0 +1,44 @@
+#pragma once
+
+class CWebServer;
+
+class CWebClientSocket : public CAsyncSocket
+{
+ CWebServer* m_pWebServer;
+ CMainFrame* m_pMainFrame;
+
+ CString m_hdr;
+
+ struct cookie_attribs {CString path, expire, domain;};
+ CAtlStringMap<cookie_attribs> m_cookieattribs;
+
+ void Clear();
+ void Header();
+
+protected:
+ void OnReceive(int nErrorCode);
+ void OnClose(int nErrorCode);
+
+public:
+ CWebClientSocket(CWebServer* pWebServer, CMainFrame* pMainFrame);
+ virtual ~CWebClientSocket();
+
+ bool SetCookie(CString name, CString value = _T(""), __time64_t expire = -1, CString path = _T("/"), CString domain = _T(""));
+
+ CString m_sessid;
+ CString m_cmd, m_path, m_query, m_ver;
+ CStringA m_data;
+ CAtlStringMap<> m_hdrlines;
+ CAtlStringMap<> m_get, m_post, m_cookie;
+ CAtlStringMap<> m_request;
+
+ bool OnCommand(CStringA& hdr, CStringA& body, CStringA& mime);
+ bool OnIndex(CStringA& hdr, CStringA& body, CStringA& mime);
+ bool OnBrowser(CStringA& hdr, CStringA& body, CStringA& mime);
+ bool OnControls(CStringA& hdr, CStringA& body, CStringA& mime);
+ bool OnStatus(CStringA& hdr, CStringA& body, CStringA& mime);
+ bool OnError404(CStringA& hdr, CStringA& body, CStringA& mime);
+ bool OnPlayer(CStringA& hdr, CStringA& body, CStringA& mime);
+ bool OnSnapShotJpeg(CStringA& hdr, CStringA& body, CStringA& mime);
+ bool OnConvRes(CStringA& hdr, CStringA& body, CStringA& mime);
+}; \ No newline at end of file
diff --git a/src/apps/mplayerc/WebServer.cpp b/src/apps/mplayerc/WebServer.cpp
new file mode 100644
index 000000000..a58b29f7d
--- /dev/null
+++ b/src/apps/mplayerc/WebServer.cpp
@@ -0,0 +1,614 @@
+#include "stdafx.h"
+#include "mplayerc.h"
+#include "resource.h"
+#include "MainFrm.h"
+#include <atlbase.h>
+#include <atlisapi.h>
+#include "WebServerSocket.h"
+#include "WebClientSocket.h"
+#include "WebServer.h"
+#include "..\..\zlib\zlib.h"
+
+CAtlStringMap<CWebServer::RequestHandler> CWebServer::m_internalpages;
+CAtlStringMap<UINT> CWebServer::m_downloads;
+CAtlStringMap<CStringA, CStringA> CWebServer::m_mimes;
+
+CWebServer::CWebServer(CMainFrame* pMainFrame, int nPort)
+ : m_pMainFrame(pMainFrame)
+ , m_nPort(nPort)
+{
+ if(m_internalpages.IsEmpty())
+ {
+ m_internalpages[_T("/")] = &CWebClientSocket::OnIndex;
+ m_internalpages[_T("/index.html")] = &CWebClientSocket::OnIndex;
+ m_internalpages[_T("/browser.html")] = &CWebClientSocket::OnBrowser;
+ m_internalpages[_T("/controls.html")] = &CWebClientSocket::OnControls;
+ m_internalpages[_T("/command.html")] = &CWebClientSocket::OnCommand;
+ m_internalpages[_T("/status.html")] = &CWebClientSocket::OnStatus;
+ m_internalpages[_T("/player.html")] = &CWebClientSocket::OnPlayer;
+ m_internalpages[_T("/snapshot.jpg")] = &CWebClientSocket::OnSnapShotJpeg;
+ m_internalpages[_T("/404.html")] = &CWebClientSocket::OnError404;
+ m_internalpages[_T("/convres.html")] = &CWebClientSocket::OnConvRes;
+ }
+
+ if(m_downloads.IsEmpty())
+ {
+ m_downloads[_T("/default.css")] = IDF_DEFAULT_CSS;
+ m_downloads[_T("/vbg.gif")] = IDF_VBR_GIF;
+ m_downloads[_T("/vbs.gif")] = IDF_VBS_GIF;
+ m_downloads[_T("/sliderbar.gif")] = IDF_SLIDERBAR_GIF;
+ m_downloads[_T("/slidergrip.gif")] = IDF_SLIDERGRIP_GIF;
+ m_downloads[_T("/sliderback.gif")] = IDF_SLIDERBACK_GIF;
+ m_downloads[_T("/1pix.gif")] = IDF_1PIX_GIF;
+ m_downloads[_T("/headericon.png")] = IDF_HEADERICON_PNG;
+ m_downloads[_T("/headerback.png")] = IDF_HEADERBACK_PNG;
+ m_downloads[_T("/headerclose.png")] = IDF_HEADERCLOSE_PNG;
+ m_downloads[_T("/leftside.png")] = IDF_LEFTSIDE_PNG;
+ m_downloads[_T("/rightside.png")] = IDF_RIGHTSIDE_PNG;
+ m_downloads[_T("/bottomside.png")] = IDF_BOTTOMSIDE_PNG;
+ m_downloads[_T("/leftbottomside.png")] = IDF_LEFTBOTTOMSIDE_PNG;
+ m_downloads[_T("/rightbottomside.png")] = IDF_RIGHTBOTTOMSIDE_PNG;
+ m_downloads[_T("/seekbarleft.png")] = IDF_SEEKBARLEFT_PNG;
+ m_downloads[_T("/seekbarmid.png")] = IDF_SEEKBARMID_PNG;
+ m_downloads[_T("/seekbarright.png")] = IDF_SEEKBARRIGHT_PNG;
+ m_downloads[_T("/seekbargrip.png")] = IDF_SEEKBARGRIP_PNG;
+ m_downloads[_T("/logo.png")] = IDF_LOGO_PNG;
+ m_downloads[_T("/controlback.png")] = IDF_CONTROLBACK_PNG;
+ m_downloads[_T("/controlbuttonplay.png")] = IDF_CONTROLBUTTONPLAY_PNG;
+ m_downloads[_T("/controlbuttonpause.png")] = IDF_CONTROLBUTTONPAUSE_PNG;
+ m_downloads[_T("/controlbuttonstop.png")] = IDF_CONTROLBUTTONSTOP_PNG;
+ m_downloads[_T("/controlbuttonskipback.png")] = IDF_CONTROLBUTTONSKIPBACK_PNG;
+ m_downloads[_T("/controlbuttondecrate.png")] = IDF_CONTROLBUTTONDECRATE_PNG;
+ m_downloads[_T("/controlbuttonincrate.png")] = IDF_CONTROLBUTTONINCRATE_PNG;
+ m_downloads[_T("/controlbuttonskipforward.png")] = IDF_CONTROLBUTTONSKIPFORWARD_PNG;
+ m_downloads[_T("/controlbuttonstep.png")] = IDF_CONTROLBUTTONSTEP_PNG;
+ m_downloads[_T("/controlvolumeon.png")] = IDF_CONTROLVOLUMEON_PNG;
+ m_downloads[_T("/controlvolumeoff.png")] = IDF_CONTROLVOLUMEOFF_PNG;
+ m_downloads[_T("/controlvolumebar.png")] = IDF_CONTROLVOLUMEBAR_PNG;
+ m_downloads[_T("/controlvolumegrip.png")] = IDF_CONTROLVOLUMEGRIP_PNG;
+ }
+
+ CRegKey key;
+ CString str(_T("MIME\\Database\\Content Type"));
+ if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, str, KEY_READ))
+ {
+ TCHAR buff[256];
+ DWORD len = countof(buff);
+ for(int i = 0; ERROR_SUCCESS == key.EnumKey(i, buff, &len); i++, len = countof(buff))
+ {
+ CRegKey mime;
+ TCHAR ext[64];
+ ULONG len = countof(ext);
+ if(ERROR_SUCCESS == mime.Open(HKEY_CLASSES_ROOT, str + _T("\\") + buff, KEY_READ)
+ && ERROR_SUCCESS == mime.QueryStringValue(_T("Extension"), ext, &len))
+ m_mimes[CStringA(ext).MakeLower()] = CStringA(buff).MakeLower();
+ }
+ }
+
+ m_mimes[".html"] = "text/html";
+ m_mimes[".txt"] = "text/plain";
+ m_mimes[".css"] = "text/css";
+ m_mimes[".gif"] = "image/gif";
+ m_mimes[".jpeg"] = "image/jpeg";
+ m_mimes[".jpg"] = "image/jpeg";
+ m_mimes[".png"] = "image/png";
+
+ GetModuleFileName(AfxGetInstanceHandle(), str.GetBuffer(MAX_PATH), MAX_PATH);
+ str.ReleaseBuffer();
+ m_webroot = CPath(str);
+ m_webroot.RemoveFileSpec();
+
+ CString WebRoot = AfxGetAppSettings().WebRoot;
+ WebRoot.Replace('/', '\\');
+ WebRoot.Trim();
+ CPath p(WebRoot);
+ if(WebRoot.Find(_T(":\\")) < 0 && WebRoot.Find(_T("\\\\")) < 0) m_webroot.Append(WebRoot);
+ else m_webroot = p;
+ m_webroot.Canonicalize();
+ m_webroot.MakePretty();
+ if(!m_webroot.IsDirectory()) m_webroot = CPath();
+
+ CAtlList<CString> sl;
+ Explode(AfxGetAppSettings().WebServerCGI, sl, ';');
+ POSITION pos = sl.GetHeadPosition();
+ while(pos)
+ {
+ CAtlList<CString> sl2;
+ CString ext = Explode(sl.GetNext(pos), sl2, '=', 2);
+ if(sl2.GetCount() < 2) continue;
+ m_cgi[ext] = sl2.GetTail();
+ }
+
+ m_ThreadId = 0;
+ m_hThread = ::CreateThread(NULL, 0, StaticThreadProc, (LPVOID)this, 0, &m_ThreadId);
+}
+
+CWebServer::~CWebServer()
+{
+ if(m_hThread != NULL)
+ {
+ PostThreadMessage(m_ThreadId, WM_QUIT, 0, 0);
+ WaitForSingleObject(m_hThread, 10000);
+ EXECUTE_ASSERT(CloseHandle(m_hThread));
+ }
+}
+
+DWORD WINAPI CWebServer::StaticThreadProc(LPVOID lpParam)
+{
+ return ((CWebServer*)lpParam)->ThreadProc();
+}
+
+DWORD CWebServer::ThreadProc()
+{
+ if(!AfxSocketInit(NULL))
+ return -1;
+
+ CWebServerSocket s(this, m_nPort);
+
+ MSG msg;
+ while((int)GetMessage(&msg, NULL, 0, 0) > 0)
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return 0;
+}
+
+static void PutFileContents(LPCTSTR fn, const CStringA& data)
+{
+ if(FILE* f = _tfopen(fn, _T("wb")))
+ {
+ fwrite((LPCSTR)data, 1, data.GetLength(), f);
+ fclose(f);
+ }
+}
+
+void CWebServer::Deploy(CString dir)
+{
+ CStringA data;
+ if(LoadResource(IDR_HTML_INDEX, data, RT_HTML)) PutFileContents(dir + _T("index.html"), data);
+ if(LoadResource(IDR_HTML_BROWSER, data, RT_HTML)) PutFileContents(dir + _T("browser.html"), data);
+ if(LoadResource(IDR_HTML_CONTROLS, data, RT_HTML)) PutFileContents(dir + _T("controls.html"), data);
+ if(LoadResource(IDR_HTML_404, data, RT_HTML)) PutFileContents(dir + _T("404.html"), data);
+ if(LoadResource(IDR_HTML_PLAYER, data, RT_HTML)) PutFileContents(dir + _T("player.html"), data);
+
+ POSITION pos = m_downloads.GetStartPosition();
+ while(pos)
+ {
+ CString fn;
+ UINT id;
+ m_downloads.GetNextAssoc(pos, fn, id);
+ if(LoadResource(id, data, _T("FILE")))
+ PutFileContents(dir + fn, data);
+ }
+}
+
+bool CWebServer::ToLocalPath(CString& path, CString& redir)
+{
+ if(!path.IsEmpty() && m_webroot.IsDirectory())
+ {
+ CString str = path;
+ str.Replace('/', '\\');
+ str.TrimLeft('\\');
+
+ CPath p;
+ p.Combine(m_webroot, str);
+ p.Canonicalize();
+
+ if(p.IsDirectory())
+ {
+ CAtlList<CString> sl;
+ Explode(AfxGetAppSettings().WebDefIndex, sl, ';');
+ POSITION pos = sl.GetHeadPosition();
+ while(pos)
+ {
+ str = sl.GetNext(pos);
+ CPath p2 = p;
+ p2.Append(str);
+ if(p2.FileExists())
+ {
+ p = p2;
+ redir = path;
+ if(redir.GetAt(redir.GetLength()-1) != '/') redir += '/';
+ redir += str;
+ break;
+ }
+ }
+ }
+
+ if(_tcslen(p) > _tcslen(m_webroot) && p.FileExists())
+ {
+ path = (LPCTSTR)p;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool CWebServer::LoadPage(UINT resid, CStringA& str, CString path)
+{
+ CString redir;
+ if(ToLocalPath(path, redir))
+ {
+ if(FILE* f = _tfopen(path, _T("rb")))
+ {
+ fseek(f, 0, 2);
+ char* buff = str.GetBufferSetLength(ftell(f));
+ fseek(f, 0, 0);
+ int len = fread(buff, 1, str.GetLength(), f);
+ fclose(f);
+ return len == str.GetLength();
+ }
+ }
+
+ return LoadResource(resid, str, RT_HTML);
+}
+
+void CWebServer::OnAccept(CWebServerSocket* pServer)
+{
+ CAutoPtr<CWebClientSocket> p(new CWebClientSocket(this, m_pMainFrame));
+ if(pServer->Accept(*p))
+ {
+ CString name;
+ UINT port;
+ if(AfxGetAppSettings().fWebServerLocalhostOnly && p->GetPeerName(name, port) && name != _T("127.0.0.1"))
+ {
+ p->Close();
+ return;
+ }
+
+ m_clients.AddTail(p);
+ }
+}
+
+void CWebServer::OnClose(CWebClientSocket* pClient)
+{
+ POSITION pos = m_clients.GetHeadPosition();
+ while(pos)
+ {
+ POSITION cur = pos;
+ if(m_clients.GetNext(pos) == pClient)
+ {
+ m_clients.RemoveAt(cur);
+ break;
+ }
+ }
+}
+
+void CWebServer::OnRequest(CWebClientSocket* pClient, CStringA& hdr, CStringA& body)
+{
+ CPath p(pClient->m_path);
+ CStringA ext = p.GetExtension().MakeLower();
+ CStringA mime;
+ if(ext.IsEmpty()) mime = "text/html";
+ else m_mimes.Lookup(ext, mime);
+
+ hdr = "HTTP/1.0 200 OK\r\n";
+
+ bool fHandled = false, fCGI = false;
+
+ if(!fHandled && m_webroot.IsDirectory())
+ {
+ CStringA tmphdr;
+ fHandled = fCGI = CallCGI(pClient, tmphdr, body, mime);
+
+ if(fHandled)
+ {
+ tmphdr.Replace("\r\n", "\n");
+ CAtlList<CStringA> hdrlines;
+ ExplodeMin(tmphdr, hdrlines, '\n');
+ POSITION pos = hdrlines.GetHeadPosition();
+ while(pos)
+ {
+ POSITION cur = pos;
+ CAtlList<CStringA> sl;
+ CStringA key = Explode(hdrlines.GetNext(pos), sl, ':', 2);
+ if(sl.GetCount() < 2) continue;
+ key.Trim().MakeLower();
+ if(key == "content-type") {mime = sl.GetTail().Trim(); hdrlines.RemoveAt(cur);}
+ else if(key == "content-length") {hdrlines.RemoveAt(cur);}
+ }
+ tmphdr = Implode(hdrlines, '\n');
+ tmphdr.Replace("\n", "\r\n");
+ hdr += tmphdr + "\r\n";
+ }
+ }
+
+ RequestHandler rh = NULL;
+ if(!fHandled && m_internalpages.Lookup(pClient->m_path, rh) && (pClient->*rh)(hdr, body, mime))
+ {
+ if(mime.IsEmpty()) mime = "text/html";
+
+ CString redir;
+ if(pClient->m_get.Lookup(_T("redir"), redir)
+ || pClient->m_post.Lookup(_T("redir"), redir))
+ {
+ if(redir.IsEmpty()) redir = '/';
+
+ hdr =
+ "HTTP/1.0 302 Found\r\n"
+ "Location: " + CStringA(redir) + "\r\n";
+ return;
+ }
+
+ fHandled = true;
+ }
+
+ if(!fHandled && m_webroot.IsDirectory())
+ {
+ fHandled = LoadPage(0, body, pClient->m_path);
+ }
+
+ UINT resid;
+ CStringA res;
+ if(!fHandled && m_downloads.Lookup(pClient->m_path, resid) && LoadResource(resid, res, _T("FILE")))
+ {
+ if(mime.IsEmpty()) mime = "application/octet-stream";
+ memcpy(body.GetBufferSetLength(res.GetLength()), res.GetBuffer(), res.GetLength());
+ fHandled = true;
+ }
+
+ if(!fHandled)
+ {
+ hdr = mime == "text/html"
+ ? "HTTP/1.0 301 Moved Permanently\r\n" "Location: /404.html\r\n"
+ : "HTTP/1.0 404 Not Found\r\n";
+ return;
+ }
+
+ if(mime == "text/html" && !fCGI)
+ {
+ hdr +=
+ "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n"
+ "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n"
+ "Pragma: no-cache\r\n";
+
+ CStringA debug;
+ if(AfxGetAppSettings().fWebServerPrintDebugInfo)
+ {
+ debug += "<hr>\r\n";
+ CString key, value;
+ POSITION pos;
+ pos = pClient->m_hdrlines.GetStartPosition();
+ while(pos) {pClient->m_hdrlines.GetNextAssoc(pos, key, value); debug += "HEADER[" + key + "] = " + value + "<br>\r\n";}
+ debug += "cmd: " + pClient->m_cmd + "<br>\r\n";
+ debug += "path: " + pClient->m_path + "<br>\r\n";
+ debug += "ver: " + pClient->m_ver + "<br>\r\n";
+ pos = pClient->m_get.GetStartPosition();
+ while(pos) {pClient->m_get.GetNextAssoc(pos, key, value); debug += "GET[" + key + "] = " + value + "<br>\r\n";}
+ pos = pClient->m_post.GetStartPosition();
+ while(pos) {pClient->m_post.GetNextAssoc(pos, key, value); debug += "POST[" + key + "] = " + value + "<br>\r\n";}
+ pos = pClient->m_cookie.GetStartPosition();
+ while(pos) {pClient->m_cookie.GetNextAssoc(pos, key, value); debug += "COOKIE[" + key + "] = " + value + "<br>\r\n";}
+ pos = pClient->m_request.GetStartPosition();
+ while(pos) {pClient->m_request.GetNextAssoc(pos, key, value); debug += "REQUEST[" + key + "] = " + value + "<br>\r\n";}
+ }
+
+ body.Replace("[path]", CStringA(pClient->m_path));
+ body.Replace("[indexpath]", "/index.html");
+ body.Replace("[commandpath]", "/command.html");
+ body.Replace("[browserpath]", "/browser.html");
+ body.Replace("[controlspath]", "/controls.html");
+ body.Replace("[wmcname]", "wm_command");
+ body.Replace("[setposcommand]", CMD_SETPOS);
+ body.Replace("[setvolumecommand]", CMD_SETVOLUME);
+ body.Replace("[debug]", debug);
+ // TODO: add more general tags to replace
+ }
+
+ // gzip
+ if(AfxGetAppSettings().fWebServerUseCompression && hdr.Find("Content-Encoding:") < 0)
+ do
+ {
+ CString accept_encoding;
+ pClient->m_hdrlines.Lookup(_T("accept-encoding"), accept_encoding);
+ accept_encoding.MakeLower();
+ CAtlList<CString> sl;
+ ExplodeMin(accept_encoding, sl, ',');
+ if(!sl.Find(_T("gzip"))) break;;
+
+ CHAR path[MAX_PATH], fn[MAX_PATH];
+ if(!GetTempPathA(MAX_PATH, path) || !GetTempFileNameA(path, "mpc_gz", 0, fn))
+ break;
+
+ gzFile gf = gzopen(fn, "wb9");
+ if(!gf || gzwrite(gf, (LPVOID)(LPCSTR)body, body.GetLength()) != body.GetLength())
+ {
+ if(gf) gzclose(gf);
+ DeleteFileA(fn);
+ break;
+ }
+ gzclose(gf);
+
+ FILE* f = fopen(fn, "rb");
+ if(!f) {DeleteFileA(fn); break;}
+ fseek(f, 0, 2);
+ CHAR* s = body.GetBufferSetLength(ftell(f));
+ fseek(f, 0, 0);
+ int len = fread(s, 1, body.GetLength(), f);
+ ASSERT(len == body.GetLength());
+ fclose(f);
+ DeleteFileA(fn);
+
+ hdr += "Content-Encoding: gzip\r\n";
+ }
+ while(0);
+
+ CStringA content;
+ content.Format(
+ "Content-Type: %s\r\n"
+ "Content-Length: %d\r\n",
+ mime, body.GetLength());
+ hdr += content;
+}
+
+static DWORD WINAPI KillCGI(LPVOID lParam)
+{
+ HANDLE hProcess = (HANDLE)lParam;
+ if(WaitForSingleObject(hProcess, 30000) == WAIT_TIMEOUT)
+ TerminateProcess(hProcess, 0);
+ return 0;
+}
+
+bool CWebServer::CallCGI(CWebClientSocket* pClient, CStringA& hdr, CStringA& body, CStringA& mime)
+{
+ CString path = pClient->m_path, redir = path;
+ if(!ToLocalPath(path, redir)) return false;
+ CString ext = CPath(path).GetExtension().MakeLower();
+ CPath dir(path);
+ dir.RemoveFileSpec();
+
+ CString cgi;
+ if(!m_cgi.Lookup(ext, cgi) || !CPath(cgi).FileExists())
+ return false;
+
+ HANDLE hProcess = GetCurrentProcess();
+ HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup = NULL;
+ HANDLE hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup = NULL;
+
+ SECURITY_ATTRIBUTES saAttr;
+ ZeroMemory(&saAttr, sizeof(saAttr));
+ saAttr.nLength = sizeof(saAttr);
+ saAttr.bInheritHandle = TRUE;
+
+ if(CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
+ {
+ BOOL fSuccess = DuplicateHandle(hProcess, hChildStdoutRd, hProcess, &hChildStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
+ CloseHandle(hChildStdoutRd);
+ }
+
+ if(CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
+ {
+ BOOL fSuccess = DuplicateHandle(hProcess, hChildStdinWr, hProcess, &hChildStdinWrDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
+ CloseHandle(hChildStdinWr);
+ }
+
+ STARTUPINFO siStartInfo;
+ ZeroMemory(&siStartInfo, sizeof(siStartInfo));
+ siStartInfo.cb = sizeof(siStartInfo);
+ siStartInfo.hStdError = hChildStdoutWr;
+ siStartInfo.hStdOutput = hChildStdoutWr;
+ siStartInfo.hStdInput = hChildStdinRd;
+ siStartInfo.dwFlags |= STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
+ siStartInfo.wShowWindow = SW_HIDE;
+
+ PROCESS_INFORMATION piProcInfo;
+ ZeroMemory(&piProcInfo, sizeof(piProcInfo));
+
+ CStringA envstr;
+
+ if(LPVOID lpvEnv = GetEnvironmentStrings())
+ {
+ CString str;
+
+ CAtlList<CString> env;
+ for(LPTSTR lpszVariable = (LPTSTR)lpvEnv; *lpszVariable; lpszVariable += _tcslen(lpszVariable)+1)
+ if(lpszVariable != (LPTSTR)lpvEnv)
+ env.AddTail(lpszVariable);
+
+ env.AddTail(_T("GATEWAY_INTERFACE=CGI/1.1"));
+ env.AddTail(_T("SERVER_SOFTWARE=Media Player Classic/6.4.x.y"));
+ env.AddTail(_T("SERVER_PROTOCOL=") + pClient->m_ver);
+ env.AddTail(_T("REQUEST_METHOD=") + pClient->m_cmd);
+ env.AddTail(_T("PATH_INFO=") + redir);
+ env.AddTail(_T("PATH_TRANSLATED=") + path);
+ env.AddTail(_T("SCRIPT_NAME=") + redir);
+ env.AddTail(_T("QUERY_STRING=") + pClient->m_query);
+
+ if(pClient->m_hdrlines.Lookup(_T("content-type"), str))
+ env.AddTail(_T("CONTENT_TYPE=") + str);
+ if(pClient->m_hdrlines.Lookup(_T("content-length"), str))
+ env.AddTail(_T("CONTENT_LENGTH=") + str);
+
+ POSITION pos = pClient->m_hdrlines.GetStartPosition();
+ while(pos)
+ {
+ CString key = pClient->m_hdrlines.GetKeyAt(pos);
+ CString value = pClient->m_hdrlines.GetNextValue(pos);
+ key.Replace(_T("-"), _T("_"));
+ key.MakeUpper();
+ env.AddTail(_T("HTTP_") + key + _T("=") + value);
+ }
+
+ CString name;
+ UINT port;
+
+ if(pClient->GetPeerName(name, port))
+ {
+ str.Format(_T("%d"), port);
+ env.AddTail(_T("REMOTE_ADDR=")+name);
+ env.AddTail(_T("REMOTE_HOST=")+name);
+ env.AddTail(_T("REMOTE_PORT=")+str);
+ }
+
+ if(pClient->GetSockName(name, port))
+ {
+ str.Format(_T("%d"), port);
+ env.AddTail(_T("SERVER_NAME=")+name);
+ env.AddTail(_T("SERVER_PORT=")+str);
+ }
+
+ env.AddTail(_T("\0"));
+
+ str = Implode(env, '\0');
+ envstr = CStringA(str, str.GetLength());
+
+ FreeEnvironmentStrings((LPTSTR)lpvEnv);
+ }
+
+ TCHAR* cmdln = new TCHAR[32768];
+ _sntprintf(cmdln, 32768, _T("\"%s\" \"%s\""), cgi, path);
+
+ if(hChildStdinRd && hChildStdoutWr)
+ if(CreateProcess(
+ NULL, cmdln, NULL, NULL, TRUE, 0,
+ envstr.GetLength() ? (LPVOID)(LPCSTR)envstr : NULL,
+ dir, &siStartInfo, &piProcInfo))
+ {
+ DWORD ThreadId;
+ CreateThread(NULL, 0, KillCGI, (LPVOID)piProcInfo.hProcess, 0, &ThreadId);
+
+ static const int BUFFSIZE = 1024;
+ DWORD dwRead, dwWritten = 0;
+
+ int i = 0, len = pClient->m_data.GetLength();
+ for(; i < len; i += dwWritten)
+ if(!WriteFile(hChildStdinWrDup, (LPCSTR)pClient->m_data + i, min(len - i, BUFFSIZE), &dwWritten, NULL))
+ break;
+
+ CloseHandle(hChildStdinWrDup);
+ CloseHandle(hChildStdoutWr);
+
+ body.Empty();
+
+ CStringA buff;
+ while(i == len && ReadFile(hChildStdoutRdDup, buff.GetBuffer(BUFFSIZE), BUFFSIZE, &dwRead, NULL) && dwRead)
+ {
+ buff.ReleaseBufferSetLength(dwRead);
+ body += buff;
+ }
+
+ int hdrend = body.Find("\r\n\r\n");
+ if(hdrend >= 0)
+ {
+ hdr = body.Left(hdrend+2);
+ body = body.Mid(hdrend+4);
+ }
+
+ CloseHandle(hChildStdinRd);
+ CloseHandle(hChildStdoutRdDup);
+
+ CloseHandle(piProcInfo.hProcess);
+ CloseHandle(piProcInfo.hThread);
+ }
+ else
+ {
+ body = _T("CGI Error");
+ }
+
+ delete [] cmdln;
+
+ return true;
+}
diff --git a/src/apps/mplayerc/WebServer.h b/src/apps/mplayerc/WebServer.h
new file mode 100644
index 000000000..9518f498c
--- /dev/null
+++ b/src/apps/mplayerc/WebServer.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#include <afxsock.h>
+#include <atlcoll.h>
+
+#define UTF8(str) UTF16To8(TToW(str))
+#define UTF8Arg(str) UrlEncode(UTF8(str))
+
+#define CMD_SETPOS "-1"
+#define CMD_SETVOLUME "-2"
+
+
+class CWebServerSocket;
+class CWebClientSocket;
+class CMainFrame;
+
+class CWebServer
+{
+ CMainFrame* m_pMainFrame;
+ int m_nPort;
+
+ DWORD ThreadProc();
+ static DWORD WINAPI StaticThreadProc(LPVOID lpParam);
+ DWORD m_ThreadId;
+ HANDLE m_hThread;
+
+ CAutoPtrList<CWebClientSocket> m_clients;
+
+ typedef bool (CWebClientSocket::*RequestHandler)(CStringA& hdr, CStringA& body, CStringA& mime);
+ static CAtlStringMap<RequestHandler> m_internalpages;
+ static CAtlStringMap<UINT> m_downloads;
+ static CAtlStringMap<CStringA, CStringA> m_mimes;
+ CPath m_webroot;
+
+ CAtlStringMap<> m_cgi;
+ bool CallCGI(CWebClientSocket* pClient, CStringA& hdr, CStringA& body, CStringA& mime);
+
+public:
+ CWebServer(CMainFrame* pMainFrame, int nPort = 13579);
+ virtual ~CWebServer();
+
+ static void Deploy(CString dir);
+
+ bool ToLocalPath(CString& path, CString& redir);
+ bool LoadPage(UINT resid, CStringA& str, CString path = _T(""));
+
+ void OnAccept(CWebServerSocket* pServer);
+ void OnClose(CWebClientSocket* pClient);
+ void OnRequest(CWebClientSocket* pClient, CStringA& reshdr, CStringA& resbody);
+};
diff --git a/src/apps/mplayerc/WebServerSocket.cpp b/src/apps/mplayerc/WebServerSocket.cpp
new file mode 100644
index 000000000..ab2ab5710
--- /dev/null
+++ b/src/apps/mplayerc/WebServerSocket.cpp
@@ -0,0 +1,22 @@
+#include "stdafx.h"
+#include ".\webserver.h"
+#include ".\webserversocket.h"
+
+CWebServerSocket::CWebServerSocket(CWebServer* pWebServer, int port)
+ : m_pWebServer(pWebServer)
+{
+ Create(port);
+ Listen();
+}
+
+CWebServerSocket::~CWebServerSocket()
+{
+}
+
+void CWebServerSocket::OnAccept(int nErrorCode)
+{
+ if(nErrorCode == 0 && m_pWebServer)
+ m_pWebServer->OnAccept(this);
+
+ __super::OnAccept(nErrorCode);
+}
diff --git a/src/apps/mplayerc/WebServerSocket.h b/src/apps/mplayerc/WebServerSocket.h
new file mode 100644
index 000000000..e7737960d
--- /dev/null
+++ b/src/apps/mplayerc/WebServerSocket.h
@@ -0,0 +1,15 @@
+#pragma once
+
+class CWebServer;
+
+class CWebServerSocket : public CAsyncSocket
+{
+ CWebServer* m_pWebServer;
+
+protected:
+ void OnAccept(int nErrorCode);
+
+public:
+ CWebServerSocket(CWebServer* pWebServer, int port = 13579);
+ virtual ~CWebServerSocket();
+}; \ No newline at end of file
diff --git a/src/apps/mplayerc/jpeg.cpp b/src/apps/mplayerc/jpeg.cpp
new file mode 100644
index 000000000..0ea2172e5
--- /dev/null
+++ b/src/apps/mplayerc/jpeg.cpp
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * - a simple baseline encoder
+ * - created exactly after the specs
+ * - no optimization or anything like that :)
+ *
+ */
+
+
+#include "stdafx.h"
+#include <math.h>
+#include "jpeg.h"
+#include "jpeg_tables.h"
+
+bool CJpegEncoder::PutBit(int b, int n)
+{
+ if(n > 24 || n <= 0) return(false);
+
+ m_bbuff <<= n;
+ m_bbuff |= b & ((1 << n) - 1);
+ m_bwidth += n;
+
+ while(m_bwidth >= 8)
+ {
+ BYTE c = (BYTE)(m_bbuff >> (m_bwidth - 8));
+ PutByte(c);
+ if(c == 0xff) PutByte(0);
+ m_bwidth -= 8;
+ }
+
+ return(true);
+}
+
+void CJpegEncoder::Flush()
+{
+ if(m_bwidth > 0)
+ {
+ BYTE c = m_bbuff << (8 - m_bwidth);
+ PutByte(c);
+ if(c == 0xff) PutByte(0);
+ }
+
+ m_bbuff = m_bwidth = 0;
+}
+
+///////
+
+int CJpegEncoder::GetBitWidth(short q)
+{
+ if(q == 0) return(0);
+ if(q < 0) q = -q;
+
+ int width = 15;
+ for(; !(q&0x4000); q <<= 1, width--);
+ return(width);
+}
+
+///////
+
+void CJpegEncoder::WriteSOI()
+{
+ PutByte(0xff);
+ PutByte(0xd8);
+}
+
+void CJpegEncoder::WriteDQT()
+{
+ PutByte(0xff);
+ PutByte(0xdb);
+
+ WORD size = 2 + 2*(65 + 64*0);
+ PutByte(size>>8);
+ PutByte(size&0xff);
+
+ for(int c = 0; c < 2; c++)
+ {
+ PutByte(c);
+ PutBytes(quanttbl[c], 64);
+ }
+}
+
+void CJpegEncoder::WriteSOF0()
+{
+ PutByte(0xff);
+ PutByte(0xc0);
+
+ WORD size = 8 + 3*ColorComponents;
+ PutByte(size>>8);
+ PutByte(size&0xff);
+
+ PutByte(8); // precision
+
+ PutByte(m_h>>8);
+ PutByte(m_h&0xff);
+ PutByte(m_w>>8);
+ PutByte(m_w&0xff);
+
+ PutByte(ColorComponents); // color components
+
+ PutByte(1); // component id
+ PutByte(0x11); // hor | ver sampling factor
+ PutByte(0); // quant. tbl. id
+
+ PutByte(2); // component id
+ PutByte(0x11); // hor | ver sampling factor
+ PutByte(1); // quant. tbl. id
+
+ PutByte(3); // component id
+ PutByte(0x11); // hor | ver sampling factor
+ PutByte(1); // quant. tbl. id
+}
+
+void CJpegEncoder::WriteDHT()
+{
+ PutByte(0xff);
+ PutByte(0xc4);
+
+ WORD size = 0x01A2; // 2 + n*(17+mi);
+ PutByte(size>>8);
+ PutByte(size&0xff);
+
+ PutByte(0x00); // tbl class (DC) | tbl id
+ PutBytes(DCVLC_NumByLength[0], 16);
+ for(int i = 0; i < 12; i++) PutByte(i);
+
+ PutByte(0x01); // tbl class (DC) | tbl id
+ PutBytes(DCVLC_NumByLength[1], 16);
+ for(int i = 0; i < 12; i++) PutByte(i);
+
+ PutByte(0x10); // tbl class (AC) | tbl id
+ PutBytes(ACVLC_NumByLength[0], 16);
+ PutBytes(ACVLC_Data[0], sizeof(ACVLC_Data[0]));
+
+ PutByte(0x11); // tbl class (AC) | tbl id
+ PutBytes(ACVLC_NumByLength[1], 16);
+ PutBytes(ACVLC_Data[1], sizeof(ACVLC_Data[1]));
+}
+
+// float(1.0 / sqrt(2.0))
+#define invsq2 0.70710678118654f
+#define PI 3.14159265358979
+
+void CJpegEncoder::WriteSOS()
+{
+ PutByte(0xff);
+ PutByte(0xda);
+
+ WORD size = 6 + 2*ColorComponents;
+ PutByte(size>>8);
+ PutByte(size&0xff);
+
+ PutByte(ColorComponents); // color components: 3
+
+ PutByte(1); // component id
+ PutByte(0x00); // DC | AC huff tbl
+
+ PutByte(2); // component id
+ PutByte(0x11); // DC | AC huff tbl
+
+ PutByte(3); // component id
+ PutByte(0x11); // DC | AC huff tbl
+
+ PutByte(0); // ss, first AC
+ PutByte(63); // se, last AC
+
+ PutByte(0); // ah | al
+
+ static float cosuv[8][8][8][8];
+
+ // oh yeah, we don't need no fast dct :)
+ for(int v = 0; v < 8; v++)
+ for(int u = 0; u < 8; u++)
+ for(int j = 0; j < 8; j++)
+ for(int i = 0; i < 8; i++)
+ cosuv[v][u][j][i] = (float)(cos((2*i+1)*u*PI/16) * cos((2*j+1)*v*PI/16));
+
+ int prevDC[3] = {0, 0, 0};
+
+ for(int y = 0; y < m_h; y += 8)
+ {
+ int jj = min(m_h - y, 8);
+
+ for(int x = 0; x < m_w; x += 8)
+ {
+ int ii = min(m_w - x, 8);
+
+ for(int c = 0; c < ColorComponents; c++)
+ {
+ int cc = !!c;
+
+ int ACs = 0;
+
+ static short block[64];
+
+ for(int zigzag = 0; zigzag < 64; zigzag++)
+ {
+ BYTE u = zigzagU[zigzag];
+ BYTE v = zigzagV[zigzag];
+
+ float F = 0;
+/*
+ for(int j = 0; j < jj; j++)
+ for(int i = 0; i < ii; i++)
+ F += (signed char)m_p[((y+j)*m_w + (x+i))*4 + c] * cosuv[v][u][j][i];
+*/
+ for(int j = 0; j < jj; j++)
+ {
+ signed char* p = (signed char*)&m_p[((y+j)*m_w + x)*4 + c];
+ for(int i = 0; i < ii; i++, p += 4)
+ F += *p * cosuv[v][u][j][i];
+ }
+
+ float cu = !u ? invsq2 : 1.0f;
+ float cv = !v ? invsq2 : 1.0f;
+
+ block[zigzag] = short(2.0 / 8.0 * cu * cv * F) / quanttbl[cc][zigzag];
+ }
+
+ short DC = block[0] - prevDC[c];
+ prevDC[c] = block[0];
+
+ int size = GetBitWidth(DC);
+ PutBit(DCVLC[cc][size], DCVLC_Size[cc][size]);
+
+ if(DC < 0) DC = DC - 1;
+ PutBit(DC, size);
+
+ int j;
+ for(j = 64; j > 1 && !block[j-1]; j--);
+
+ for(int i = 1; i < j; i++)
+ {
+ short AC = block[i];
+
+ if(AC == 0)
+ {
+ if(++ACs == 16)
+ {
+ PutBit(ACVLC[cc][15][0], ACVLC_Size[cc][15][0]);
+ ACs = 0;
+ }
+ }
+ else
+ {
+ int size = GetBitWidth(AC);
+ PutBit(ACVLC[cc][ACs][size], ACVLC_Size[cc][ACs][size]);
+
+ if(AC < 0) AC--;
+ PutBit(AC, size);
+
+ ACs = 0;
+ }
+ }
+
+ if(j < 64) PutBit(ACVLC[cc][0][0], ACVLC_Size[cc][0][0]);
+ }
+ }
+ }
+
+ Flush();
+}
+
+void CJpegEncoder::WriteEOI()
+{
+ PutByte(0xff);
+ PutByte(0xd9);
+}
+
+//
+
+CJpegEncoder::CJpegEncoder()
+{
+}
+
+bool CJpegEncoder::Encode(const BYTE* dib)
+{
+ m_bbuff = m_bwidth = 0;
+
+ BITMAPINFO* bi = (BITMAPINFO*)dib;
+
+ int bpp = bi->bmiHeader.biBitCount;
+
+ if(bpp != 16 && bpp != 24 && bpp != 32) // 16 & 24 not tested!!! there may be some alignment problems when the row size is not 4*something in bytes
+ return false;
+
+ m_w = bi->bmiHeader.biWidth;
+ m_h = abs(bi->bmiHeader.biHeight);
+ m_p = new BYTE[m_w*m_h*4];
+
+ const BYTE* src = dib + sizeof(bi->bmiHeader);
+ if(bi->bmiHeader.biBitCount <= 8)
+ {
+ if(bi->bmiHeader.biClrUsed) src += bi->bmiHeader.biClrUsed * sizeof(bi->bmiColors[0]);
+ else src += (1 << bi->bmiHeader.biBitCount) * sizeof(bi->bmiColors[0]);
+ }
+
+ int srcpitch = m_w*(bpp>>3);
+ int dstpitch = m_w*4;
+
+ BitBltFromRGBToRGB(
+ m_w, m_h,
+ m_p, dstpitch, 32,
+ (BYTE*)src + srcpitch*(m_h-1), -srcpitch, bpp);
+
+ BYTE* p = m_p;
+ for(BYTE* e = p + m_h*dstpitch; p < e; p += 4)
+ {
+ int r = p[2], g = p[1], b = p[0];
+
+ p[0] = (BYTE)min(max(0.2990*r+0.5870*g+0.1140*b, 0), 255) - 128;
+ p[1] = (BYTE)min(max(-0.1687*r-0.3313*g+0.5000*b + 128, 0), 255) - 128;
+ p[2] = (BYTE)min(max(0.5000*r-0.4187*g-0.0813*b + 128, 0), 255) - 128;
+ }
+
+ if(quanttbl[0][0] == 16)
+ {
+ for(int i = 0; i < countof(quanttbl); i++)
+ for(int j = 0; j < countof(quanttbl[0]); j++)
+ quanttbl[i][j] >>= 2; // the default quantization table contains a little too large values
+ }
+
+ WriteSOI();
+ WriteDQT();
+ WriteSOF0();
+ WriteDHT();
+ WriteSOS();
+ WriteEOI();
+
+ delete [] m_p;
+
+ return true;
+}
+
+//////////
+
+CJpegEncoderFile::CJpegEncoderFile(LPCTSTR fn)
+{
+ m_fn = fn;
+ m_file = NULL;
+}
+
+bool CJpegEncoderFile::PutByte(BYTE b)
+{
+ return fputc(b, m_file) != EOF;
+}
+
+bool CJpegEncoderFile::PutBytes(const void* pData, int len)
+{
+ return fwrite(pData, 1, len, m_file) == len;
+}
+
+bool CJpegEncoderFile::Encode(const BYTE* dib)
+{
+ if(!(m_file = _tfopen(m_fn, _T("wb")))) return false;
+ bool ret = __super::Encode(dib);
+ fclose(m_file);
+ m_file = NULL;
+ return ret;
+}
+
+//////////
+
+CJpegEncoderMem::CJpegEncoderMem()
+{
+}
+
+bool CJpegEncoderMem::PutByte(BYTE b)
+{
+ m_pdata->Add(b); // yeah... a bit unbuffered, for now
+ return true;
+}
+
+bool CJpegEncoderMem::PutBytes(const void* pData, int len)
+{
+ CAtlArray<BYTE> moredata;
+ moredata.SetCount(len);
+ memcpy(moredata.GetData(), pData, len);
+ m_pdata->Append(moredata);
+ return true;
+}
+
+bool CJpegEncoderMem::Encode(const BYTE* dib, CAtlArray<BYTE>& data)
+{
+ m_pdata = &data;
+ return __super::Encode(dib);
+}
+
diff --git a/src/apps/mplayerc/jpeg.h b/src/apps/mplayerc/jpeg.h
new file mode 100644
index 000000000..932da80fd
--- /dev/null
+++ b/src/apps/mplayerc/jpeg.h
@@ -0,0 +1,59 @@
+#pragma once
+
+class CJpegEncoder
+{
+ static const int ColorComponents = 3;
+
+ int m_w, m_h;
+ BYTE* m_p;
+
+ unsigned int m_bbuff, m_bwidth;
+ bool PutBit(int b, int n);
+ void Flush();
+ int GetBitWidth(short q);
+
+ void WriteSOI();
+ void WriteDQT();
+ void WriteSOF0();
+ void WriteDHT();
+ void WriteSOS();
+ void WriteEOI();
+
+protected:
+ virtual bool PutByte(BYTE b) = 0;
+ virtual bool PutBytes(const void* pData, int len) = 0;
+ virtual bool Encode(const BYTE* dib);
+
+public:
+ CJpegEncoder();
+};
+
+class CJpegEncoderFile : public CJpegEncoder
+{
+ CString m_fn;
+ FILE* m_file;
+
+protected:
+ bool PutByte(BYTE b);
+ bool PutBytes(const void* pData, int len);
+
+public:
+ CJpegEncoderFile(LPCTSTR fn);
+
+ bool Encode(const BYTE* dib);
+};
+
+class CJpegEncoderMem : public CJpegEncoder
+{
+ CAtlArray<BYTE>* m_pdata;
+
+protected:
+ bool PutByte(BYTE b);
+ bool PutBytes(const void* pData, int len);
+
+public:
+ CJpegEncoderMem();
+
+ bool Encode(const BYTE* dib, CAtlArray<BYTE>& data);
+};
+
diff --git a/src/apps/mplayerc/jpeg_tables.h b/src/apps/mplayerc/jpeg_tables.h
new file mode 100644
index 000000000..df01d3f67
--- /dev/null
+++ b/src/apps/mplayerc/jpeg_tables.h
@@ -0,0 +1,233 @@
+#pragma once
+
+/* Tables */
+
+static unsigned char quanttbl[2][64] =
+{
+ {
+ 16,
+ 11, 12,
+ 14, 12, 10,
+ 16, 14, 13, 14,
+ 18, 17, 16, 19, 24,
+ 40, 26, 24, 22, 22, 24,
+ 49, 35, 37, 29, 40, 58, 51,
+ 61, 30, 57, 51, 56, 55, 64, 72,
+ 92, 78, 64, 68, 87, 69, 55,
+ 56, 80, 109, 81, 87, 95,
+ 98, 103, 104, 103, 62,
+ 77, 113, 121, 112,
+ 100, 120, 92,
+ 101, 103,
+ 99
+ },
+ {
+ 17,
+ 18, 18,
+ 24, 21, 24,
+ 47, 26, 26, 47,
+ 99, 66, 56, 66, 99,
+ 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99,
+ 99, 99, 99, 99,
+ 99, 99, 99,
+ 99, 99,
+ 99
+ }
+};
+
+static unsigned char zigzagU[64] =
+{
+ 0,
+ 1, 0,
+ 0, 1, 2,
+ 3, 2, 1, 0,
+ 0, 1, 2, 3, 4,
+ 5, 4, 3, 2, 1, 0,
+ 0, 1, 2, 3, 4, 5, 6,
+ 7, 6, 5, 4, 3, 2, 1, 0,
+ 1, 2, 3, 4, 5, 6, 7,
+ 7, 6, 5, 4, 3, 2,
+ 3, 4, 5, 6, 7,
+ 7, 6, 5, 4,
+ 5, 6, 7,
+ 7, 6,
+ 7,
+};
+
+static unsigned char zigzagV[64] =
+{
+ 0,
+ 0, 1,
+ 2, 1, 0,
+ 0, 1, 2, 3,
+ 4, 3, 2, 1, 0,
+ 0, 1, 2, 3, 4, 5,
+ 6, 5, 4, 3, 2, 1, 0,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 7, 6, 5, 4, 3, 2, 1,
+ 2, 3, 4, 5, 6, 7,
+ 7, 6, 5, 4, 3,
+ 4, 5, 6, 7,
+ 7, 6, 5,
+ 6, 7,
+ 7,
+};
+
+static unsigned short DCVLC[2][12] =
+{
+ {0, 2, 3, 4, 5, 6, 14, 30, 62, 126, 254, 510},
+ {0, 1, 2, 6, 14, 30, 62, 126, 254, 510, 1022, 2046}
+};
+
+static unsigned char DCVLC_Size[2][12] =
+{
+ {2, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 9},
+ {2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
+};
+
+static unsigned char DCVLC_NumByLength[2][16] =
+{
+ {0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+};
+
+static unsigned short ACVLC[2][16][11] =
+{
+ {
+ {10, 0, 1, 4, 11, 26, 120, 248, 1014, 65410, 65410},
+ {0, 12, 27, 121, 502, 2038, 65412, 65413, 65414, 65415, 65416},
+ {0, 28, 249, 1015, 4084, 65417, 65418, 65419, 65420, 65421, 65422},
+ {0, 58, 503, 8181, 65423, 65424, 65425, 65426, 65427, 65428, 65429},
+ {0, 59, 1016, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437},
+ {0, 122, 2039, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445},
+ {0, 123, 4086, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453},
+ {0, 250, 4087, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461},
+ {0, 504, 32704, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469},
+ {0, 505, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478},
+ {0, 506, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487},
+ {0, 1017, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496},
+ {0, 1018, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505},
+ {0, 2040, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514},
+ {0, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524},
+ {2041, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534}
+ },
+ {
+ {0, 1, 4, 10, 24, 25, 56, 120, 500, 1014, 4084},
+ {0, 11, 57, 246, 501, 2038, 4085, 65416, 65417, 65418, 65419},
+ {0, 26, 247, 1015, 4086, 32706, 65420, 65421, 65422, 65423, 65424},
+ {0, 27, 248, 1016, 4087, 65425, 65426, 65427, 65428, 65429, 65430},
+ {0, 58, 502, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438},
+ {0, 59, 1017, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446},
+ {0, 121, 2039, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454},
+ {0, 122, 2040, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462},
+ {0, 249, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471},
+ {0, 503, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480},
+ {0, 504, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489},
+ {0, 505, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498},
+ {0, 506, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507},
+ {0, 2041, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516},
+ {0, 16352, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525},
+ {1018, 32707, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534}
+ }
+};
+
+static unsigned char ACVLC_Size[2][16][11] =
+{
+ {
+ {4, 2, 2, 3, 4, 5, 7, 8, 10, 16, 16},
+ {0, 4, 5, 7, 9, 11, 16, 16, 16, 16, 16},
+ {0, 5, 8, 10, 12, 16, 16, 16, 16, 16, 16},
+ {0, 6, 9, 12, 16, 16, 16, 16, 16, 16, 16},
+ {0, 6, 10, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 7, 11, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 7, 12, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 8, 12, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 9, 15, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 10, 16, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 10, 16, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16},
+ {11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}
+ },
+ {
+ {2, 2, 3, 4, 5, 5, 6, 7, 9, 10, 12},
+ {0, 4, 6, 8, 9, 11, 12, 16, 16, 16, 16},
+ {0, 5, 8, 10, 12, 15, 16, 16, 16, 16, 16},
+ {0, 5, 8, 10, 12, 16, 16, 16, 16, 16, 16},
+ {0, 6, 9, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 6, 10, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 7, 11, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 7, 11, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16},
+ {0, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16},
+ {10, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16}
+ }
+};
+
+static unsigned char ACVLC_NumByLength[2][16] =
+{
+ {0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125},
+ {0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119}
+};
+
+static unsigned char ACVLC_Data[2][162] =
+{
+ {
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+ 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+ 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08,
+ 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0,
+ 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16,
+ 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+ 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
+ 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5,
+ 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4,
+ 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
+ 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
+ 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
+ 0xF9, 0xFA
+ },
+ {
+ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+ 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+ 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+ 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0,
+ 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34,
+ 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26,
+ 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38,
+ 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+ 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+ 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5,
+ 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4,
+ 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3,
+ 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2,
+ 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
+ 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
+ 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
+ 0xF9, 0xFA
+ }
+};
diff --git a/src/apps/mplayerc/mplayerc.aps b/src/apps/mplayerc/mplayerc.aps
new file mode 100644
index 000000000..3c8e62ccf
--- /dev/null
+++ b/src/apps/mplayerc/mplayerc.aps
Binary files differ
diff --git a/src/apps/mplayerc/mplayerc.cpp b/src/apps/mplayerc/mplayerc.cpp
new file mode 100644
index 000000000..3e92220a4
--- /dev/null
+++ b/src/apps/mplayerc/mplayerc.cpp
@@ -0,0 +1,2408 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// mplayerc.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "mplayerc.h"
+#include <atlsync.h>
+#include <Tlhelp32.h>
+#include "MainFrm.h"
+#include "..\..\DSUtil\DSUtil.h"
+
+/////////
+
+void CorrectComboListWidth(CComboBox& box, CFont* pWndFont)
+{
+ int cnt = box.GetCount();
+ if(cnt <= 0) return;
+
+ CDC* pDC = box.GetDC();
+ pDC->SelectObject(pWndFont);
+
+ int maxw = box.GetDroppedWidth();
+
+ for(int i = 0; i < cnt; i++)
+ {
+ CString str;
+ box.GetLBText(i, str);
+ int w = pDC->GetTextExtent(str).cx + 22;
+ if(maxw < w) maxw = w;
+ }
+
+ box.ReleaseDC(pDC);
+
+ box.SetDroppedWidth(maxw);
+}
+
+HICON LoadIcon(CString fn, bool fSmall)
+{
+ if(fn.IsEmpty()) return(NULL);
+
+ CString ext = fn.Left(fn.Find(_T("://"))+1).TrimRight(':');
+ if(ext.IsEmpty() || !ext.CompareNoCase(_T("file")))
+ ext = _T(".") + fn.Mid(fn.ReverseFind('.')+1);
+
+ CSize size(fSmall?16:32,fSmall?16:32);
+
+ if(!ext.CompareNoCase(_T(".ifo")))
+ {
+ if(HICON hIcon = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_DVD), IMAGE_ICON, size.cx, size.cy, 0))
+ return(hIcon);
+ }
+
+ if(!ext.CompareNoCase(_T(".cda")))
+ {
+ if(HICON hIcon = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_AUDIOCD), IMAGE_ICON, size.cx, size.cy, 0))
+ return(hIcon);
+ }
+
+ do
+ {
+ CRegKey key;
+
+ TCHAR buff[256];
+ ULONG len;
+
+ if(ERROR_SUCCESS != key.Open(HKEY_CLASSES_ROOT, ext + _T("\\DefaultIcon"), KEY_READ))
+ {
+ if(ERROR_SUCCESS != key.Open(HKEY_CLASSES_ROOT, ext, KEY_READ))
+ break;
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+ if(ERROR_SUCCESS != key.QueryStringValue(NULL, buff, &len) || (ext = buff).Trim().IsEmpty())
+ break;
+
+ if(ERROR_SUCCESS != key.Open(HKEY_CLASSES_ROOT, ext + _T("\\DefaultIcon"), KEY_READ))
+ break;
+ }
+
+ CString icon;
+
+ len = sizeof(buff);
+ memset(buff, 0, len);
+ if(ERROR_SUCCESS != key.QueryStringValue(NULL, buff, &len) || (icon = buff).Trim().IsEmpty())
+ break;
+
+ int i = icon.ReverseFind(',');
+ if(i < 0) break;
+
+ int id = 0;
+ if(_stscanf(icon.Mid(i+1), _T("%d"), &id) != 1)
+ break;
+
+ icon = icon.Left(i);
+
+ HICON hIcon = NULL;
+ UINT cnt = fSmall
+ ? ExtractIconEx(icon, id, NULL, &hIcon, 1)
+ : ExtractIconEx(icon, id, &hIcon, NULL, 1);
+ if(hIcon) return hIcon;
+ }
+ while(0);
+
+ return((HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_UNKNOWN), IMAGE_ICON, size.cx, size.cy, 0));
+}
+
+bool LoadType(CString fn, CString& type)
+{
+ CRegKey key;
+
+ TCHAR buff[256];
+ ULONG len;
+
+ if(fn.IsEmpty()) return(NULL);
+
+ CString ext = fn.Left(fn.Find(_T("://"))+1).TrimRight(':');
+ if(ext.IsEmpty() || !ext.CompareNoCase(_T("file")))
+ ext = _T(".") + fn.Mid(fn.ReverseFind('.')+1);
+
+ if(ERROR_SUCCESS != key.Open(HKEY_CLASSES_ROOT, ext))
+ return(false);
+
+ CString tmp = ext;
+
+ while(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, tmp))
+ {
+ len = sizeof(buff);
+ memset(buff, 0, len);
+ if(ERROR_SUCCESS != key.QueryStringValue(NULL, buff, &len))
+ break;
+
+ CString str(buff);
+ str.Trim();
+
+ if(str.IsEmpty() || str == tmp)
+ break;
+
+ tmp = str;
+ }
+
+ type = tmp;
+
+ return(true);
+}
+
+bool LoadResource(UINT resid, CStringA& str, LPCTSTR restype)
+{
+ str.Empty();
+ HRSRC hrsrc = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(resid), restype);
+ if(!hrsrc) return(false);
+ HGLOBAL hGlobal = LoadResource(AfxGetResourceHandle(), hrsrc);
+ if(!hGlobal) return(false);
+ DWORD size = SizeofResource(AfxGetResourceHandle(), hrsrc);
+ if(!size) return(false);
+ memcpy(str.GetBufferSetLength(size), LockResource(hGlobal), size);
+ return(true);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CAboutDlg dialog used for App About
+
+class CAboutDlg : public CDialog
+{
+public:
+ CAboutDlg();
+
+// Dialog Data
+ //{{AFX_DATA(CAboutDlg)
+ enum { IDD = IDD_ABOUTBOX };
+ //}}AFX_DATA
+
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CAboutDlg)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ //{{AFX_MSG(CAboutDlg)
+ // No message handlers
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+public:
+ CString m_appname;
+ virtual BOOL OnInitDialog()
+ {
+#ifdef UNICODE
+ UpdateData();
+ m_appname += _T(" (unicode build)");
+ UpdateData(FALSE);
+#endif
+ return TRUE;
+ }
+};
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD), m_appname(_T(""))
+{
+ //{{AFX_DATA_INIT(CAboutDlg)
+ //}}AFX_DATA_INIT
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CAboutDlg)
+ //}}AFX_DATA_MAP
+ DDX_Text(pDX, IDC_STATIC1, m_appname);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+ //{{AFX_MSG_MAP(CAboutDlg)
+ // No message handlers
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CMPlayerCApp
+
+BEGIN_MESSAGE_MAP(CMPlayerCApp, CWinApp)
+ //{{AFX_MSG_MAP(CMPlayerCApp)
+ ON_COMMAND(ID_HELP_ABOUT, OnAppAbout)
+ ON_COMMAND(ID_FILE_EXIT, OnFileExit)
+ //}}AFX_MSG_MAP
+ ON_COMMAND(ID_HELP_SHOWCOMMANDLINESWITCHES, OnHelpShowcommandlineswitches)
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CMPlayerCApp construction
+
+CMPlayerCApp::CMPlayerCApp()
+// : m_hMutexOneInstance(NULL)
+{
+ m_fTearingTest = false;
+ memset (&m_ColorControl, 0, sizeof(m_ColorControl));
+ m_ColorControl[0].dwSize = sizeof (COLORPROPERTY_RANGE);
+ m_ColorControl[0].dwProperty = Brightness;
+ m_ColorControl[1].dwSize = sizeof (COLORPROPERTY_RANGE);
+ m_ColorControl[1].dwProperty = Contrast;
+ m_ColorControl[2].dwSize = sizeof (COLORPROPERTY_RANGE);
+ m_ColorControl[2].dwProperty = Hue;
+ m_ColorControl[3].dwSize = sizeof (COLORPROPERTY_RANGE);
+ m_ColorControl[3].dwProperty = Saturation;
+
+ QueryPerformanceFrequency ((LARGE_INTEGER*)&m_PerfFrequency);
+}
+
+void CMPlayerCApp::ShowCmdlnSwitches()
+{
+ CString s;
+
+ if(m_s.nCLSwitches&CLSW_UNRECOGNIZEDSWITCH)
+ {
+ CAtlList<CString> sl;
+ for(int i = 0; i < __argc; i++) sl.AddTail(__targv[i]);
+ s += "Unrecognized switch(es) found in command line string: \n\n" + Implode(sl, ' ') + "\n\n";
+ }
+
+ s +=
+ _T("Usage: mplayerc.exe \"pathname\" [switches]\n\n")
+ _T("\"pathname\"\tThe main file or directory to be loaded. (wildcards allowed)\n")
+ _T("/dub \"dubname\"\tLoad an additional audio file.\n")
+ _T("/sub \"subname\"\tLoad an additional subtitle file.\n")
+ _T("/filter \"filtername\"\tLoad DirectShow filters from a dynamic link library. (wildcards allowed)\n")
+ _T("/dvd\t\tRun in dvd mode, \"pathname\" means the dvd folder (optional).\n")
+ _T("/cd\t\tLoad all the tracks of an audio cd or (s)vcd, \"pathname\" means the drive path (optional).\n")
+ _T("/open\t\tOpen the file, don't automatically start playing.\n")
+ _T("/play\t\tStart playing the file as soon the player is launched.\n")
+ _T("/close\t\tClose the player after playback (only works when used with /play).\n")
+ _T("/shutdown\tShutdown the operating system after playback\n")
+ _T("/fullscreen\tStart in full-screen mode.\n")
+ _T("/minimized\tStart in minimized mode.\n")
+ _T("/new\t\tUse a new instance of the player.\n")
+ _T("/add\t\tAdd \"pathname\" to playlist, can be combined with /open and /play.\n")
+ _T("/regvid\t\tRegister video formats\n")
+ _T("/regaud\t\tRegister audio formats\n")
+ _T("/unregvid\t\tUnregister video formats\n")
+ _T("/unregaud\tUnregister audio formats\n")
+ _T("/start ms\t\tStart playing at \"ms\" (= milliseconds)\n")
+ _T("/fixedsize w,h\tSet fixed window size.\n")
+ _T("/monitor N\tStart on monitor N, where N starts from 1.\n")
+ _T("/help /h /?\tShow help about command line switches. (this message box)\n");
+
+ AfxMessageBox(s);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// The one and only CMPlayerCApp object
+
+CMPlayerCApp theApp;
+
+HWND g_hWnd = NULL;
+
+bool CMPlayerCApp::StoreSettingsToIni()
+{
+ CString ini = GetIniPath();
+/*
+ FILE* f;
+ if(!(f = _tfopen(ini, _T("r+"))) && !(f = _tfopen(ini, _T("w"))))
+ return StoreSettingsToRegistry();
+ fclose(f);
+*/
+ if(m_pszRegistryKey) free((void*)m_pszRegistryKey);
+ m_pszRegistryKey = NULL;
+ if(m_pszProfileName) free((void*)m_pszProfileName);
+ m_pszProfileName = _tcsdup(ini);
+
+ return(true);
+}
+
+bool CMPlayerCApp::StoreSettingsToRegistry()
+{
+ _tremove(GetIniPath());
+
+ if(m_pszRegistryKey) free((void*)m_pszRegistryKey);
+ m_pszRegistryKey = NULL;
+
+ SetRegistryKey(_T("Gabest"));
+
+ return(true);
+}
+
+CString CMPlayerCApp::GetIniPath()
+{
+ CString path;
+ GetModuleFileName(AfxGetInstanceHandle(), path.GetBuffer(MAX_PATH), MAX_PATH);
+ path.ReleaseBuffer();
+ path = path.Left(path.ReverseFind('.')+1) + _T("ini");
+ return(path);
+}
+
+bool CMPlayerCApp::IsIniValid()
+{
+ CFileStatus fs;
+ return CFileGetStatus(GetIniPath(), fs) && fs.m_size > 0;
+}
+
+bool CMPlayerCApp::GetAppDataPath(CString& path)
+{
+ path.Empty();
+
+ CRegKey key;
+ if(ERROR_SUCCESS == key.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"), KEY_READ))
+ {
+ ULONG len = MAX_PATH;
+ if(ERROR_SUCCESS == key.QueryStringValue(_T("AppData"), path.GetBuffer(MAX_PATH), &len))
+ path.ReleaseBufferSetLength(len);
+ }
+
+ if(path.IsEmpty())
+ return(false);
+
+ CPath p;
+ p.Combine(path, _T("Media Player Classic"));
+ path = (LPCTSTR)p;
+
+ return(true);
+}
+
+void CMPlayerCApp::PreProcessCommandLine()
+{
+ m_cmdln.RemoveAll();
+ for(int i = 1; i < __argc; i++)
+ {
+ CString str = CString(__targv[i]).Trim(_T(" \""));
+
+ if(str[0] != '/' && str[0] != '-' && str.Find(_T(":")) < 0)
+ {
+ LPTSTR p = NULL;
+ CString str2;
+ str2.ReleaseBuffer(GetFullPathName(str, MAX_PATH, str2.GetBuffer(MAX_PATH), &p));
+ CFileStatus fs;
+ if(!str2.IsEmpty() && CFileGetStatus(str2, fs)) str = str2;
+ }
+
+ m_cmdln.AddTail(str);
+ }
+}
+
+void CMPlayerCApp::SendCommandLine(HWND hWnd)
+{
+ if(m_cmdln.IsEmpty())
+ return;
+
+ int bufflen = sizeof(DWORD);
+
+ POSITION pos = m_cmdln.GetHeadPosition();
+ while(pos) bufflen += (m_cmdln.GetNext(pos).GetLength()+1)*sizeof(TCHAR);
+
+ CAutoVectorPtr<BYTE> buff;
+ if(!buff.Allocate(bufflen))
+ return;
+
+ BYTE* p = buff;
+
+ *(DWORD*)p = m_cmdln.GetCount();
+ p += sizeof(DWORD);
+
+ pos = m_cmdln.GetHeadPosition();
+ while(pos)
+ {
+ CString s = m_cmdln.GetNext(pos);
+ int len = (s.GetLength()+1)*sizeof(TCHAR);
+ memcpy(p, s, len);
+ p += len;
+ }
+
+ COPYDATASTRUCT cds;
+ cds.dwData = 0x6ABE51;
+ cds.cbData = bufflen;
+ cds.lpData = (void*)(BYTE*)buff;
+ SendMessage(hWnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CMPlayerCApp initialization
+
+#include "..\..\..\include\detours\detours.h"
+#include "..\..\..\include\winddk\ntddcdvd.h"
+
+DETOUR_TRAMPOLINE(BOOL WINAPI Real_IsDebuggerPresent(), IsDebuggerPresent);
+BOOL WINAPI Mine_IsDebuggerPresent()
+{
+ TRACE(_T("Oops, somebody was trying to be naughty! (called IsDebuggerPresent)\n"));
+ return FALSE;
+}
+
+DETOUR_TRAMPOLINE(LONG WINAPI Real_ChangeDisplaySettingsExA(LPCSTR lpszDeviceName, LPDEVMODEA lpDevMode, HWND hwnd, DWORD dwFlags, LPVOID lParam), ChangeDisplaySettingsExA);
+DETOUR_TRAMPOLINE(LONG WINAPI Real_ChangeDisplaySettingsExW(LPCWSTR lpszDeviceName, LPDEVMODEW lpDevMode, HWND hwnd, DWORD dwFlags, LPVOID lParam), ChangeDisplaySettingsExW);
+LONG WINAPI Mine_ChangeDisplaySettingsEx(LONG ret, DWORD dwFlags, LPVOID lParam)
+{
+ if(dwFlags&CDS_VIDEOPARAMETERS)
+ {
+ VIDEOPARAMETERS* vp = (VIDEOPARAMETERS*)lParam;
+
+ if(vp->Guid == GUIDFromCString(_T("{02C62061-1097-11d1-920F-00A024DF156E}"))
+ && (vp->dwFlags&VP_FLAGS_COPYPROTECT))
+ {
+ if(vp->dwCommand == VP_COMMAND_GET)
+ {
+ if((vp->dwTVStandard&VP_TV_STANDARD_WIN_VGA)
+ && vp->dwTVStandard != VP_TV_STANDARD_WIN_VGA)
+ {
+ TRACE(_T("Ooops, tv-out enabled? macrovision checks suck..."));
+ vp->dwTVStandard = VP_TV_STANDARD_WIN_VGA;
+ }
+ }
+ else if(vp->dwCommand == VP_COMMAND_SET)
+ {
+ TRACE(_T("Ooops, as I already told ya, no need for any macrovision bs here"));
+ return 0;
+ }
+ }
+ }
+
+ return ret;
+}
+LONG WINAPI Mine_ChangeDisplaySettingsExA(LPCSTR lpszDeviceName, LPDEVMODEA lpDevMode, HWND hwnd, DWORD dwFlags, LPVOID lParam)
+{
+ return Mine_ChangeDisplaySettingsEx(
+ Real_ChangeDisplaySettingsExA(lpszDeviceName, lpDevMode, hwnd, dwFlags, lParam),
+ dwFlags,
+ lParam);
+}
+LONG WINAPI Mine_ChangeDisplaySettingsExW(LPCWSTR lpszDeviceName, LPDEVMODEW lpDevMode, HWND hwnd, DWORD dwFlags, LPVOID lParam)
+{
+ return Mine_ChangeDisplaySettingsEx(
+ Real_ChangeDisplaySettingsExW(lpszDeviceName, lpDevMode, hwnd, dwFlags, lParam),
+ dwFlags,
+ lParam);
+}
+
+DETOUR_TRAMPOLINE(HANDLE WINAPI Real_CreateFileA(LPCSTR p1, DWORD p2, DWORD p3, LPSECURITY_ATTRIBUTES p4, DWORD p5, DWORD p6, HANDLE p7), CreateFileA);
+DETOUR_TRAMPOLINE(HANDLE WINAPI Real_CreateFileW(LPCWSTR p1, DWORD p2, DWORD p3, LPSECURITY_ATTRIBUTES p4, DWORD p5, DWORD p6, HANDLE p7), CreateFileW);
+HANDLE WINAPI Mine_CreateFileA(LPCSTR p1, DWORD p2, DWORD p3, LPSECURITY_ATTRIBUTES p4, DWORD p5, DWORD p6, HANDLE p7)
+{
+ CStringA fn(p1);
+ fn.MakeLower();
+ int i = fn.Find(".part");
+ if(i > 0 && i == fn.GetLength() - 5)
+ p3 |= FILE_SHARE_WRITE;
+
+ return Real_CreateFileA(p1, p2, p3, p4, p5, p6, p7);
+}
+HANDLE WINAPI Mine_CreateFileW(LPCWSTR p1, DWORD p2, DWORD p3, LPSECURITY_ATTRIBUTES p4, DWORD p5, DWORD p6, HANDLE p7)
+{
+ CStringW fn(p1);
+ fn.MakeLower();
+ int i = fn.Find(L".part");
+ if(i > 0 && i == fn.GetLength() - 5)
+ p3 |= FILE_SHARE_WRITE;
+
+ return Real_CreateFileW(p1, p2, p3, p4, p5, p6, p7);
+}
+
+DETOUR_TRAMPOLINE(MMRESULT WINAPI Real_mixerSetControlDetails(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails), mixerSetControlDetails);
+MMRESULT WINAPI Mine_mixerSetControlDetails(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails)
+{
+ if(fdwDetails == (MIXER_OBJECTF_HMIXER|MIXER_SETCONTROLDETAILSF_VALUE))
+ return MMSYSERR_NOERROR; // don't touch the mixer, kthx
+ return Real_mixerSetControlDetails(hmxobj, pmxcd, fdwDetails);
+}
+
+DETOUR_TRAMPOLINE(BOOL WINAPI Real_DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped), DeviceIoControl);
+BOOL WINAPI Mine_DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
+{
+ BOOL ret = Real_DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
+
+ if(IOCTL_DVD_GET_REGION == dwIoControlCode && lpOutBuffer
+ && lpBytesReturned && *lpBytesReturned == sizeof(DVD_REGION))
+ {
+ DVD_REGION* pDVDRegion = (DVD_REGION*)lpOutBuffer;
+ pDVDRegion->SystemRegion = ~pDVDRegion->RegionData;
+ }
+
+ return ret;
+}
+
+BOOL CMPlayerCApp::InitInstance()
+{
+ DetourFunctionWithTrampoline((PBYTE)Real_IsDebuggerPresent, (PBYTE)Mine_IsDebuggerPresent);
+ DetourFunctionWithTrampoline((PBYTE)Real_ChangeDisplaySettingsExA, (PBYTE)Mine_ChangeDisplaySettingsExA);
+ DetourFunctionWithTrampoline((PBYTE)Real_ChangeDisplaySettingsExW, (PBYTE)Mine_ChangeDisplaySettingsExW);
+ DetourFunctionWithTrampoline((PBYTE)Real_CreateFileA, (PBYTE)Mine_CreateFileA);
+ DetourFunctionWithTrampoline((PBYTE)Real_CreateFileW, (PBYTE)Mine_CreateFileW);
+ DetourFunctionWithTrampoline((PBYTE)Real_mixerSetControlDetails, (PBYTE)Mine_mixerSetControlDetails);
+ DetourFunctionWithTrampoline((PBYTE)Real_DeviceIoControl, (PBYTE)Mine_DeviceIoControl);
+ CFilterMapper2::Init();
+
+ HRESULT hr;
+ if(FAILED(hr = OleInitialize(0)))
+ {
+ AfxMessageBox(_T("OleInitialize failed!"));
+ return FALSE;
+ }
+
+ WNDCLASS wndcls;
+ memset(&wndcls, 0, sizeof(WNDCLASS));
+ wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
+ wndcls.lpfnWndProc = ::DefWindowProc;
+ wndcls.hInstance = AfxGetInstanceHandle();
+ wndcls.hIcon = LoadIcon(IDR_MAINFRAME);
+ wndcls.hCursor = LoadCursor(IDC_ARROW);
+ wndcls.hbrBackground = 0;//(HBRUSH)(COLOR_WINDOW + 1); // no bkg brush, the view and the bars should always fill the whole client area
+ wndcls.lpszMenuName = NULL;
+ wndcls.lpszClassName = MPC_WND_CLASS_NAME;
+
+ if(!AfxRegisterClass(&wndcls))
+ {
+ AfxMessageBox(_T("MainFrm class registration failed!"));
+ return FALSE;
+ }
+
+ if(!AfxSocketInit(NULL))
+ {
+ AfxMessageBox(_T("AfxSocketInit failed!"));
+ return FALSE;
+ }
+
+ PreProcessCommandLine();
+
+ if(IsIniValid()) StoreSettingsToIni();
+ else StoreSettingsToRegistry();
+
+ CString AppDataPath;
+ if(GetAppDataPath(AppDataPath))
+ CreateDirectory(AppDataPath, NULL);
+
+ m_s.ParseCommandLine(m_cmdln);
+
+ if(m_s.nCLSwitches&(CLSW_HELP|CLSW_UNRECOGNIZEDSWITCH))
+ {
+ ShowCmdlnSwitches();
+ return FALSE;
+ }
+
+ if((m_s.nCLSwitches&CLSW_CLOSE) && m_s.slFiles.IsEmpty())
+ {
+ return FALSE;
+ }
+
+ m_s.UpdateData(false);
+
+ if((m_s.nCLSwitches&CLSW_REGEXTVID) || (m_s.nCLSwitches&CLSW_UNREGEXTVID)
+ || (m_s.nCLSwitches&CLSW_REGEXTAUD) || (m_s.nCLSwitches&CLSW_UNREGEXTAUD))
+ {
+ CMediaFormats& mf = m_s.Formats;
+
+ for(int i = 0; i < mf.GetCount(); i++)
+ {
+ // HACK
+ if(!mf[i].GetLabel().CompareNoCase(_T("Image file"))) continue;
+
+ bool fAudioOnly = mf[i].IsAudioOnly();
+
+ int j = 0;
+ CString str = mf[i].GetExtsWithPeriod();
+ for(CString ext = str.Tokenize(_T(" "), j); !ext.IsEmpty(); ext = str.Tokenize(_T(" "), j))
+ {
+ if((m_s.nCLSwitches&CLSW_REGEXTVID) && !fAudioOnly
+ || (m_s.nCLSwitches&CLSW_REGEXTAUD) && fAudioOnly)
+ CPPageFormats::RegisterExt(ext, true);
+
+ if((m_s.nCLSwitches&CLSW_UNREGEXTVID) && !fAudioOnly
+ || (m_s.nCLSwitches&CLSW_UNREGEXTAUD) && fAudioOnly)
+ CPPageFormats::RegisterExt(ext, false);
+ }
+ }
+
+ return FALSE;
+ }
+
+ m_mutexOneInstance.Create(NULL, TRUE, MPC_WND_CLASS_NAME);
+
+ if(GetLastError() == ERROR_ALREADY_EXISTS
+ && (!(m_s.fAllowMultipleInst || (m_s.nCLSwitches&CLSW_NEW) || m_cmdln.IsEmpty())
+ || (m_s.nCLSwitches&CLSW_ADD)))
+ {
+ if(HWND hWnd = ::FindWindow(MPC_WND_CLASS_NAME, NULL))
+ {
+ SetForegroundWindow(hWnd);
+
+ if(!(m_s.nCLSwitches&CLSW_MINIMIZED) && IsIconic(hWnd))
+ ShowWindow(hWnd, SW_RESTORE);
+
+ SendCommandLine(hWnd);
+
+ return FALSE;
+ }
+ }
+
+ if(!__super::InitInstance())
+ {
+ AfxMessageBox(_T("InitInstance failed!"));
+ return FALSE;
+ }
+
+ CRegKey key;
+ if(ERROR_SUCCESS == key.Create(HKEY_LOCAL_MACHINE, _T("Software\\Gabest\\Media Player Classic")))
+ {
+ CString path;
+ GetModuleFileName(AfxGetInstanceHandle(), path.GetBuffer(MAX_PATH), MAX_PATH);
+ path.ReleaseBuffer();
+ key.SetStringValue(_T("ExePath"), path);
+ }
+
+ AfxEnableControlContainer();
+
+ CMainFrame* pFrame = new CMainFrame;
+ m_pMainWnd = pFrame;
+ pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE, NULL, NULL);
+ pFrame->SetDefaultWindowRect((m_s.nCLSwitches&CLSW_MONITOR)?m_s.iMonitor:0);
+ pFrame->RestoreFloatingControlBars();
+ pFrame->SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), TRUE);
+ pFrame->DragAcceptFiles();
+ pFrame->ShowWindow((m_s.nCLSwitches&CLSW_MINIMIZED)?SW_SHOWMINIMIZED:SW_SHOW);
+ pFrame->UpdateWindow();
+ pFrame->m_hAccelTable = m_s.hAccel;
+
+ m_s.WinLircClient.SetHWND(m_pMainWnd->m_hWnd);
+ if(m_s.fWinLirc) m_s.WinLircClient.Connect(m_s.WinLircAddr);
+ m_s.UIceClient.SetHWND(m_pMainWnd->m_hWnd);
+ if(m_s.fUIce) m_s.UIceClient.Connect(m_s.UIceAddr);
+
+ SendCommandLine(m_pMainWnd->m_hWnd);
+
+ pFrame->SetFocus();
+
+ return TRUE;
+}
+
+int CMPlayerCApp::ExitInstance()
+{
+ m_s.UpdateData(true);
+
+ OleUninitialize();
+
+ return CWinApp::ExitInstance();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CMPlayerCApp message handlers
+// App command to run the dialog
+
+void CMPlayerCApp::OnAppAbout()
+{
+ CAboutDlg aboutDlg;
+ aboutDlg.DoModal();
+}
+
+void CMPlayerCApp::OnFileExit()
+{
+ OnAppExit();
+}
+
+// CRemoteCtrlClient
+
+CRemoteCtrlClient::CRemoteCtrlClient()
+ : m_pWnd(NULL)
+ , m_nStatus(DISCONNECTED)
+{
+}
+
+void CRemoteCtrlClient::SetHWND(HWND hWnd)
+{
+ CAutoLock cAutoLock(&m_csLock);
+
+ m_pWnd = CWnd::FromHandle(hWnd);
+}
+
+void CRemoteCtrlClient::Connect(CString addr)
+{
+ CAutoLock cAutoLock(&m_csLock);
+
+ if(m_nStatus == CONNECTING && m_addr == addr)
+ {
+ TRACE(_T("CRemoteCtrlClient (Connect): already connecting to %s\n"), addr);
+ return;
+ }
+
+ if(m_nStatus == CONNECTED && m_addr == addr)
+ {
+ TRACE(_T("CRemoteCtrlClient (Connect): already connected to %s\n"), addr);
+ return;
+ }
+
+ m_nStatus = CONNECTING;
+
+ TRACE(_T("CRemoteCtrlClient (Connect): connecting to %s\n"), addr);
+
+ Close();
+
+ Create();
+
+ CString ip = addr.Left(addr.Find(':')+1).TrimRight(':');
+ int port = _tcstol(addr.Mid(addr.Find(':')+1), NULL, 10);
+
+ __super::Connect(ip, port);
+
+ m_addr = addr;
+}
+
+void CRemoteCtrlClient::OnConnect(int nErrorCode)
+{
+ CAutoLock cAutoLock(&m_csLock);
+
+ m_nStatus = (nErrorCode == 0 ? CONNECTED : DISCONNECTED);
+
+ TRACE(_T("CRemoteCtrlClient (OnConnect): %d\n"), nErrorCode);
+}
+
+void CRemoteCtrlClient::OnClose(int nErrorCode)
+{
+ CAutoLock cAutoLock(&m_csLock);
+
+ if(m_hSocket != INVALID_SOCKET && m_nStatus == CONNECTED)
+ {
+ TRACE(_T("CRemoteCtrlClient (OnClose): connection lost\n"));
+ }
+
+ m_nStatus = DISCONNECTED;
+
+ TRACE(_T("CRemoteCtrlClient (OnClose): %d\n"), nErrorCode);
+}
+
+void CRemoteCtrlClient::OnReceive(int nErrorCode)
+{
+ if(nErrorCode != 0 || !m_pWnd) return;
+
+ CStringA str;
+ int ret = Receive(str.GetBuffer(256), 255, 0);
+ if(ret <= 0) return;
+ str.ReleaseBuffer(ret);
+
+ TRACE(_T("CRemoteCtrlClient (OnReceive): %s\n"), CString(str));
+
+ OnCommand(str);
+
+ __super::OnReceive(nErrorCode);
+}
+
+void CRemoteCtrlClient::ExecuteCommand(CStringA cmd, int repcnt)
+{
+ cmd.Trim();
+ if(cmd.IsEmpty()) return;
+ cmd.Replace(' ', '_');
+
+ AppSettings& s = AfxGetAppSettings();
+
+ POSITION pos = s.wmcmds.GetHeadPosition();
+ while(pos)
+ {
+ wmcmd wc = s.wmcmds.GetNext(pos);
+ CStringA name = CString(wc.name);
+ name.Replace(' ', '_');
+ if((repcnt == 0 && wc.rmrepcnt == 0 || wc.rmrepcnt > 0 && (repcnt%wc.rmrepcnt) == 0)
+ && (!name.CompareNoCase(cmd) || !wc.rmcmd.CompareNoCase(cmd) || wc.cmd == (WORD)strtol(cmd, NULL, 10)))
+ {
+ CAutoLock cAutoLock(&m_csLock);
+ TRACE(_T("CRemoteCtrlClient (calling command): %s\n"), wc.name);
+ m_pWnd->SendMessage(WM_COMMAND, wc.cmd);
+ break;
+ }
+ }
+}
+
+// CWinLircClient
+
+CWinLircClient::CWinLircClient()
+{
+}
+
+void CWinLircClient::OnCommand(CStringA str)
+{
+ TRACE(_T("CWinLircClient (OnCommand): %s\n"), CString(str));
+
+ int i = 0, j = 0, repcnt = 0;
+ for(CStringA token = str.Tokenize(" ", i);
+ !token.IsEmpty();
+ token = str.Tokenize(" ", i), j++)
+ {
+ if(j == 1)
+ repcnt = strtol(token, NULL, 16);
+ else if(j == 2)
+ ExecuteCommand(token, repcnt);
+ }
+}
+
+// CUIceClient
+
+CUIceClient::CUIceClient()
+{
+}
+
+void CUIceClient::OnCommand(CStringA str)
+{
+ TRACE(_T("CUIceClient (OnCommand): %s\n"), CString(str));
+
+ CStringA cmd;
+ int i = 0, j = 0;
+ for(CStringA token = str.Tokenize("|", i);
+ !token.IsEmpty();
+ token = str.Tokenize("|", i), j++)
+ {
+ if(j == 0)
+ cmd = token;
+ else if(j == 1)
+ ExecuteCommand(cmd, strtol(token, NULL, 16));
+ }
+}
+
+// CMPlayerCApp::Settings
+
+CMPlayerCApp::Settings::Settings()
+ : fInitialized(false)
+ , MRU(0, _T("Recent File List"), _T("File%d"), 20)
+ , MRUDub(0, _T("Recent Dub List"), _T("Dub%d"), 20)
+ , hAccel(NULL)
+{
+#define ADDCMD(cmd) wmcmds.AddTail(wmcmd##cmd)
+ ADDCMD((ID_FILE_OPENQUICK, 'Q', FVIRTKEY|FCONTROL|FNOINVERT, _T("Quick Open File")));
+ ADDCMD((ID_FILE_OPENMEDIA, 'O', FVIRTKEY|FCONTROL|FNOINVERT, _T("Open File")));
+ ADDCMD((ID_FILE_OPENDVD, 'D', FVIRTKEY|FCONTROL|FNOINVERT, _T("Open DVD")));
+ ADDCMD((ID_FILE_OPENDEVICE, 'V', FVIRTKEY|FCONTROL|FNOINVERT, _T("Open Device")));
+ ADDCMD((ID_FILE_SAVE_COPY, 0, FVIRTKEY|FNOINVERT, _T("Save As")));
+ ADDCMD((ID_FILE_SAVE_IMAGE, 0, FVIRTKEY|FNOINVERT, _T("Save Image")));
+ ADDCMD((ID_FILE_SAVE_IMAGE_AUTO, VK_F5, FVIRTKEY|FNOINVERT, _T("Save Image (auto)")));
+ ADDCMD((ID_FILE_LOAD_SUBTITLE, 'L', FVIRTKEY|FCONTROL|FNOINVERT, _T("Load Subtitle")));
+ ADDCMD((ID_FILE_SAVE_SUBTITLE, 'S', FVIRTKEY|FCONTROL|FNOINVERT, _T("Save Subtitle")));
+ ADDCMD((ID_FILE_CLOSEPLAYLIST, 'C', FVIRTKEY|FCONTROL|FNOINVERT, _T("Close")));
+ ADDCMD((ID_FILE_PROPERTIES, VK_F10, FVIRTKEY|FSHIFT|FNOINVERT, _T("Properties")));
+ ADDCMD((ID_FILE_EXIT, 'X', FVIRTKEY|FALT|FNOINVERT, _T("Exit")));
+ ADDCMD((ID_PLAY_PLAYPAUSE, VK_SPACE, FVIRTKEY|FNOINVERT, _T("Play/Pause"), APPCOMMAND_MEDIA_PLAY_PAUSE, wmcmd::LDOWN));
+ ADDCMD((ID_PLAY_PLAY, 0, FVIRTKEY|FNOINVERT, _T("Play")));
+ ADDCMD((ID_PLAY_PAUSE, 0, FVIRTKEY|FNOINVERT, _T("Pause")));
+ ADDCMD((ID_PLAY_STOP, VK_OEM_PERIOD, FVIRTKEY|FNOINVERT, _T("Stop"), APPCOMMAND_MEDIA_STOP));
+ ADDCMD((ID_PLAY_FRAMESTEP, VK_RIGHT, FVIRTKEY|FNOINVERT, _T("Framestep")));
+ ADDCMD((ID_PLAY_FRAMESTEPCANCEL, VK_LEFT, FVIRTKEY|FNOINVERT, _T("Framestep back")));
+ ADDCMD((ID_PLAY_GOTO, 'G', FVIRTKEY|FCONTROL|FNOINVERT, _T("Go To")));
+ ADDCMD((ID_PLAY_INCRATE, VK_UP, FVIRTKEY|FCONTROL|FNOINVERT, _T("Increase Rate")));
+ ADDCMD((ID_PLAY_DECRATE, VK_DOWN, FVIRTKEY|FCONTROL|FNOINVERT, _T("Decrease Rate")));
+ ADDCMD((ID_PLAY_RESETRATE, 'R', FVIRTKEY|FCONTROL|FNOINVERT, _T("Reset Rate")));
+ ADDCMD((ID_PLAY_INCAUDDELAY, VK_ADD, FVIRTKEY|FNOINVERT, _T("Audio Delay +10ms")));
+ ADDCMD((ID_PLAY_DECAUDDELAY, VK_SUBTRACT, FVIRTKEY|FNOINVERT, _T("Audio Delay -10ms")));
+ ADDCMD((ID_PLAY_SEEKFORWARDSMALL, 0, FVIRTKEY|FNOINVERT, _T("Jump Forward (small)")));
+ ADDCMD((ID_PLAY_SEEKBACKWARDSMALL, 0, FVIRTKEY|FNOINVERT, _T("Jump Backward (small)")));
+ ADDCMD((ID_PLAY_SEEKFORWARDMED, VK_RIGHT, FVIRTKEY|FCONTROL|FNOINVERT, _T("Jump Forward (medium)")));
+ ADDCMD((ID_PLAY_SEEKBACKWARDMED, VK_LEFT, FVIRTKEY|FCONTROL|FNOINVERT, _T("Jump Backward (medium)")));
+ ADDCMD((ID_PLAY_SEEKFORWARDLARGE, 0, FVIRTKEY|FNOINVERT, _T("Jump Forward (large)")));
+ ADDCMD((ID_PLAY_SEEKBACKWARDLARGE, 0, FVIRTKEY|FNOINVERT, _T("Jump Backward (large)")));
+ ADDCMD((ID_PLAY_SEEKKEYFORWARD, VK_RIGHT, FVIRTKEY|FSHIFT|FNOINVERT, _T("Jump Forward (keyframe)")));
+ ADDCMD((ID_PLAY_SEEKKEYBACKWARD, VK_LEFT, FVIRTKEY|FSHIFT|FNOINVERT, _T("Jump Backward (keyframe)")));
+ ADDCMD((ID_NAVIGATE_SKIPFORWARD, VK_NEXT, FVIRTKEY|FNOINVERT, _T("Next"), APPCOMMAND_MEDIA_NEXTTRACK, wmcmd::X2DOWN));
+ ADDCMD((ID_NAVIGATE_SKIPBACK, VK_PRIOR, FVIRTKEY|FNOINVERT, _T("Previous"), APPCOMMAND_MEDIA_PREVIOUSTRACK, wmcmd::X1DOWN));
+ ADDCMD((ID_NAVIGATE_SKIPFORWARDPLITEM, VK_NEXT, FVIRTKEY|FCONTROL|FNOINVERT, _T("Next Playlist Item")));
+ ADDCMD((ID_NAVIGATE_SKIPBACKPLITEM, VK_PRIOR, FVIRTKEY|FCONTROL|FNOINVERT, _T("Previous Playlist Item")));
+ ADDCMD((ID_VIEW_CAPTIONMENU, '0', FVIRTKEY|FCONTROL|FNOINVERT, _T("Toggle Caption&Menu")));
+ ADDCMD((ID_VIEW_SEEKER, '1', FVIRTKEY|FCONTROL|FNOINVERT, _T("Toggle Seeker")));
+ ADDCMD((ID_VIEW_CONTROLS, '2', FVIRTKEY|FCONTROL|FNOINVERT, _T("Toggle Controls")));
+ ADDCMD((ID_VIEW_INFORMATION, '3', FVIRTKEY|FCONTROL|FNOINVERT, _T("Toggle Information")));
+ ADDCMD((ID_VIEW_STATISTICS, '4', FVIRTKEY|FCONTROL|FNOINVERT, _T("Toggle Statistics")));
+ ADDCMD((ID_VIEW_STATUS, '5', FVIRTKEY|FCONTROL|FNOINVERT, _T("Toggle Status")));
+ ADDCMD((ID_VIEW_SUBRESYNC, '6', FVIRTKEY|FCONTROL|FNOINVERT, _T("Toggle Subresync Bar")));
+ ADDCMD((ID_VIEW_PLAYLIST, '7', FVIRTKEY|FCONTROL|FNOINVERT, _T("Toggle Playlist Bar")));
+ ADDCMD((ID_VIEW_CAPTURE, '8', FVIRTKEY|FCONTROL|FNOINVERT, _T("Toggle Capture Bar")));
+ ADDCMD((ID_VIEW_SHADEREDITOR, '9', FVIRTKEY|FCONTROL|FNOINVERT, _T("Toggle Shader Editor Bar")));
+ ADDCMD((ID_VIEW_PRESETS_MINIMAL, '1', FVIRTKEY|FNOINVERT, _T("View Minimal")));
+ ADDCMD((ID_VIEW_PRESETS_COMPACT, '2', FVIRTKEY|FNOINVERT, _T("View Compact")));
+ ADDCMD((ID_VIEW_PRESETS_NORMAL, '3', FVIRTKEY|FNOINVERT, _T("View Normal")));
+ ADDCMD((ID_VIEW_FULLSCREEN, VK_RETURN, FVIRTKEY|FALT|FNOINVERT, _T("Fullscreen"), 0, wmcmd::LDBLCLK));
+ ADDCMD((ID_VIEW_FULLSCREEN_SECONDARY, VK_RETURN, FVIRTKEY|FCONTROL|FNOINVERT, _T("Fullscreen (w/o res.change)")));
+ ADDCMD((ID_VIEW_ZOOM_50, '1', FVIRTKEY|FALT|FNOINVERT, _T("Zoom 50%")));
+ ADDCMD((ID_VIEW_ZOOM_100, '2', FVIRTKEY|FALT|FNOINVERT, _T("Zoom 100%")));
+ ADDCMD((ID_VIEW_ZOOM_200, '3', FVIRTKEY|FALT|FNOINVERT, _T("Zoom 200%")));
+ ADDCMD((ID_VIEW_ZOOM_AUTOFIT, '4', FVIRTKEY|FALT|FNOINVERT, _T("Zoom Auto Fit")));
+ ADDCMD((ID_ASPECTRATIO_NEXT, 0, FVIRTKEY|FNOINVERT, _T("Next AR Preset")));
+ ADDCMD((ID_VIEW_VF_HALF, 0, FVIRTKEY|FNOINVERT, _T("VidFrm Half")));
+ ADDCMD((ID_VIEW_VF_NORMAL, 0, FVIRTKEY|FNOINVERT, _T("VidFrm Normal")));
+ ADDCMD((ID_VIEW_VF_DOUBLE, 0, FVIRTKEY|FNOINVERT, _T("VidFrm Double")));
+ ADDCMD((ID_VIEW_VF_STRETCH, 0, FVIRTKEY|FNOINVERT, _T("VidFrm Stretch")));
+ ADDCMD((ID_VIEW_VF_FROMINSIDE, 0, FVIRTKEY|FNOINVERT, _T("VidFrm Inside")));
+ ADDCMD((ID_VIEW_VF_FROMOUTSIDE, 0, FVIRTKEY|FNOINVERT, _T("VidFrm Outside")));
+ ADDCMD((ID_ONTOP_ALWAYS, 'A', FVIRTKEY|FCONTROL|FNOINVERT, _T("Always On Top")));
+ ADDCMD((ID_VIEW_RESET, VK_NUMPAD5, FVIRTKEY|FNOINVERT, _T("PnS Reset")));
+ ADDCMD((ID_VIEW_INCSIZE, VK_NUMPAD9, FVIRTKEY|FNOINVERT, _T("PnS Inc Size")));
+ ADDCMD((ID_VIEW_INCWIDTH, VK_NUMPAD6, FVIRTKEY|FNOINVERT, _T("PnS Inc Width")));
+ ADDCMD((ID_VIEW_INCHEIGHT, VK_NUMPAD8, FVIRTKEY|FNOINVERT, _T("PnS Inc Height")));
+ ADDCMD((ID_VIEW_DECSIZE, VK_NUMPAD1, FVIRTKEY|FNOINVERT, _T("PnS Dec Size")));
+ ADDCMD((ID_VIEW_DECWIDTH, VK_NUMPAD4, FVIRTKEY|FNOINVERT, _T("PnS Dec Width")));
+ ADDCMD((ID_VIEW_DECHEIGHT, VK_NUMPAD2, FVIRTKEY|FNOINVERT, _T("PnS Dec Height")));
+ ADDCMD((ID_PANSCAN_CENTER, VK_NUMPAD5, FVIRTKEY|FCONTROL|FNOINVERT, _T("PnS Center")));
+ ADDCMD((ID_PANSCAN_MOVELEFT, VK_NUMPAD4, FVIRTKEY|FCONTROL|FNOINVERT, _T("PnS Left")));
+ ADDCMD((ID_PANSCAN_MOVERIGHT, VK_NUMPAD6, FVIRTKEY|FCONTROL|FNOINVERT, _T("PnS Right")));
+ ADDCMD((ID_PANSCAN_MOVEUP, VK_NUMPAD8, FVIRTKEY|FCONTROL|FNOINVERT, _T("PnS Up")));
+ ADDCMD((ID_PANSCAN_MOVEDOWN, VK_NUMPAD2, FVIRTKEY|FCONTROL|FNOINVERT, _T("PnS Down")));
+ ADDCMD((ID_PANSCAN_MOVEUPLEFT, VK_NUMPAD7, FVIRTKEY|FCONTROL|FNOINVERT, _T("PnS Up/Left")));
+ ADDCMD((ID_PANSCAN_MOVEUPRIGHT, VK_NUMPAD9, FVIRTKEY|FCONTROL|FNOINVERT, _T("PnS Up/Right")));
+ ADDCMD((ID_PANSCAN_MOVEDOWNLEFT, VK_NUMPAD1, FVIRTKEY|FCONTROL|FNOINVERT, _T("PnS Down/Left")));
+ ADDCMD((ID_PANSCAN_MOVEDOWNRIGHT, VK_NUMPAD3, FVIRTKEY|FCONTROL|FNOINVERT, _T("PnS Down/Right")));
+ ADDCMD((ID_PANSCAN_ROTATEXP, VK_NUMPAD8, FVIRTKEY|FALT|FNOINVERT, _T("PnS Rotate X+")));
+ ADDCMD((ID_PANSCAN_ROTATEXM, VK_NUMPAD2, FVIRTKEY|FALT|FNOINVERT, _T("PnS Rotate X-")));
+ ADDCMD((ID_PANSCAN_ROTATEYP, VK_NUMPAD4, FVIRTKEY|FALT|FNOINVERT, _T("PnS Rotate Y+")));
+ ADDCMD((ID_PANSCAN_ROTATEYM, VK_NUMPAD6, FVIRTKEY|FALT|FNOINVERT, _T("PnS Rotate Y-")));
+ ADDCMD((ID_PANSCAN_ROTATEZP, VK_NUMPAD1, FVIRTKEY|FALT|FNOINVERT, _T("PnS Rotate Z+")));
+ ADDCMD((ID_PANSCAN_ROTATEZM, VK_NUMPAD3, FVIRTKEY|FALT|FNOINVERT, _T("PnS Rotate Z-")));
+ ADDCMD((ID_VOLUME_UP, VK_UP, FVIRTKEY|FNOINVERT, _T("Volume Up"), APPCOMMAND_VOLUME_UP, wmcmd::WUP));
+ ADDCMD((ID_VOLUME_DOWN, VK_DOWN, FVIRTKEY|FNOINVERT, _T("Volume Down"), APPCOMMAND_VOLUME_DOWN, wmcmd::WDOWN));
+ ADDCMD((ID_VOLUME_MUTE, 'M', FVIRTKEY|FCONTROL|FNOINVERT, _T("Volume Mute"), APPCOMMAND_VOLUME_MUTE));
+ ADDCMD((ID_NAVIGATE_TITLEMENU, 'T', FVIRTKEY|FALT|FNOINVERT, _T("DVD Title Menu")));
+ ADDCMD((ID_NAVIGATE_ROOTMENU, 'R', FVIRTKEY|FALT|FNOINVERT, _T("DVD Root Menu")));
+ ADDCMD((ID_NAVIGATE_SUBPICTUREMENU, 0, FVIRTKEY|FNOINVERT, _T("DVD Subtitle Menu")));
+ ADDCMD((ID_NAVIGATE_AUDIOMENU, 0, FVIRTKEY|FNOINVERT, _T("DVD Audio Menu")));
+ ADDCMD((ID_NAVIGATE_ANGLEMENU, 0, FVIRTKEY|FNOINVERT, _T("DVD Angle Menu")));
+ ADDCMD((ID_NAVIGATE_CHAPTERMENU, 0, FVIRTKEY|FNOINVERT, _T("DVD Chapter Menu")));
+ ADDCMD((ID_NAVIGATE_MENU_LEFT, VK_LEFT, FVIRTKEY|FALT|FNOINVERT, _T("DVD Menu Left")));
+ ADDCMD((ID_NAVIGATE_MENU_RIGHT, VK_RIGHT, FVIRTKEY|FALT|FNOINVERT, _T("DVD Menu Right")));
+ ADDCMD((ID_NAVIGATE_MENU_UP, VK_UP, FVIRTKEY|FALT|FNOINVERT, _T("DVD Menu Up")));
+ ADDCMD((ID_NAVIGATE_MENU_DOWN, VK_DOWN, FVIRTKEY|FALT|FNOINVERT, _T("DVD Menu Down")));
+ ADDCMD((ID_NAVIGATE_MENU_ACTIVATE, VK_SPACE, FVIRTKEY|FALT|FNOINVERT, _T("DVD Menu Activate")));
+ ADDCMD((ID_NAVIGATE_MENU_BACK, 0, FVIRTKEY|FNOINVERT, _T("DVD Menu Back")));
+ ADDCMD((ID_NAVIGATE_MENU_LEAVE, 0, FVIRTKEY|FNOINVERT, _T("DVD Menu Leave")));
+ ADDCMD((ID_BOSS, 'B', FVIRTKEY|FNOINVERT, _T("Boss key")));
+ ADDCMD((ID_MENU_PLAYER_SHORT, 0, FVIRTKEY|FNOINVERT, _T("Player Menu (short)"), 0, wmcmd::RUP));
+ ADDCMD((ID_MENU_PLAYER_LONG, 0, FVIRTKEY|FNOINVERT, _T("Player Menu (long)")));
+ ADDCMD((ID_MENU_FILTERS, 0, FVIRTKEY|FNOINVERT, _T("Filters Menu")));
+ ADDCMD((ID_VIEW_OPTIONS, 'O', FVIRTKEY|FNOINVERT, _T("Options")));
+ ADDCMD((ID_STREAM_AUDIO_NEXT, 'A', FVIRTKEY|FNOINVERT, _T("Next Audio")));
+ ADDCMD((ID_STREAM_AUDIO_PREV, 'A', FVIRTKEY|FSHIFT|FNOINVERT, _T("Prev Audio")));
+ ADDCMD((ID_STREAM_SUB_NEXT, 'S', FVIRTKEY|FNOINVERT, _T("Next Subtitle")));
+ ADDCMD((ID_STREAM_SUB_PREV, 'S', FVIRTKEY|FSHIFT|FNOINVERT, _T("Prev Subtitle")));
+ ADDCMD((ID_STREAM_SUB_ONOFF, 'W', FVIRTKEY|FNOINVERT, _T("On/Off Subtitle")));
+ ADDCMD((ID_SUBTITLES_SUBITEM_START+2, 0, FVIRTKEY|FNOINVERT, _T("Reload Subtitles")));
+ ADDCMD((ID_OGM_AUDIO_NEXT, 0, FVIRTKEY|FNOINVERT, _T("Next Audio (OGM)")));
+ ADDCMD((ID_OGM_AUDIO_PREV, 0, FVIRTKEY|FNOINVERT, _T("Prev Audio (OGM)")));
+ ADDCMD((ID_OGM_SUB_NEXT, 0, FVIRTKEY|FNOINVERT, _T("Next Subtitle (OGM)")));
+ ADDCMD((ID_OGM_SUB_PREV, 0, FVIRTKEY|FNOINVERT, _T("Prev Subtitle (OGM)")));
+ ADDCMD((ID_DVD_ANGLE_NEXT, 0, FVIRTKEY|FNOINVERT, _T("Next Angle (DVD)")));
+ ADDCMD((ID_DVD_ANGLE_PREV, 0, FVIRTKEY|FNOINVERT, _T("Prev Angle (DVD)")));
+ ADDCMD((ID_DVD_AUDIO_NEXT, 0, FVIRTKEY|FNOINVERT, _T("Next Audio (DVD)")));
+ ADDCMD((ID_DVD_AUDIO_PREV, 0, FVIRTKEY|FNOINVERT, _T("Prev Audio (DVD)")));
+ ADDCMD((ID_DVD_SUB_NEXT, 0, FVIRTKEY|FNOINVERT, _T("Next Subtitle (DVD)")));
+ ADDCMD((ID_DVD_SUB_PREV, 0, FVIRTKEY|FNOINVERT, _T("Prev Subtitle (DVD)")));
+ ADDCMD((ID_DVD_SUB_ONOFF, 0, FVIRTKEY|FNOINVERT, _T("On/Off Subtitle (DVD)")));
+
+ // === CASIMIR666 : nouveau shortcuts
+ ADDCMD((ID_VIEW_TEARING_TEST, 'T', FVIRTKEY|FCONTROL|FNOINVERT, _T("Tearing Test")));
+ ADDCMD((ID_VIEW_REMAINING_TIME, 'I', FVIRTKEY|FCONTROL|FNOINVERT, _T("Remaining Time")));
+ ADDCMD((ID_SHADER_TOGGLE, 'P', FVIRTKEY|FCONTROL|FNOINVERT, _T("Toggle Pixel Shader")));
+
+ nCurrentDvdPosition = -1;
+ nCurrentFilePosition = -1;
+
+#undef ADDCMD
+}
+
+CMPlayerCApp::Settings::~Settings()
+{
+ if(hAccel)
+ DestroyAcceleratorTable(hAccel);
+}
+
+DVD_POSITION* CMPlayerCApp::Settings::CurrentDVDPosition()
+{
+ if (nCurrentDvdPosition != -1)
+ return &DvdPosition[nCurrentDvdPosition];
+ else
+ return NULL;
+}
+
+bool CMPlayerCApp::Settings::NewDvd(ULONGLONG llDVDGuid)
+{
+ int i;
+
+ // Recherche si la position du DVD est connue
+ for (i=0; i<MAX_DVD_POSITION; i++)
+ {
+ if (DvdPosition[i].llDVDGuid == llDVDGuid)
+ {
+ nCurrentDvdPosition = i;
+ return false;
+ }
+ }
+
+ // Si DVD inconnu, le mettre en premier
+ for (int i=MAX_DVD_POSITION-1; i>0; i--)
+ memcpy (&DvdPosition[i], &DvdPosition[i-1], sizeof(DVD_POSITION));
+ DvdPosition[0].llDVDGuid = llDVDGuid;
+ nCurrentDvdPosition = 0;
+ return true;
+}
+
+FILE_POSITION* CMPlayerCApp::Settings::CurrentFilePosition()
+{
+ if (nCurrentFilePosition != -1)
+ return &FilePosition[nCurrentFilePosition];
+ else
+ return NULL;
+}
+
+bool CMPlayerCApp::Settings::NewFile(LPCTSTR strFileName)
+{
+ int i;
+
+ // Recherche si la position du fichier est connue
+ for (i=0; i<MAX_FILE_POSITION; i++)
+ {
+ if (FilePosition[i].strFile == strFileName)
+ {
+ nCurrentFilePosition = i;
+ return false;
+ }
+ }
+
+ // Si fichier inconnu, le mettre en premier
+ for (int i=MAX_FILE_POSITION-1; i>0; i--)
+ {
+ FilePosition[i].strFile = FilePosition[i-1].strFile;
+ FilePosition[i].llPosition = FilePosition[i-1].llPosition;
+ }
+ FilePosition[0].strFile = strFileName;
+ FilePosition[0].llPosition = 0;
+ nCurrentFilePosition = 0;
+ return true;
+}
+
+
+void CMPlayerCApp::Settings::DeserializeHex (LPCTSTR strVal, BYTE* pBuffer, int nBufSize)
+{
+ long lRes;
+
+ for (int i=0; i<nBufSize; i++)
+ {
+ _stscanf (strVal+(i*2), _T("%02x"), &lRes);
+ pBuffer[i] = (BYTE)lRes;
+ }
+}
+
+CString CMPlayerCApp::Settings::SerializeHex (BYTE* pBuffer, int nBufSize)
+{
+ CString strTemp;
+ CString strResult;
+
+ for (int i=0; i<nBufSize; i++)
+ {
+ strTemp.Format (_T("%02x"), pBuffer[i]);
+ strResult += strTemp;
+ }
+
+ return strResult;
+}
+
+void CMPlayerCApp::Settings::UpdateData(bool fSave)
+{
+ CWinApp* pApp = AfxGetApp();
+ ASSERT(pApp);
+
+ UINT len;
+ BYTE* ptr = NULL;
+
+ if(fSave)
+ {
+ if(!fInitialized) return;
+
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_HIDECAPTIONMENU), fHideCaptionMenu);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_CONTROLSTATE), nCS);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DEFAULTVIDEOFRAME), iDefaultVideoSize);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_KEEPASPECTRATIO), fKeepAspectRatio);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_COMPMONDESKARDIFF), fCompMonDeskARDiff);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_VOLUME), nVolume);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_BALANCE), nBalance);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_MUTE), fMute);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LOOPNUM), nLoops);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LOOP), fLoopForever);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_REWIND), fRewind);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ZOOM), iZoomLevel);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_MULTIINST), fAllowMultipleInst);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_TITLEBARTEXTSTYLE), iTitleBarTextStyle);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_TITLEBARTEXTTITLE), fTitleBarTextTitle);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ONTOP), iOnTop);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_TRAYICON), fTrayIcon);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUTOZOOM), fRememberZoomLevel);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_FULLSCREENCTRLS), fShowBarsWhenFullScreen);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_FULLSCREENCTRLSTIMEOUT), nShowBarsWhenFullScreenTimeOut);
+ pApp->WriteProfileBinary(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_FULLSCREENRES), (BYTE*)&dmFullscreenRes, sizeof(dmFullscreenRes));
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_EXITFULLSCREENATTHEEND), fExitFullScreenAtTheEnd);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_REMEMBERWINDOWPOS), fRememberWindowPos);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_REMEMBERWINDOWSIZE), fRememberWindowSize);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SNAPTODESKTOPEDGES), fSnapToDesktopEdges);
+ pApp->WriteProfileBinary(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LASTWINDOWRECT), (BYTE*)&rcLastWindowPos, sizeof(rcLastWindowPos));
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LASTWINDOWTYPE), lastWindowType);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ASPECTRATIO_X), AspectRatio.cx);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ASPECTRATIO_Y), AspectRatio.cy);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_KEEPHISTORY), fKeepHistory);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DSVIDEORENDERERTYPE), iDSVideoRendererType);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_RMVIDEORENDERERTYPE), iRMVideoRendererType);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_QTVIDEORENDERERTYPE), iQTVideoRendererType);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_APSURACEFUSAGE), iAPSurfaceUsage);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_VMRSYNCFIX), fVMRSyncFix);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DX9_RESIZER), iDX9Resizer);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_VMR9MIXERMODE), fVMR9MixerMode);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_VMR9MIXERYUV), fVMR9MixerYUV);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUDIORENDERERTYPE), CString(AudioRendererDisplayName));
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUTOLOADAUDIO), fAutoloadAudio);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUTOLOADSUBTITLES), fAutoloadSubtitles);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ENABLEWORKERTHREADFOROPENING), fEnableWorkerThreadForOpening);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_REPORTFAILEDPINS), fReportFailedPins);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DVDPATH), sDVDPath);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_USEDVDPATH), fUseDVDPath);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_MENULANG), idMenuLang);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUDIOLANG), idAudioLang);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SUBTITLESLANG), idSubtitlesLang);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUTOSPEAKERCONF), fAutoSpeakerConf);
+ CString style;
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPLOGFONT), style <<= subdefstyle);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPOVERRIDEPLACEMENT), fOverridePlacement);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPHORPOS), nHorPos);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPVERPOS), nVerPos);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPCSIZE), nSPCSize);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPCMAXRES), nSPCMaxRes);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_POW2TEX), fSPCPow2Tex);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ENABLESUBTITLES), fEnableSubtitles);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ENABLEAUDIOSWITCHER), fEnableAudioSwitcher);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ENABLEAUDIOTIMESHIFT), fAudioTimeShift);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUDIOTIMESHIFT), tAudioTimeShift);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DOWNSAMPLETO441), fDownSampleTo441);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_CUSTOMCHANNELMAPPING), fCustomChannelMapping);
+ pApp->WriteProfileBinary(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPEAKERTOCHANNELMAPPING), (BYTE*)pSpeakerToChannelMap, sizeof(pSpeakerToChannelMap));
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUDIONORMALIZE), fAudioNormalize);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUDIONORMALIZERECOVER), fAudioNormalizeRecover);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUDIOBOOST), (int)AudioBoost);
+
+ // CASIMIR666 : nouveau settings
+ CString strTemp;
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_D3DFULLSCREEN), fD3DFullscreen);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_MONITOR_AUTOREFRESHRATE), fMonitorAutoRefreshRate);
+
+ strTemp.Format (_T("%f"), dBrightness);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_COLOR_BRIGHTNESS), strTemp);
+ strTemp.Format (_T("%f"), dContrast);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_COLOR_CONTRAST), strTemp);
+ strTemp.Format (_T("%f"), dHue);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_COLOR_HUE), strTemp);
+ strTemp.Format (_T("%f"), dSaturation);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_COLOR_SATURATION), strTemp);
+
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SHADERLIST), strShaderList);
+
+ // Position de lecture des derniers DVD's
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DVDPOS), (int)fRememberDVDPos);
+ for (int i=0; i<MAX_DVD_POSITION; i++)
+ {
+ CString strDVDPos;
+ CString strValue;
+
+ strDVDPos.Format (_T("DVD Position %d"), i);
+ strValue = SerializeHex((BYTE*)&DvdPosition[i], sizeof(DVD_POSITION));
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), strDVDPos, strValue);
+ }
+
+ // Position de lecture des derniers fichiers
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_FILEPOS), (int)fRememberFilePos);
+ for (int i=0; i<MAX_FILE_POSITION; i++)
+ {
+ CString strFilePos;
+ CString strValue;
+
+ strFilePos.Format (_T("File Name %d"), i);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), strFilePos, FilePosition[i].strFile);
+ strFilePos.Format (_T("File Position %d"), i);
+ strValue.Format (_T("%I64d"), FilePosition[i].llPosition);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), strFilePos, strValue);
+ }
+
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LASTFULLSCREEN), (int)fLastFullScreen);
+ // CASIMIR666 : fin nouveaux settings
+
+ {
+ for(int i = 0; ; i++)
+ {
+ CString key;
+ key.Format(_T("%s\\%04d"), ResStr(IDS_R_FILTERS), i);
+ int j = pApp->GetProfileInt(key, _T("Enabled"), -1);
+ pApp->WriteProfileString(key, NULL, NULL);
+ if(j < 0) break;
+ }
+ pApp->WriteProfileString(ResStr(IDS_R_FILTERS), NULL, NULL);
+
+ POSITION pos = filters.GetHeadPosition();
+ for(int i = 0; pos; i++)
+ {
+ FilterOverride* f = filters.GetNext(pos);
+
+ if(f->fTemporary)
+ continue;
+
+ CString key;
+ key.Format(_T("%s\\%04d"), ResStr(IDS_R_FILTERS), i);
+
+ pApp->WriteProfileInt(key, _T("SourceType"), (int)f->type);
+ pApp->WriteProfileInt(key, _T("Enabled"), (int)!f->fDisabled);
+ if(f->type == FilterOverride::REGISTERED)
+ {
+ pApp->WriteProfileString(key, _T("DisplayName"), CString(f->dispname));
+ pApp->WriteProfileString(key, _T("Name"), f->name);
+ }
+ else if(f->type == FilterOverride::EXTERNAL)
+ {
+ pApp->WriteProfileString(key, _T("Path"), f->path);
+ pApp->WriteProfileString(key, _T("Name"), f->name);
+ pApp->WriteProfileString(key, _T("CLSID"), CStringFromGUID(f->clsid));
+ }
+ POSITION pos2 = f->backup.GetHeadPosition();
+ for(int i = 0; pos2; i++)
+ {
+ CString val;
+ val.Format(_T("org%04d"), i);
+ pApp->WriteProfileString(key, val, CStringFromGUID(f->backup.GetNext(pos2)));
+ }
+ pos2 = f->guids.GetHeadPosition();
+ for(int i = 0; pos2; i++)
+ {
+ CString val;
+ val.Format(_T("mod%04d"), i);
+ pApp->WriteProfileString(key, val, CStringFromGUID(f->guids.GetNext(pos2)));
+ }
+ pApp->WriteProfileInt(key, _T("LoadType"), f->iLoadType);
+ pApp->WriteProfileInt(key, _T("Merit"), f->dwMerit);
+ }
+ }
+
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_INTREALMEDIA), fIntRealMedia);
+ // pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_REALMEDIARENDERLESS), fRealMediaRenderless);
+ // pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_QUICKTIMERENDERER), iQuickTimeRenderer);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_REALMEDIAFPS), *((DWORD*)&RealMediaQuickTimeFPS));
+
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS) + _T("\\") + ResStr(IDS_RS_PNSPRESETS), NULL, NULL);
+ for(int i = 0, j = m_pnspresets.GetCount(); i < j; i++)
+ {
+ CString str;
+ str.Format(_T("Preset%d"), i);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS) + _T("\\") + ResStr(IDS_RS_PNSPRESETS), str, m_pnspresets[i]);
+ }
+
+ pApp->WriteProfileString(ResStr(IDS_R_COMMANDS), NULL, NULL);
+ POSITION pos = wmcmds.GetHeadPosition();
+ for(int i = 0; pos; )
+ {
+ wmcmd& wc = wmcmds.GetNext(pos);
+ if(wc.IsModified())
+ {
+ CString str;
+ str.Format(_T("CommandMod%d"), i);
+ CString str2;
+ str2.Format(_T("%d %x %x %s %d %d %d"),
+ wc.cmd, wc.fVirt, wc.key,
+ _T("\"") + CString(wc.rmcmd) + _T("\""), wc.rmrepcnt,
+ wc.mouse, wc.appcmd);
+ pApp->WriteProfileString(ResStr(IDS_R_COMMANDS), str, str2);
+ i++;
+ }
+ }
+
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WINLIRC), fWinLirc);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WINLIRCADDR), WinLircAddr);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_UICE), fUIce);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_UICEADDR), UIceAddr);
+
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DISABLEXPTOOLBARS), fDisabeXPToolbars);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_USEWMASFREADER), fUseWMASFReader);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_JUMPDISTS), nJumpDistS);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_JUMPDISTM), nJumpDistM);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_JUMPDISTL), nJumpDistL);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_FREEWINDOWRESIZING), fFreeWindowResizing);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_NOTIFYMSN), fNotifyMSN);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_NOTIFYGTSDLL), fNotifyGTSdll);
+
+ Formats.UpdateData(true);
+
+ pApp->WriteProfileInt(ResStr(IDS_R_INTERNAL_FILTERS), ResStr(IDS_RS_SRCFILTERS), SrcFilters|~(SRC_LAST-1));
+ pApp->WriteProfileInt(ResStr(IDS_R_INTERNAL_FILTERS), ResStr(IDS_RS_TRAFILTERS), TraFilters|~(TRA_LAST-1));
+
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LOGOFILE), logofn);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LOGOID), logoid);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LOGOEXT), logoext);
+
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_HIDECDROMSSUBMENU), fHideCDROMsSubMenu);
+
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_PRIORITY), priority);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LAUNCHFULLSCREEN), launchfullscreen);
+
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ENABLEWEBSERVER), fEnableWebServer);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBSERVERPORT), nWebServerPort);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBSERVERPRINTDEBUGINFO), fWebServerPrintDebugInfo);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBSERVERUSECOMPRESSION), fWebServerUseCompression);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBSERVERLOCALHOSTONLY), fWebServerLocalhostOnly);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBROOT), WebRoot);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBDEFINDEX), WebDefIndex);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBSERVERCGI), WebServerCGI);
+
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SNAPSHOTPATH), SnapShotPath);
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SNAPSHOTEXT), SnapShotExt);
+
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_THUMBROWS), ThumbRows);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_THUMBCOLS), ThumbCols);
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_THUMBWIDTH), ThumbWidth);
+
+ pApp->WriteProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ISDB), ISDb);
+
+ pApp->WriteProfileString(_T("Shaders"), NULL, NULL);
+ pApp->WriteProfileInt(_T("Shaders"), _T("Initialized"), 1);
+ pApp->WriteProfileString(_T("Shaders"), _T("Combine"), m_shadercombine);
+
+ pos = m_shaders.GetHeadPosition();
+ for(int i = 0; pos; i++)
+ {
+ const Shader& s = m_shaders.GetNext(pos);
+
+ if(!s.label.IsEmpty())
+ {
+ CString index;
+ index.Format(_T("%d"), i);
+ CString srcdata = s.srcdata;
+ srcdata.Replace(_T("\r"), _T(""));
+ srcdata.Replace(_T("\n"), _T("\\n"));
+ srcdata.Replace(_T("\t"), _T("\\t"));
+ AfxGetApp()->WriteProfileString(_T("Shaders"), index, s.label + _T("|") + s.target + _T("|") + srcdata);
+ }
+ }
+
+ if(pApp->m_pszRegistryKey)
+ {
+ // WINBUG: on win2k this would crash WritePrivateProfileString
+ pApp->WriteProfileInt(_T(""), _T(""), pApp->GetProfileInt(_T(""), _T(""), 0)?0:1);
+ }
+ }
+ else
+ {
+ if(fInitialized) return;
+
+ if(pApp->m_pszRegistryKey)
+ {
+ CRegKey appkey, settingskey;
+ appkey.Attach(pApp->GetAppRegistryKey());
+ settingskey.Attach(pApp->GetSectionKey(ResStr(IDS_R_INTERNAL_FILTERS)));
+ if(appkey && settingskey)
+ {
+ ULONGLONG ftapp = 0, ftsettings = 0;
+ RegQueryInfoKey(appkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, (FILETIME*)&ftapp);
+ RegQueryInfoKey(settingskey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, (FILETIME*)&ftsettings);
+ if(ftapp < ftsettings)
+ {
+ pApp->WriteProfileInt(ResStr(IDS_R_INTERNAL_FILTERS), ResStr(IDS_RS_SRCFILTERS), ~0);
+ pApp->WriteProfileInt(ResStr(IDS_R_INTERNAL_FILTERS), ResStr(IDS_RS_TRAFILTERS), ~0^TRA_MPEG1);
+ }
+ }
+ }
+
+ OSVERSIONINFO vi;
+ vi.dwOSVersionInfoSize = sizeof(vi);
+ GetVersionEx(&vi);
+ fXpOrBetter = (vi.dwMajorVersion >= 5 && vi.dwMinorVersion >= 1 || vi.dwMajorVersion >= 6);
+
+ iDXVer = 0;
+ CRegKey dxver;
+ if(ERROR_SUCCESS == dxver.Open(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\DirectX"), KEY_READ))
+ {
+ CString str;
+ ULONG len = 64;
+ if(ERROR_SUCCESS == dxver.QueryStringValue(_T("Version"), str.GetBuffer(len), &len))
+ {
+ str.ReleaseBuffer(len);
+ int ver[4];
+ _stscanf(str, _T("%d.%d.%d.%d"), ver+0, ver+1, ver+2, ver+3);
+ iDXVer = ver[1];
+ }
+ }
+
+ fHideCaptionMenu = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_HIDECAPTIONMENU), 0);
+ nCS = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_CONTROLSTATE), CS_SEEKBAR|CS_TOOLBAR|CS_INFOBAR|CS_STATUSBAR);
+ iDefaultVideoSize = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DEFAULTVIDEOFRAME), DVS_FROMINSIDE);
+ fKeepAspectRatio = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_KEEPASPECTRATIO), TRUE);
+ fCompMonDeskARDiff = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_COMPMONDESKARDIFF), FALSE);
+ nVolume = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_VOLUME), 100);
+ nBalance = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_BALANCE), 0);
+ fMute = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_MUTE), 0);
+ nLoops = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LOOPNUM), 1);
+ fLoopForever = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LOOP), 1);
+ fRewind = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_REWIND), TRUE);
+ iZoomLevel = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ZOOM), 1);
+ iDSVideoRendererType = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DSVIDEORENDERERTYPE), VIDRNDT_DS_DEFAULT);
+ iRMVideoRendererType = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_RMVIDEORENDERERTYPE), VIDRNDT_RM_DEFAULT);
+ iQTVideoRendererType = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_QTVIDEORENDERERTYPE), VIDRNDT_QT_DEFAULT);
+ iAPSurfaceUsage = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_APSURACEFUSAGE), VIDRNDT_AP_TEXTURE2D);
+ fVMRSyncFix = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_VMRSYNCFIX), FALSE);
+ iDX9Resizer = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DX9_RESIZER), 1);
+ fVMR9MixerMode = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_VMR9MIXERMODE), FALSE);
+ fVMR9MixerYUV = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_VMR9MIXERYUV), FALSE);
+ AudioRendererDisplayName = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUDIORENDERERTYPE), _T(""));
+ fAutoloadAudio = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUTOLOADAUDIO), TRUE);
+ fAutoloadSubtitles = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUTOLOADSUBTITLES), TRUE);
+ fEnableWorkerThreadForOpening = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ENABLEWORKERTHREADFOROPENING), TRUE);
+ fReportFailedPins = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_REPORTFAILEDPINS), TRUE);
+ fAllowMultipleInst = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_MULTIINST), 0);
+ iTitleBarTextStyle = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_TITLEBARTEXTSTYLE), 1);
+ fTitleBarTextTitle = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_TITLEBARTEXTTITLE), FALSE);
+ iOnTop = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ONTOP), 0);
+ fTrayIcon = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_TRAYICON), 0);
+ fRememberZoomLevel = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUTOZOOM), 1);
+ fShowBarsWhenFullScreen = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_FULLSCREENCTRLS), 1);
+ nShowBarsWhenFullScreenTimeOut = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_FULLSCREENCTRLSTIMEOUT), 0);
+ if(pApp->GetProfileBinary(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_FULLSCREENRES), &ptr, &len))
+ {
+ memcpy(&dmFullscreenRes, ptr, sizeof(dmFullscreenRes));
+ delete [] ptr;
+ }
+ else
+ {
+ dmFullscreenRes.fValid = false;
+ }
+ fExitFullScreenAtTheEnd = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_EXITFULLSCREENATTHEEND), 0);
+ fRememberWindowPos = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_REMEMBERWINDOWPOS), 0);
+ fRememberWindowSize = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_REMEMBERWINDOWSIZE), 0);
+ fSnapToDesktopEdges = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SNAPTODESKTOPEDGES), 0);
+ AspectRatio.cx = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ASPECTRATIO_X), 0);
+ AspectRatio.cy = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ASPECTRATIO_Y), 0);
+ fKeepHistory = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_KEEPHISTORY), 1);
+ if(pApp->GetProfileBinary(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LASTWINDOWRECT), &ptr, &len))
+ {
+ memcpy(&rcLastWindowPos, ptr, sizeof(rcLastWindowPos));
+ delete [] ptr;
+ }
+ else
+ {
+ fRememberWindowPos = false;
+ }
+ lastWindowType = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LASTWINDOWTYPE), SIZE_RESTORED);
+ sDVDPath = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DVDPATH), _T(""));
+ fUseDVDPath = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_USEDVDPATH), 0);
+ idMenuLang = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_MENULANG), ::GetUserDefaultLCID());
+ idAudioLang = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUDIOLANG), ::GetUserDefaultLCID());
+ idSubtitlesLang = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SUBTITLESLANG), ::GetUserDefaultLCID());
+ fAutoSpeakerConf = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUTOSPEAKERCONF), 1);
+ // TODO: rename subdefstyle -> defStyle, IDS_RS_SPLOGFONT -> IDS_RS_SPSTYLE
+ subdefstyle <<= pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPLOGFONT), _T(""));
+ fOverridePlacement = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPOVERRIDEPLACEMENT), 0);
+ nHorPos = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPHORPOS), 50);
+ nVerPos = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPVERPOS), 90);
+ nSPCSize = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPCSIZE), 3);
+ nSPCMaxRes = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPCMAXRES), 2);
+ fSPCPow2Tex = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_POW2TEX), TRUE);
+ fEnableSubtitles = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ENABLESUBTITLES), TRUE);
+ fEnableAudioSwitcher = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ENABLEAUDIOSWITCHER), TRUE);
+ fAudioTimeShift = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ENABLEAUDIOTIMESHIFT), 0);
+ tAudioTimeShift = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUDIOTIMESHIFT), 0);
+ fDownSampleTo441 = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DOWNSAMPLETO441), 0);
+ fCustomChannelMapping = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_CUSTOMCHANNELMAPPING), 0);
+ if(pApp->GetProfileBinary(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SPEAKERTOCHANNELMAPPING), &ptr, &len))
+ {
+ memcpy(pSpeakerToChannelMap, ptr, sizeof(pSpeakerToChannelMap));
+ delete [] ptr;
+ }
+ else
+ {
+ memset(pSpeakerToChannelMap, 0, sizeof(pSpeakerToChannelMap));
+ for(int j = 0; j < 18; j++)
+ for(int i = 0; i <= j; i++)
+ pSpeakerToChannelMap[j][i] = 1<<i;
+
+ pSpeakerToChannelMap[0][0] = 1<<0;
+ pSpeakerToChannelMap[0][1] = 1<<0;
+
+ pSpeakerToChannelMap[3][0] = 1<<0;
+ pSpeakerToChannelMap[3][1] = 1<<1;
+ pSpeakerToChannelMap[3][2] = 0;
+ pSpeakerToChannelMap[3][3] = 0;
+ pSpeakerToChannelMap[3][4] = 1<<2;
+ pSpeakerToChannelMap[3][5] = 1<<3;
+
+ pSpeakerToChannelMap[4][0] = 1<<0;
+ pSpeakerToChannelMap[4][1] = 1<<1;
+ pSpeakerToChannelMap[4][2] = 1<<2;
+ pSpeakerToChannelMap[4][3] = 0;
+ pSpeakerToChannelMap[4][4] = 1<<3;
+ pSpeakerToChannelMap[4][5] = 1<<4;
+ }
+ fAudioNormalize = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUDIONORMALIZE), FALSE);
+ fAudioNormalizeRecover = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUDIONORMALIZERECOVER), TRUE);
+ AudioBoost = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_AUDIOBOOST), 1);
+
+ {
+ for(int i = 0; ; i++)
+ {
+ CString key;
+ key.Format(_T("%s\\%04d"), ResStr(IDS_R_FILTERS), i);
+
+ CAutoPtr<FilterOverride> f(new FilterOverride);
+
+ f->fDisabled = !pApp->GetProfileInt(key, _T("Enabled"), 0);
+
+ UINT j = pApp->GetProfileInt(key, _T("SourceType"), -1);
+ if(j == 0)
+ {
+ f->type = FilterOverride::REGISTERED;
+ f->dispname = CStringW(pApp->GetProfileString(key, _T("DisplayName"), _T("")));
+ f->name = pApp->GetProfileString(key, _T("Name"), _T(""));
+ }
+ else if(j == 1)
+ {
+ f->type = FilterOverride::EXTERNAL;
+ f->path = pApp->GetProfileString(key, _T("Path"), _T(""));
+ f->name = pApp->GetProfileString(key, _T("Name"), _T(""));
+ f->clsid = GUIDFromCString(pApp->GetProfileString(key, _T("CLSID"), _T("")));
+ }
+ else
+ {
+ pApp->WriteProfileString(key, NULL, 0);
+ break;
+ }
+
+ f->backup.RemoveAll();
+ for(int i = 0; ; i++)
+ {
+ CString val;
+ val.Format(_T("org%04d"), i);
+ CString guid = pApp->GetProfileString(key, val, _T(""));
+ if(guid.IsEmpty()) break;
+ f->backup.AddTail(GUIDFromCString(guid));
+ }
+
+ f->guids.RemoveAll();
+ for(int i = 0; ; i++)
+ {
+ CString val;
+ val.Format(_T("mod%04d"), i);
+ CString guid = pApp->GetProfileString(key, val, _T(""));
+ if(guid.IsEmpty()) break;
+ f->guids.AddTail(GUIDFromCString(guid));
+ }
+
+ f->iLoadType = (int)pApp->GetProfileInt(key, _T("LoadType"), -1);
+ if(f->iLoadType < 0) break;
+
+ f->dwMerit = pApp->GetProfileInt(key, _T("Merit"), MERIT_DO_NOT_USE+1);
+
+ filters.AddTail(f);
+ }
+ }
+
+ fIntRealMedia = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_INTREALMEDIA), 0);
+ //fRealMediaRenderless = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_REALMEDIARENDERLESS), 0);
+ //iQuickTimeRenderer = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_QUICKTIMERENDERER), 2);
+ RealMediaQuickTimeFPS = 25.0;
+ *((DWORD*)&RealMediaQuickTimeFPS) = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_REALMEDIAFPS), *((DWORD*)&RealMediaQuickTimeFPS));
+
+ m_pnspresets.RemoveAll();
+ for(int i = 0; i < (ID_PANNSCAN_PRESETS_END - ID_PANNSCAN_PRESETS_START); i++)
+ {
+ CString str;
+ str.Format(_T("Preset%d"), i);
+ str = pApp->GetProfileString(ResStr(IDS_R_SETTINGS) + _T("\\") + ResStr(IDS_RS_PNSPRESETS), str, _T(""));
+ if(str.IsEmpty()) break;
+ m_pnspresets.Add(str);
+ }
+ if(m_pnspresets.IsEmpty())
+ {
+ double _4p3 = 4.0/3.0;
+ double _16p9 = 16.0/9.0;
+ double _185p1 = 1.85/1.0;
+ double _235p1 = 2.35/1.0;
+
+ CString str;
+ str.Format(_T("Scale to 16:9 TV,%.3f,%.3f,%.3f,%.3f"), 0.5, 0.5, _4p3/_4p3, _16p9/_4p3);
+ m_pnspresets.Add(str);
+ str.Format(_T("Zoom To Widescreen,%.3f,%.3f,%.3f,%.3f"), 0.5, 0.5, _16p9/_4p3, _16p9/_4p3);
+ m_pnspresets.Add(str);
+ str.Format(_T("Zoom To Ultra-Widescreen,%.3f,%.3f,%.3f,%.3f"), 0.5, 0.5, _235p1/_4p3, _235p1/_4p3);
+ m_pnspresets.Add(str);
+ }
+
+ for(int i = 0; i < wmcmds.GetCount(); i++)
+ {
+ CString str;
+ str.Format(_T("CommandMod%d"), i);
+ str = pApp->GetProfileString(ResStr(IDS_R_COMMANDS), str, _T(""));
+ if(str.IsEmpty()) break;
+ int cmd, fVirt, key, repcnt, mouse, appcmd;
+ TCHAR buff[128];
+ int n;
+ if(5 > (n = _stscanf(str, _T("%d %x %x %s %d %d %d"), &cmd, &fVirt, &key, buff, &repcnt, &mouse, &appcmd)))
+ break;
+ if(POSITION pos = wmcmds.Find(cmd))
+ {
+ wmcmd& wc = wmcmds.GetAt(pos);
+ wc.cmd = cmd;
+ wc.fVirt = fVirt;
+ wc.key = key;
+ if(n >= 6) wc.mouse = (UINT)mouse;
+ if(n >= 7) wc.appcmd = (UINT)appcmd;
+ wc.rmcmd = CStringA(buff).Trim('\"');
+ wc.rmrepcnt = repcnt;
+ }
+ }
+
+ CAtlArray<ACCEL> pAccel;
+ pAccel.SetCount(wmcmds.GetCount());
+ POSITION pos = wmcmds.GetHeadPosition();
+ for(int i = 0; pos; i++) pAccel[i] = wmcmds.GetNext(pos);
+ hAccel = CreateAcceleratorTable(pAccel.GetData(), pAccel.GetCount());
+
+ WinLircAddr = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WINLIRCADDR), _T("127.0.0.1:8765"));
+ fWinLirc = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WINLIRC), 0);
+ UIceAddr = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_UICEADDR), _T("127.0.0.1:1234"));
+ fUIce = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_UICE), 0);
+
+ fDisabeXPToolbars = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DISABLEXPTOOLBARS), 0);
+ fUseWMASFReader = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_USEWMASFREADER), TRUE);
+ nJumpDistS = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_JUMPDISTS), 1000);
+ nJumpDistM = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_JUMPDISTM), 5000);
+ nJumpDistL = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_JUMPDISTL), 20000);
+ fFreeWindowResizing = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_FREEWINDOWRESIZING), TRUE);
+ fNotifyMSN = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_NOTIFYMSN), FALSE);
+ fNotifyGTSdll = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_NOTIFYGTSDLL), FALSE);
+
+ Formats.UpdateData(false);
+
+ SrcFilters = pApp->GetProfileInt(ResStr(IDS_R_INTERNAL_FILTERS), ResStr(IDS_RS_SRCFILTERS), ~0);
+ TraFilters = pApp->GetProfileInt(ResStr(IDS_R_INTERNAL_FILTERS), ResStr(IDS_RS_TRAFILTERS), ~0^TRA_MPEG1);
+
+ logofn = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LOGOFILE), _T(""));
+ logoid = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LOGOID), IDB_LOGO7);
+ logoext = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LOGOEXT), 0);
+
+ fHideCDROMsSubMenu = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_HIDECDROMSSUBMENU), 0);
+
+ priority = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_PRIORITY), NORMAL_PRIORITY_CLASS);
+ ::SetPriorityClass(::GetCurrentProcess(), priority);
+ launchfullscreen = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LAUNCHFULLSCREEN), FALSE);
+
+ fEnableWebServer = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ENABLEWEBSERVER), FALSE);
+ nWebServerPort = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBSERVERPORT), 13579);
+ fWebServerPrintDebugInfo = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBSERVERPRINTDEBUGINFO), FALSE);
+ fWebServerUseCompression = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBSERVERUSECOMPRESSION), TRUE);
+ fWebServerLocalhostOnly = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBSERVERLOCALHOSTONLY), TRUE);
+ WebRoot = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBROOT), _T("*./webroot"));
+ WebDefIndex = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBDEFINDEX), _T("index.html;index.php"));
+ WebServerCGI = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_WEBSERVERCGI), _T(""));
+
+ CString MyPictures;
+
+ CRegKey key;
+ // grrrrr
+ // if(!SHGetSpecialFolderPath(NULL, MyPictures.GetBufferSetLength(MAX_PATH), CSIDL_MYPICTURES, TRUE)) MyPictures.Empty();
+ // else MyPictures.ReleaseBuffer();
+ if(ERROR_SUCCESS == key.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"), KEY_READ))
+ {
+ ULONG len = MAX_PATH;
+ if(ERROR_SUCCESS == key.QueryStringValue(_T("My Pictures"), MyPictures.GetBuffer(MAX_PATH), &len)) MyPictures.ReleaseBufferSetLength(len);
+ else MyPictures.Empty();
+ }
+ SnapShotPath = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SNAPSHOTPATH), MyPictures);
+ SnapShotExt = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SNAPSHOTEXT), _T(".bmp"));
+
+ ThumbRows = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_THUMBROWS), 4);
+ ThumbCols = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_THUMBCOLS), 4);
+ ThumbWidth = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_THUMBWIDTH), 1024);
+
+ ISDb = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_ISDB), _T("isdb.go.dyndns.org"));
+
+ pApp->WriteProfileInt(ResStr(IDS_R_SETTINGS), _T("LastUsedPage"), 0);
+
+ //
+
+ m_shaders.RemoveAll();
+
+ CAtlStringMap<UINT> shaders;
+
+ shaders[_T("contour")] = IDF_SHADER_CONTOUR;
+ shaders[_T("deinterlace (blend)")] = IDF_SHADER_DEINTERLACE;
+ shaders[_T("emboss")] = IDF_SHADER_EMBOSS;
+ shaders[_T("grayscale")] = IDF_SHADER_GRAYSCALE;
+ shaders[_T("invert")] = IDF_SHADER_INVERT;
+ shaders[_T("letterbox")] = IDF_SHADER_LETTERBOX;
+ shaders[_T("procamp")] = IDF_SHADER_PROCAMP;
+ shaders[_T("sharpen")] = IDF_SHADER_SHARPEN;
+ shaders[_T("sphere")] = IDF_SHADER_SPHERE;
+ shaders[_T("spotlight")] = IDF_SHADER_SPOTLIGHT;
+ shaders[_T("wave")] = IDF_SHADER_WAVE;
+ shaders[_T("Edge Sharpen (jim.ro)")] = IDF_SHADER_EDGE_SHARPEN;
+ shaders[_T("Sharpen complex (jim.ro)")] = IDF_SHADER_SHARPEN_COMPLEX;
+
+ int iShader = 0;
+
+ for(; ; iShader++)
+ {
+ CString str;
+ str.Format(_T("%d"), iShader);
+ str = pApp->GetProfileString(_T("Shaders"), str);
+
+ CAtlList<CString> sl;
+ CString label = Explode(str, sl, '|');
+ if(label.IsEmpty()) break;
+ if(sl.GetCount() < 3) continue;
+
+ Shader s;
+ s.label = sl.RemoveHead();
+ s.target = sl.RemoveHead();
+ s.srcdata = sl.RemoveHead();
+ s.srcdata.Replace(_T("\\n"), _T("\n"));
+ s.srcdata.Replace(_T("\\t"), _T("\t"));
+ m_shaders.AddTail(s);
+
+ shaders.RemoveKey(s.label);
+ }
+
+ pos = shaders.GetStartPosition();
+ for(; pos; iShader++)
+ {
+ CAtlStringMap<UINT>::CPair* pPair = shaders.GetNext(pos);
+
+ CStringA srcdata;
+ if(LoadResource(pPair->m_value, srcdata, _T("FILE")))
+ {
+ Shader s;
+ s.label = pPair->m_key;
+ s.target = _T("ps_2_0");
+ s.srcdata = CString(srcdata);
+ m_shaders.AddTail(s);
+ }
+ }
+
+ // CASIMIR666 : nouveaux settings
+ fD3DFullscreen = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_D3DFULLSCREEN), FALSE);
+ fMonitorAutoRefreshRate = !!pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_MONITOR_AUTOREFRESHRATE), FALSE);
+
+ dBrightness = _tstof(pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_COLOR_BRIGHTNESS), _T("1")));
+ dContrast = _tstof(pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_COLOR_CONTRAST), _T("1")));
+ dHue = _tstof(pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_COLOR_HUE), _T("0")));
+ dSaturation = _tstof(pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_COLOR_SATURATION), _T("1")));
+ strShaderList = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_SHADERLIST), _T(""));
+
+ // Position de lecture des derniers DVD's
+ fRememberDVDPos = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_DVDPOS), 0);
+ nCurrentDvdPosition = -1;
+ memset (DvdPosition, 0, sizeof(DvdPosition));
+ for (int i=0; i<MAX_DVD_POSITION; i++)
+ {
+ CString strDVDPos;
+ CString strValue;
+
+ strDVDPos.Format (_T("DVD Position %d"), i);
+ strValue = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), strDVDPos, _T(""));
+ if (strValue.GetLength()/2 == sizeof(DVD_POSITION))
+ {
+ DeserializeHex(strValue, (BYTE*)&DvdPosition[i], sizeof(DVD_POSITION));
+ }
+ }
+
+ // Position de lecture des derniers fichiers
+ fRememberFilePos = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_FILEPOS), 0);
+ nCurrentFilePosition = -1;
+ for (int i=0; i<MAX_FILE_POSITION; i++)
+ {
+ CString strFilePos;
+ CString strValue;
+
+ strFilePos.Format (_T("File Name %d"), i);
+ FilePosition[i].strFile = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), strFilePos, _T(""));
+
+ strFilePos.Format (_T("File Position %d"), i);
+ strValue = pApp->GetProfileString(ResStr(IDS_R_SETTINGS), strFilePos, _T(""));
+ FilePosition[i].llPosition = _tstoi64 (strValue);
+ }
+
+ fLastFullScreen = pApp->GetProfileInt(ResStr(IDS_R_SETTINGS), ResStr(IDS_RS_LASTFULLSCREEN), 0);
+
+ // CASIMIR666 : fin nouveaux settings
+
+
+ // TODO: sort shaders by label
+
+ m_shadercombine = pApp->GetProfileString(_T("Shaders"), _T("Combine"), _T(""));
+
+ fInitialized = true;
+ }
+}
+
+void CMPlayerCApp::Settings::ParseCommandLine(CAtlList<CString>& cmdln)
+{
+ nCLSwitches = 0;
+ slFiles.RemoveAll();
+ slDubs.RemoveAll();
+ slSubs.RemoveAll();
+ slFilters.RemoveAll();
+ rtStart = 0;
+ fixedWindowSize.SetSize(0, 0);
+ iMonitor = 0;
+
+ if(launchfullscreen) nCLSwitches |= CLSW_FULLSCREEN;
+
+ POSITION pos = cmdln.GetHeadPosition();
+ while(pos)
+ {
+ CString param = cmdln.GetNext(pos);
+ if(param.IsEmpty()) continue;
+
+ if((param[0] == '-' || param[0] == '/') && param.GetLength() > 1)
+ {
+ CString sw = param.Mid(1).MakeLower();
+ if(sw == _T("open")) nCLSwitches |= CLSW_OPEN;
+ else if(sw == _T("play")) nCLSwitches |= CLSW_PLAY;
+ else if(sw == _T("fullscreen")) nCLSwitches |= CLSW_FULLSCREEN;
+ else if(sw == _T("minimized")) nCLSwitches |= CLSW_MINIMIZED;
+ else if(sw == _T("new")) nCLSwitches |= CLSW_NEW;
+ else if(sw == _T("help") || sw == _T("h") || sw == _T("?")) nCLSwitches |= CLSW_HELP;
+ else if(sw == _T("dub") && pos) slDubs.AddTail(cmdln.GetNext(pos));
+ else if(sw == _T("sub") && pos) slSubs.AddTail(cmdln.GetNext(pos));
+ else if(sw == _T("filter") && pos) slFilters.AddTail(cmdln.GetNext(pos));
+ else if(sw == _T("dvd")) nCLSwitches |= CLSW_DVD;
+ else if(sw == _T("cd")) nCLSwitches |= CLSW_CD;
+ else if(sw == _T("add")) nCLSwitches |= CLSW_ADD;
+ else if(sw == _T("regvid")) nCLSwitches |= CLSW_REGEXTVID;
+ else if(sw == _T("regaud")) nCLSwitches |= CLSW_REGEXTAUD;
+ else if(sw == _T("unregvid")) nCLSwitches |= CLSW_UNREGEXTVID;
+ else if(sw == _T("unregaud")) nCLSwitches |= CLSW_UNREGEXTAUD;
+ else if(sw == _T("start") && pos) {rtStart = 10000i64*_tcstol(cmdln.GetNext(pos), NULL, 10); nCLSwitches |= CLSW_STARTVALID;}
+ else if(sw == _T("startpos") && pos) {/* TODO: mm:ss. */;}
+ else if(sw == _T("nofocus")) nCLSwitches |= CLSW_NOFOCUS;
+ else if(sw == _T("close")) nCLSwitches |= CLSW_CLOSE;
+ else if(sw == _T("standby")) nCLSwitches |= CLSW_STANDBY;
+ else if(sw == _T("hibernate")) nCLSwitches |= CLSW_HIBERNATE;
+ else if(sw == _T("shutdown")) nCLSwitches |= CLSW_SHUTDOWN;
+ else if(sw == _T("logoff")) nCLSwitches |= CLSW_LOGOFF;
+ else if(sw == _T("fixedsize") && pos)
+ {
+ CAtlList<CString> sl;
+ Explode(cmdln.GetNext(pos), sl, ',', 2);
+ if(sl.GetCount() == 2)
+ {
+ fixedWindowSize.SetSize(_ttol(sl.GetHead()), _ttol(sl.GetTail()));
+ if(fixedWindowSize.cx > 0 && fixedWindowSize.cy > 0)
+ nCLSwitches |= CLSW_FIXEDSIZE;
+ }
+ }
+ else if(sw == _T("monitor") && pos) {iMonitor = _tcstol(cmdln.GetNext(pos), NULL, 10); nCLSwitches |= CLSW_MONITOR;}
+ else nCLSwitches |= CLSW_HELP|CLSW_UNRECOGNIZEDSWITCH;
+ }
+ else
+ {
+ slFiles.AddTail(param);
+ }
+ }
+}
+
+void CMPlayerCApp::Settings::GetFav(favtype ft, CAtlList<CString>& sl)
+{
+ sl.RemoveAll();
+
+ CString root;
+
+ switch(ft)
+ {
+ case FAV_FILE: root = ResStr(IDS_R_FAVFILES); break;
+ case FAV_DVD: root = ResStr(IDS_R_FAVDVDS); break;
+ case FAV_DEVICE: root = ResStr(IDS_R_FAVDEVICES); break;
+ default: return;
+ }
+
+ for(int i = 0; ; i++)
+ {
+ CString s;
+ s.Format(_T("Name%d"), i);
+ s = AfxGetApp()->GetProfileString(root, s, NULL);
+ if(s.IsEmpty()) break;
+ sl.AddTail(s);
+ }
+}
+
+void CMPlayerCApp::Settings::SetFav(favtype ft, CAtlList<CString>& sl)
+{
+ CString root;
+
+ switch(ft)
+ {
+ case FAV_FILE: root = ResStr(IDS_R_FAVFILES); break;
+ case FAV_DVD: root = ResStr(IDS_R_FAVDVDS); break;
+ case FAV_DEVICE: root = ResStr(IDS_R_FAVDEVICES); break;
+ default: return;
+ }
+
+ AfxGetApp()->WriteProfileString(root, NULL, NULL);
+
+ int i = 0;
+ POSITION pos = sl.GetHeadPosition();
+ while(pos)
+ {
+ CString s;
+ s.Format(_T("Name%d"), i++);
+ AfxGetApp()->WriteProfileString(root, s, sl.GetNext(pos));
+ }
+}
+
+void CMPlayerCApp::Settings::AddFav(favtype ft, CString s)
+{
+ CAtlList<CString> sl;
+ GetFav(ft, sl);
+ if(sl.Find(s)) return;
+ sl.AddTail(s);
+ SetFav(ft, sl);
+}
+
+// CMPlayerCApp::Settings::CRecentFileAndURLList
+
+CMPlayerCApp::Settings::CRecentFileAndURLList::CRecentFileAndURLList(UINT nStart, LPCTSTR lpszSection,
+ LPCTSTR lpszEntryFormat, int nSize,
+ int nMaxDispLen)
+ : CRecentFileList(nStart, lpszSection, lpszEntryFormat, nSize, nMaxDispLen)
+{
+}
+
+//#include <afximpl.h>
+extern BOOL AFXAPI AfxFullPath(LPTSTR lpszPathOut, LPCTSTR lpszFileIn);
+extern BOOL AFXAPI AfxComparePath(LPCTSTR lpszPath1, LPCTSTR lpszPath2);
+
+void CMPlayerCApp::Settings::CRecentFileAndURLList::Add(LPCTSTR lpszPathName)
+{
+ ASSERT(m_arrNames != NULL);
+ ASSERT(lpszPathName != NULL);
+ ASSERT(AfxIsValidString(lpszPathName));
+
+ if(CString(lpszPathName).MakeLower().Find(_T("@device:")) >= 0)
+ return;
+
+ bool fURL = (CString(lpszPathName).Find(_T("://")) >= 0);
+
+ // fully qualify the path name
+ TCHAR szTemp[1024];
+ if(fURL) _tcscpy(szTemp, lpszPathName);
+ else AfxFullPath(szTemp, lpszPathName);
+
+ // update the MRU list, if an existing MRU string matches file name
+ int iMRU;
+ for (iMRU = 0; iMRU < m_nSize-1; iMRU++)
+ {
+ if((fURL && !_tcscmp(m_arrNames[iMRU], szTemp))
+ || AfxComparePath(m_arrNames[iMRU], szTemp))
+ break; // iMRU will point to matching entry
+ }
+ // move MRU strings before this one down
+ for (; iMRU > 0; iMRU--)
+ {
+ ASSERT(iMRU > 0);
+ ASSERT(iMRU < m_nSize);
+ m_arrNames[iMRU] = m_arrNames[iMRU-1];
+ }
+ // place this one at the beginning
+ m_arrNames[0] = szTemp;
+}
+
+
+void CMPlayerCApp::OnHelpShowcommandlineswitches()
+{
+ ShowCmdlnSwitches();
+}
+
+//
+
+void GetCurDispMode(dispmode& dm)
+{
+ if(HDC hDC = ::GetDC(0))
+ {
+ dm.fValid = true;
+ dm.size = CSize(GetDeviceCaps(hDC, HORZRES), GetDeviceCaps(hDC, VERTRES));
+ dm.bpp = GetDeviceCaps(hDC, BITSPIXEL);
+ dm.freq = GetDeviceCaps(hDC, VREFRESH);
+ ::ReleaseDC(0, hDC);
+ }
+}
+
+bool GetDispMode(int i, dispmode& dm)
+{
+ DEVMODE devmode;
+ devmode.dmSize = sizeof(DEVMODE);
+ if(!EnumDisplaySettings(0, i, &devmode))
+ return(false);
+
+ dm.fValid = true;
+ dm.size = CSize(devmode.dmPelsWidth, devmode.dmPelsHeight);
+ dm.bpp = devmode.dmBitsPerPel;
+ dm.freq = devmode.dmDisplayFrequency;
+
+ return(true);
+}
+
+void SetDispMode(dispmode& dm)
+{
+ if(!dm.fValid) return;
+
+ DEVMODE dmScreenSettings;
+ memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
+ dmScreenSettings.dmSize = sizeof(dmScreenSettings);
+ dmScreenSettings.dmPelsWidth = dm.size.cx;
+ dmScreenSettings.dmPelsHeight = dm.size.cy;
+ dmScreenSettings.dmBitsPerPel = dm.bpp;
+ dmScreenSettings.dmDisplayFrequency = dm.freq;
+ dmScreenSettings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
+ ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
+}
+
+#include <afxsock.h>
+#include <atlsync.h>
+#include <atlutil.h> // put this before the first detours macro above to see an ICE with vc71 :)
+#include <atlrx.h>
+
+typedef CAtlRegExp<CAtlRECharTraits> CAtlRegExpT;
+typedef CAtlREMatchContext<CAtlRECharTraits> CAtlREMatchContextT;
+
+bool FindRedir(CUrl& src, CString ct, CString& body, CAtlList<CString>& urls, CAutoPtrList<CAtlRegExpT>& res)
+{
+ POSITION pos = res.GetHeadPosition();
+ while(pos)
+ {
+ CAtlRegExpT* re = res.GetNext(pos);
+
+ CAtlREMatchContextT mc;
+ const CAtlREMatchContextT::RECHAR* s = (LPCTSTR)body;
+ const CAtlREMatchContextT::RECHAR* e = NULL;
+ for(; s && re->Match(s, &mc, &e); s = e)
+ {
+ const CAtlREMatchContextT::RECHAR* szStart = 0;
+ const CAtlREMatchContextT::RECHAR* szEnd = 0;
+ mc.GetMatch(0, &szStart, &szEnd);
+
+ CString url;
+ url.Format(_T("%.*s"), szEnd - szStart, szStart);
+ url.Trim();
+
+ if(url.CompareNoCase(_T("asf path")) == 0) continue;
+
+ CUrl dst;
+ dst.CrackUrl(CString(url));
+ if(_tcsicmp(src.GetSchemeName(), dst.GetSchemeName())
+ || _tcsicmp(src.GetHostName(), dst.GetHostName())
+ || _tcsicmp(src.GetUrlPath(), dst.GetUrlPath()))
+ {
+ urls.AddTail(url);
+ }
+ else
+ {
+ // recursive
+ urls.RemoveAll();
+ break;
+ }
+ }
+ }
+
+ return urls.GetCount() > 0;
+}
+
+bool FindRedir(CString& fn, CString ct, CAtlList<CString>& fns, CAutoPtrList<CAtlRegExpT>& res)
+{
+ CString body;
+
+ CTextFile f(CTextFile::ANSI);
+ if(f.Open(fn)) for(CString tmp; f.ReadString(tmp); body += tmp + '\n');
+
+ CString dir = fn.Left(max(fn.ReverseFind('/'), fn.ReverseFind('\\'))+1); // "ReverseFindOneOf"
+
+ POSITION pos = res.GetHeadPosition();
+ while(pos)
+ {
+ CAtlRegExpT* re = res.GetNext(pos);
+
+ CAtlREMatchContextT mc;
+ const CAtlREMatchContextT::RECHAR* s = (LPCTSTR)body;
+ const CAtlREMatchContextT::RECHAR* e = NULL;
+ for(; s && re->Match(s, &mc, &e); s = e)
+ {
+ const CAtlREMatchContextT::RECHAR* szStart = 0;
+ const CAtlREMatchContextT::RECHAR* szEnd = 0;
+ mc.GetMatch(0, &szStart, &szEnd);
+
+ CString fn2;
+ fn2.Format(_T("%.*s"), szEnd - szStart, szStart);
+ fn2.Trim();
+
+ if(!fn2.CompareNoCase(_T("asf path"))) continue;
+ if(fn2.Find(_T("EXTM3U")) == 0 || fn2.Find(_T("#EXTINF")) == 0) continue;
+
+ if(fn2.Find(_T(":")) < 0 && fn2.Find(_T("\\\\")) != 0 && fn2.Find(_T("//")) != 0)
+ {
+ CPath p;
+ p.Combine(dir, fn2);
+ fn2 = (LPCTSTR)p;
+ }
+
+ if(!fn2.CompareNoCase(fn))
+ continue;
+
+ fns.AddTail(fn2);
+ }
+ }
+
+ return fns.GetCount() > 0;
+}
+
+CString GetContentType(CString fn, CAtlList<CString>* redir)
+{
+ CUrl url;
+ CString ct, body;
+
+ if(fn.Find(_T("://")) >= 0)
+ {
+ url.CrackUrl(fn);
+
+ if(_tcsicmp(url.GetSchemeName(), _T("pnm")) == 0)
+ return "audio/x-pn-realaudio";
+
+ if(_tcsicmp(url.GetSchemeName(), _T("mms")) == 0)
+ return "video/x-ms-asf";
+
+ if(_tcsicmp(url.GetSchemeName(), _T("http")) != 0)
+ return "";
+
+ DWORD ProxyEnable = 0;
+ CString ProxyServer;
+ DWORD ProxyPort = 0;
+
+ ULONG len = 256+1;
+ CRegKey key;
+ if(ERROR_SUCCESS == key.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"), KEY_READ)
+ && ERROR_SUCCESS == key.QueryDWORDValue(_T("ProxyEnable"), ProxyEnable) && ProxyEnable
+ && ERROR_SUCCESS == key.QueryStringValue(_T("ProxyServer"), ProxyServer.GetBufferSetLength(256), &len))
+ {
+ ProxyServer.ReleaseBufferSetLength(len);
+
+ CAtlList<CString> sl;
+ ProxyServer = Explode(ProxyServer, sl, ';');
+ if(sl.GetCount() > 1)
+ {
+ POSITION pos = sl.GetHeadPosition();
+ while(pos)
+ {
+ CAtlList<CString> sl2;
+ if(!Explode(sl.GetNext(pos), sl2, '=', 2).CompareNoCase(_T("http"))
+ && sl2.GetCount() == 2)
+ {
+ ProxyServer = sl2.GetTail();
+ break;
+ }
+ }
+ }
+
+ ProxyServer = Explode(ProxyServer, sl, ':');
+ if(sl.GetCount() > 1) ProxyPort = _tcstol(sl.GetTail(), NULL, 10);
+ }
+
+ CSocket s;
+ s.Create();
+ if(s.Connect(
+ ProxyEnable ? ProxyServer : url.GetHostName(),
+ ProxyEnable ? ProxyPort : url.GetPortNumber()))
+ {
+ CStringA host = CStringA(url.GetHostName());
+ CStringA path = CStringA(url.GetUrlPath()) + CStringA(url.GetExtraInfo());
+
+ if(ProxyEnable) path = "http://" + host + path;
+
+ CStringA hdr;
+ hdr.Format(
+ "GET %s HTTP/1.0\r\n"
+ "User-Agent: Media Player Classic\r\n"
+ "Host: %s\r\n"
+ "Accept: */*\r\n"
+ "\r\n", path, host);
+
+// MessageBox(NULL, CString(hdr), _T("Sending..."), MB_OK);
+
+ if(s.Send((LPCSTR)hdr, hdr.GetLength()) < hdr.GetLength()) return "";
+
+ hdr.Empty();
+ while(1)
+ {
+ CStringA str;
+ str.ReleaseBuffer(s.Receive(str.GetBuffer(256), 256)); // SOCKET_ERROR == -1, also suitable for ReleaseBuffer
+ if(str.IsEmpty()) break;
+ hdr += str;
+ int hdrend = hdr.Find("\r\n\r\n");
+ if(hdrend >= 0) {body = hdr.Mid(hdrend+4); hdr = hdr.Left(hdrend); break;}
+ }
+
+// MessageBox(NULL, CString(hdr), _T("Received..."), MB_OK);
+
+ CAtlList<CStringA> sl;
+ Explode(hdr, sl, '\n');
+ POSITION pos = sl.GetHeadPosition();
+ while(pos)
+ {
+ CStringA& hdrline = sl.GetNext(pos);
+ CAtlList<CStringA> sl2;
+ Explode(hdrline, sl2, ':', 2);
+ CStringA field = sl2.RemoveHead().MakeLower();
+ if(field == "location" && !sl2.IsEmpty())
+ return GetContentType(CString(sl2.GetHead()), redir);
+ if(field == "content-type" && !sl2.IsEmpty())
+ ct = sl2.GetHead();
+ }
+
+ while(body.GetLength() < 256)
+ {
+ CStringA str;
+ str.ReleaseBuffer(s.Receive(str.GetBuffer(256), 256)); // SOCKET_ERROR == -1, also suitable for ReleaseBuffer
+ if(str.IsEmpty()) break;
+ body += str;
+ }
+
+ if(body.GetLength() >= 8)
+ {
+ CStringA str = TToA(body);
+ if(!strncmp((LPCSTR)str, ".ra", 3))
+ return "audio/x-pn-realaudio";
+ if(!strncmp((LPCSTR)str, ".RMF", 4))
+ return "audio/x-pn-realaudio";
+ if(*(DWORD*)(LPCSTR)str == 0x75b22630)
+ return "video/x-ms-wmv";
+ if(!strncmp((LPCSTR)str+4, "moov", 4))
+ return "video/quicktime";
+ }
+
+ if(redir && (ct == _T("audio/x-scpls") || ct == _T("audio/x-mpegurl")))
+ {
+ while(body.GetLength() < 4*1024) // should be enough for a playlist...
+ {
+ CStringA str;
+ str.ReleaseBuffer(s.Receive(str.GetBuffer(256), 256)); // SOCKET_ERROR == -1, also suitable for ReleaseBuffer
+ if(str.IsEmpty()) break;
+ body += str;
+ }
+ }
+ }
+ }
+ else if(!fn.IsEmpty())
+ {
+ CPath p(fn);
+ CString ext = p.GetExtension().MakeLower();
+ if(ext == _T(".asx")) ct = _T("video/x-ms-asf");
+ else if(ext == _T(".pls")) ct = _T("audio/x-scpls");
+ else if(ext == _T(".m3u")) ct = _T("audio/x-mpegurl");
+ else if(ext == _T(".qtl")) ct = _T("application/x-quicktimeplayer");
+ else if(ext == _T(".mpcpl")) ct = _T("application/x-mpc-playlist");
+
+ if(FILE* f = _tfopen(fn, _T("rb")))
+ {
+ CStringA str;
+ str.ReleaseBufferSetLength(fread(str.GetBuffer(10240), 1, 10240, f));
+ body = AToT(str);
+ fclose(f);
+ }
+ }
+
+ if(body.GetLength() >= 4) // here only those which cannot be opened through dshow
+ {
+ CStringA str = TToA(body);
+ if(!strncmp((LPCSTR)str, ".ra", 3))
+ return "audio/x-pn-realaudio";
+ if(!strncmp((LPCSTR)str, "FWS", 3))
+ return "application/x-shockwave-flash";
+
+ }
+
+ if(redir && !ct.IsEmpty())
+ {
+ CAutoPtrList<CAtlRegExpT> res;
+ CAutoPtr<CAtlRegExpT> re;
+
+ if(ct == _T("video/x-ms-asf"))
+ {
+ // ...://..."/>
+ re.Attach(new CAtlRegExpT());
+ if(re && REPARSE_ERROR_OK == re->Parse(_T("{[a-zA-Z]+://[^\n\">]*}"), FALSE))
+ res.AddTail(re);
+ // Ref#n= ...://...\n
+ re.Attach(new CAtlRegExpT());
+ if(re && REPARSE_ERROR_OK == re->Parse(_T("Ref\\z\\b*=\\b*[\"]*{([a-zA-Z]+://[^\n\"]+}"), FALSE))
+ res.AddTail(re);
+ }
+ else if(ct == _T("audio/x-scpls"))
+ {
+ // File1=...\n
+ re.Attach(new CAtlRegExp<>());
+ if(re && REPARSE_ERROR_OK == re->Parse(_T("file\\z\\b*=\\b*[\"]*{[^\n\"]+}"), FALSE))
+ res.AddTail(re);
+ }
+ else if(ct == _T("audio/x-mpegurl"))
+ {
+ // #comment
+ // ...
+ re.Attach(new CAtlRegExp<>());
+ if(re && REPARSE_ERROR_OK == re->Parse(_T("{[^#][^\n]+}"), FALSE))
+ res.AddTail(re);
+ }
+ else if(ct == _T("audio/x-pn-realaudio"))
+ {
+ // rtsp://...
+ re.Attach(new CAtlRegExp<>());
+ if(re && REPARSE_ERROR_OK == re->Parse(_T("{rtsp://[^\n]+}"), FALSE))
+ res.AddTail(re);
+ }
+
+ if(!body.IsEmpty())
+ {
+ if(fn.Find(_T("://")) >= 0) FindRedir(url, ct, body, *redir, res);
+ else FindRedir(fn, ct, *redir, res);
+ }
+ }
+
+ return ct;
+}
+
+
+LONGLONG CMPlayerCApp::GetPerfCounter()
+{
+ LONGLONG i64TicksMicroSeconde;
+ if (m_PerfFrequency != 0)
+ {
+ QueryPerformanceCounter ((LARGE_INTEGER*)&i64TicksMicroSeconde);
+ i64TicksMicroSeconde = i64TicksMicroSeconde * 1000000;
+ i64TicksMicroSeconde = i64TicksMicroSeconde / m_PerfFrequency;
+
+ return i64TicksMicroSeconde;
+ }
+ return 0;
+}
+
+COLORPROPERTY_RANGE* CMPlayerCApp::GetColorControl(ControlType nFlag)
+{
+ switch (nFlag)
+ {
+ case Brightness :
+ return &m_ColorControl[0];
+ case Contrast :
+ return &m_ColorControl[1];
+ case Hue :
+ return &m_ColorControl[2];
+ case Saturation :
+ return &m_ColorControl[3];
+ }
+ return NULL;
+} \ No newline at end of file
diff --git a/src/apps/mplayerc/mplayerc.h b/src/apps/mplayerc/mplayerc.h
new file mode 100644
index 000000000..792fcc150
--- /dev/null
+++ b/src/apps/mplayerc/mplayerc.h
@@ -0,0 +1,580 @@
+/*
+ * Copyright (C) 2003-2006 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h" // main symbols
+#include <afxadv.h>
+#include <atlsync.h>
+#include "..\..\subtitles\STS.h"
+#include "MediaFormats.h"
+#include "fakefiltermapper2.h"
+
+#ifdef UNICODE
+#define MPC_WND_CLASS_NAME L"MediaPlayerClassicW"
+#else
+#define MPC_WND_CLASS_NAME "MediaPlayerClassicA"
+#endif
+
+enum
+{
+ WM_GRAPHNOTIFY = WM_APP+1,
+ WM_REARRANGERENDERLESS,
+ WM_RESUMEFROMSTATE
+};
+
+#define WM_MYMOUSELAST WM_XBUTTONDBLCLK
+
+///////////////
+
+extern void CorrectComboListWidth(CComboBox& box, CFont* pWndFont);
+extern HICON LoadIcon(CString fn, bool fSmall);
+extern bool LoadType(CString fn, CString& type);
+extern bool LoadResource(UINT resid, CStringA& str, LPCTSTR restype);
+extern CString GetContentType(CString fn, CAtlList<CString>* redir = NULL);
+
+/////////////////////////////////////////////////////////////////////////////
+// Casimir666
+//
+typedef enum
+{
+ Brightness = 0x1,
+ Contrast = 0x2,
+ Hue = 0x4,
+ Saturation = 0x8,
+} ControlType;
+
+typedef struct // _VMR9ProcAmpControlRange
+ {
+ DWORD dwSize;
+ DWORD dwProperty;
+ float MinValue;
+ float MaxValue;
+ float DefaultValue;
+ float StepSize;
+} COLORPROPERTY_RANGE;
+
+#define MAX_DVD_POSITION 5
+typedef struct
+{
+ ULONGLONG llDVDGuid;
+ ULONG lTitle;
+ DVD_HMSF_TIMECODE Timecode;
+} DVD_POSITION;
+
+#define MAX_FILE_POSITION 5
+typedef struct
+{
+ CString strFile;
+ LONGLONG llPosition;
+} FILE_POSITION;
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CMPlayerCApp:
+// See mplayerc.cpp for the implementation of this class
+//
+
+// flags for AppSettings::nCS
+enum
+{
+ CS_NONE=0,
+ CS_SEEKBAR=1,
+ CS_TOOLBAR=CS_SEEKBAR<<1,
+ CS_INFOBAR=CS_TOOLBAR<<1,
+ CS_STATSBAR=CS_INFOBAR<<1,
+ CS_STATUSBAR=CS_STATSBAR<<1,
+ CS_LAST=CS_STATUSBAR
+};
+
+enum
+{
+ CLSW_NONE=0,
+ CLSW_OPEN=1,
+ CLSW_PLAY=CLSW_OPEN<<1,
+ CLSW_CLOSE=CLSW_PLAY<<1,
+ CLSW_STANDBY=CLSW_CLOSE<<1,
+ CLSW_HIBERNATE=CLSW_STANDBY<<1,
+ CLSW_SHUTDOWN=CLSW_HIBERNATE<<1,
+ CLSW_LOGOFF=CLSW_SHUTDOWN<<1,
+ CLSW_AFTERPLAYBACK_MASK=CLSW_CLOSE|CLSW_STANDBY|CLSW_SHUTDOWN|CLSW_HIBERNATE|CLSW_LOGOFF,
+ CLSW_FULLSCREEN=CLSW_LOGOFF<<1,
+ CLSW_NEW=CLSW_FULLSCREEN<<1,
+ CLSW_HELP=CLSW_NEW<<1,
+ CLSW_DVD=CLSW_HELP<<1,
+ CLSW_CD=CLSW_DVD<<1,
+ CLSW_ADD=CLSW_CD<<1,
+ CLSW_MINIMIZED=CLSW_ADD<<1,
+ CLSW_REGEXTVID=CLSW_MINIMIZED<<1,
+ CLSW_REGEXTAUD=CLSW_REGEXTVID<<1,
+ CLSW_UNREGEXTVID=CLSW_REGEXTAUD<<1,
+ CLSW_UNREGEXTAUD=CLSW_UNREGEXTVID<<1,
+ CLSW_STARTVALID=CLSW_UNREGEXTAUD<<1,
+ CLSW_NOFOCUS=CLSW_STARTVALID<<1,
+ CLSW_FIXEDSIZE=CLSW_NOFOCUS<<1,
+ CLSW_MONITOR=CLSW_FIXEDSIZE<<1,
+ CLSW_UNRECOGNIZEDSWITCH=CLSW_MONITOR<<1
+};
+
+enum
+{
+ VIDRNDT_DS_DEFAULT,
+ VIDRNDT_DS_OLDRENDERER,
+ VIDRNDT_DS_OVERLAYMIXER,
+ VIDRNDT_DS_VMR7WINDOWED,
+ VIDRNDT_DS_VMR9WINDOWED,
+ VIDRNDT_DS_VMR7RENDERLESS,
+ VIDRNDT_DS_VMR9RENDERLESS,
+ VIDRNDT_DS_DXR,
+ VIDRNDT_DS_NULL_COMP,
+ VIDRNDT_DS_NULL_UNCOMP,
+};
+
+enum
+{
+ VIDRNDT_RM_DEFAULT,
+ VIDRNDT_RM_DX7,
+ VIDRNDT_RM_DX9,
+};
+
+enum
+{
+ VIDRNDT_QT_DEFAULT,
+ VIDRNDT_QT_DX7,
+ VIDRNDT_QT_DX9,
+};
+
+enum
+{
+ VIDRNDT_AP_SURFACE,
+ VIDRNDT_AP_TEXTURE2D,
+ VIDRNDT_AP_TEXTURE3D,
+};
+
+#define AUDRNDT_NULL_COMP _T("Null Audio Renderer (Any)")
+#define AUDRNDT_NULL_UNCOMP _T("Null Audio Renderer (Uncompressed)")
+
+enum
+{
+ SRC_CDDA=1,
+ SRC_CDXA=SRC_CDDA<<1,
+ SRC_VTS=SRC_CDXA<<1,
+ SRC_FLIC=SRC_VTS<<1,
+ SRC_D2V=SRC_FLIC<<1,
+ SRC_DTSAC3=SRC_D2V<<1,
+ SRC_MATROSKA=SRC_DTSAC3<<1,
+ SRC_SHOUTCAST=SRC_MATROSKA<<1,
+ SRC_REALMEDIA=SRC_SHOUTCAST<<1,
+ SRC_AVI=SRC_REALMEDIA<<1,
+ SRC_RADGT=SRC_AVI<<1,
+ SRC_ROQ=SRC_RADGT<<1,
+ SRC_OGG=SRC_ROQ<<1,
+ SRC_NUT=SRC_OGG<<1,
+ SRC_MPEG=SRC_NUT<<1,
+ SRC_DIRAC=SRC_MPEG<<1,
+ SRC_MPA=SRC_DIRAC<<1,
+ SRC_DSM=SRC_MPA<<1,
+ SRC_SUBS=SRC_DSM<<1,
+ SRC_MP4=SRC_SUBS<<1,
+ SRC_LAST=SRC_MP4<<1
+};
+
+enum
+{
+ TRA_MPEG1=1,
+ TRA_MPEG2=TRA_MPEG1<<1,
+ TRA_RV=TRA_MPEG2<<1,
+ TRA_RA=TRA_RV<<1,
+ TRA_MPA=TRA_RA<<1,
+ TRA_LPCM=TRA_MPA<<1,
+ TRA_AC3=TRA_LPCM<<1,
+ TRA_DTS=TRA_AC3<<1,
+ TRA_AAC=TRA_DTS<<1,
+ TRA_PS2AUD=TRA_AAC<<1,
+ TRA_DIRAC=TRA_PS2AUD<<1,
+ TRA_VORBIS=TRA_DIRAC<<1,
+ TRA_FLV4=TRA_VORBIS<<1,
+ TRA_VP62=TRA_FLV4<<1,
+ TRA_LAST=TRA_VP62<<1
+};
+
+enum
+{
+ DVS_HALF,
+ DVS_NORMAL,
+ DVS_DOUBLE,
+ DVS_STRETCH,
+ DVS_FROMINSIDE,
+ DVS_FROMOUTSIDE
+};
+
+typedef enum
+{
+ FAV_FILE,
+ FAV_DVD,
+ FAV_DEVICE
+} favtype;
+
+#pragma pack(push, 1)
+typedef struct
+{
+ bool fValid;
+ CSize size;
+ int bpp, freq;
+} dispmode;
+
+class wmcmd : public ACCEL
+{
+ ACCEL backup;
+ UINT appcmdorg;
+ UINT mouseorg;
+public:
+ CString name;
+ UINT appcmd;
+ enum {NONE,LDOWN,LUP,LDBLCLK,MDOWN,MUP,MDBLCLK,RDOWN,RUP,RDBLCLK,X1DOWN,X1UP,X1DBLCLK,X2DOWN,X2UP,X2DBLCLK,WUP,WDOWN,LAST};
+ UINT mouse;
+ CStringA rmcmd;
+ int rmrepcnt;
+ wmcmd(WORD cmd = 0) {this->cmd = cmd;}
+ wmcmd(WORD cmd, WORD key, BYTE fVirt, LPCTSTR name, UINT appcmd = 0, UINT mouse = NONE, LPCSTR rmcmd = "", int rmrepcnt = 5)
+ {
+ this->cmd = cmd;
+ this->key = key;
+ this->fVirt = fVirt;
+ this->appcmd = appcmdorg = appcmd;
+ this->name = name;
+ this->mouse = mouseorg = mouse;
+ this->rmcmd = rmcmd;
+ this->rmrepcnt = rmrepcnt;
+ backup = *this;
+ }
+ bool operator == (const wmcmd& wc) const
+ {
+ return(cmd > 0 && cmd == wc.cmd);
+ }
+ void Restore() {*(ACCEL*)this = backup; appcmd = appcmdorg; mouse = mouseorg; rmcmd.Empty(); rmrepcnt = 5;}
+ bool IsModified() {return(memcmp((const ACCEL*)this, &backup, sizeof(ACCEL)) || appcmd != appcmdorg || mouse != mouseorg || !rmcmd.IsEmpty() || rmrepcnt != 5);}
+};
+#pragma pack(pop)
+
+#include <afxsock.h>
+
+class CRemoteCtrlClient : public CAsyncSocket
+{
+protected:
+ CCritSec m_csLock;
+ CWnd* m_pWnd;
+ enum {DISCONNECTED, CONNECTED, CONNECTING} m_nStatus;
+ CString m_addr;
+
+ virtual void OnConnect(int nErrorCode);
+ virtual void OnClose(int nErrorCode);
+ virtual void OnReceive(int nErrorCode);
+
+ virtual void OnCommand(CStringA str) = 0;
+
+ void ExecuteCommand(CStringA cmd, int repcnt);
+
+public:
+ CRemoteCtrlClient();
+ void SetHWND(HWND hWnd);
+ void Connect(CString addr);
+ int GetStatus() {return(m_nStatus);}
+};
+
+class CWinLircClient : public CRemoteCtrlClient
+{
+protected:
+ virtual void OnCommand(CStringA str);
+
+public:
+ CWinLircClient();
+};
+
+class CUIceClient : public CRemoteCtrlClient
+{
+protected:
+ virtual void OnCommand(CStringA str);
+
+public:
+ CUIceClient();
+};
+
+extern void GetCurDispMode(dispmode& dm);
+extern bool GetDispMode(int i, dispmode& dm);
+extern void SetDispMode(dispmode& dm);
+
+class CMPlayerCApp : public CWinApp
+{
+ ATL::CMutex m_mutexOneInstance;
+
+ CAtlList<CString> m_cmdln;
+ void PreProcessCommandLine();
+ void SendCommandLine(HWND hWnd);
+
+ // === CASIMIR666 : Ajout CMPlayerCApp
+ COLORPROPERTY_RANGE m_ColorControl[4];
+
+public:
+ CMPlayerCApp();
+
+ void ShowCmdlnSwitches();
+
+ bool StoreSettingsToIni();
+ bool StoreSettingsToRegistry();
+ CString GetIniPath();
+ bool IsIniValid();
+
+ bool GetAppDataPath(CString& path);
+
+ // === CASIMIR666 : Ajout CMPlayerCApp
+ bool m_fTearingTest;
+ LONGLONG m_PerfFrequency;
+
+ LONGLONG GetPerfCounter();
+ COLORPROPERTY_RANGE* GetColorControl(ControlType nFlag);
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CMPlayerCApp)
+ public:
+ virtual BOOL InitInstance();
+ virtual int ExitInstance();
+ //}}AFX_VIRTUAL
+
+// Implementation
+
+ class Settings
+ {
+ friend class CMPlayerCApp;
+
+ bool fInitialized;
+
+ class CRecentFileAndURLList : public CRecentFileList
+ {
+ public:
+ CRecentFileAndURLList(UINT nStart, LPCTSTR lpszSection,
+ LPCTSTR lpszEntryFormat, int nSize,
+ int nMaxDispLen = AFX_ABBREV_FILENAME_LEN);
+
+ virtual void Add(LPCTSTR lpszPathName); // we have to override CRecentFileList::Add because the original version can't handle URLs
+ };
+
+ public:
+ // cmdline params
+ int nCLSwitches;
+ CAtlList<CString> slFiles, slDubs, slSubs, slFilters;
+ __int64 rtStart;
+ CSize fixedWindowSize;
+ bool HasFixedWindowSize() {return fixedWindowSize.cx > 0 || fixedWindowSize.cy > 0;}
+ // int iFixedWidth, iFixedHeight;
+ int iMonitor;
+
+ void ParseCommandLine(CAtlList<CString>& cmdln);
+
+ bool fXpOrBetter;
+ int iDXVer;
+
+ int nCS;
+ bool fHideCaptionMenu;
+ int iDefaultVideoSize;
+ bool fKeepAspectRatio;
+ bool fCompMonDeskARDiff;
+
+ CRecentFileAndURLList MRU;
+ CRecentFileAndURLList MRUDub;
+
+ CAutoPtrList<FilterOverride> filters;
+
+ int iDSVideoRendererType;
+ int iRMVideoRendererType;
+ int iQTVideoRendererType;
+ int iAPSurfaceUsage;
+ bool fVMRSyncFix;
+ int iDX9Resizer;
+ bool fVMR9MixerMode;
+ bool fVMR9MixerYUV;
+
+ int nVolume;
+ int nBalance;
+ bool fMute;
+ int nLoops;
+ bool fLoopForever;
+ bool fRewind;
+ int iZoomLevel;
+ // int iVideoRendererType;
+ CStringW AudioRendererDisplayName;
+ bool fAutoloadAudio;
+ bool fAutoloadSubtitles;
+ bool fEnableWorkerThreadForOpening;
+ bool fReportFailedPins;
+
+ bool fAllowMultipleInst;
+ int iTitleBarTextStyle;
+ bool fTitleBarTextTitle;
+ int iOnTop;
+ bool fTrayIcon;
+ bool fRememberZoomLevel;
+ bool fShowBarsWhenFullScreen;
+ int nShowBarsWhenFullScreenTimeOut;
+ dispmode dmFullscreenRes;
+ bool fExitFullScreenAtTheEnd;
+ bool fRememberWindowPos;
+ bool fRememberWindowSize;
+ bool fSnapToDesktopEdges;
+ CRect rcLastWindowPos;
+ UINT lastWindowType;
+ CSize AspectRatio;
+ bool fKeepHistory;
+
+ CString sDVDPath;
+ bool fUseDVDPath;
+ LCID idMenuLang, idAudioLang, idSubtitlesLang;
+ bool fAutoSpeakerConf;
+
+ STSStyle subdefstyle;
+ bool fOverridePlacement;
+ int nHorPos, nVerPos;
+ int nSPCSize;
+ int nSPCMaxRes;
+ bool fSPCPow2Tex;
+ bool fEnableSubtitles;
+
+ bool fDisabeXPToolbars;
+ bool fUseWMASFReader;
+ int nJumpDistS;
+ int nJumpDistM;
+ int nJumpDistL;
+ bool fFreeWindowResizing;
+ bool fNotifyMSN;
+ bool fNotifyGTSdll;
+
+ bool fEnableAudioSwitcher;
+ bool fDownSampleTo441;
+ bool fAudioTimeShift;
+ int tAudioTimeShift;
+ bool fCustomChannelMapping;
+ DWORD pSpeakerToChannelMap[18][18];
+ bool fAudioNormalize;
+ bool fAudioNormalizeRecover;
+ float AudioBoost;
+
+ bool fIntRealMedia;
+ // bool fRealMediaRenderless;
+ int iQuickTimeRenderer;
+ float RealMediaQuickTimeFPS;
+
+ CStringArray m_pnspresets;
+
+ CList<wmcmd> wmcmds;
+ HACCEL hAccel;
+
+ bool fWinLirc;
+ CString WinLircAddr;
+ CWinLircClient WinLircClient;
+ bool fUIce;
+ CString UIceAddr;
+ CUIceClient UIceClient;
+
+ CMediaFormats Formats;
+
+ UINT SrcFilters, TraFilters;
+
+ CString logofn;
+ UINT logoid;
+ bool logoext;
+
+ bool fHideCDROMsSubMenu;
+
+ DWORD priority;
+ bool launchfullscreen;
+
+ BOOL fEnableWebServer;
+ int nWebServerPort;
+ bool fWebServerPrintDebugInfo;
+ bool fWebServerUseCompression;
+ bool fWebServerLocalhostOnly;
+ CString WebRoot, WebDefIndex;
+ CString WebServerCGI;
+
+ CString SnapShotPath, SnapShotExt;
+ int ThumbRows, ThumbCols, ThumbWidth;
+
+ CString ISDb;
+
+ struct Shader {CString label, target, srcdata;};
+ CAtlList<Shader> m_shaders;
+ CString m_shadercombine;
+
+ // === CASIMIR666 : nouveau settings
+ bool fD3DFullscreen;
+ bool fMonitorAutoRefreshRate;
+ bool fLastFullScreen;
+ float dBrightness;
+ float dContrast;
+ float dHue;
+ float dSaturation;
+ CString strShaderList;
+
+ bool fRememberDVDPos;
+ bool fRememberFilePos;
+
+
+ DVD_POSITION* CurrentDVDPosition();
+ bool NewDvd(ULONGLONG llDVDGuid);
+ FILE_POSITION* CurrentFilePosition();
+ bool NewFile(LPCTSTR strFileName);
+
+ void DeserializeHex (LPCTSTR strVal, BYTE* pBuffer, int nBufSize);
+ CString SerializeHex (BYTE* pBuffer, int nBufSize);
+
+ private :
+ DVD_POSITION DvdPosition[MAX_DVD_POSITION];
+ int nCurrentDvdPosition;
+ FILE_POSITION FilePosition[MAX_FILE_POSITION];
+ int nCurrentFilePosition;
+
+
+ public:
+ Settings();
+ virtual ~Settings();
+ void UpdateData(bool fSave);
+
+ void GetFav(favtype ft, CAtlList<CString>& sl);
+ void SetFav(favtype ft, CAtlList<CString>& sl);
+ void AddFav(favtype ft, CString s);
+ } m_s;
+
+public:
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnAppAbout();
+ afx_msg void OnFileExit();
+ afx_msg void OnHelpShowcommandlineswitches();
+};
+
+#define AfxGetMyApp() ((CMPlayerCApp*)AfxGetApp())
+#define AfxGetAppSettings() ((CMPlayerCApp*)AfxGetApp())->m_s
+#define AppSettings CMPlayerCApp::Settings
diff --git a/src/apps/mplayerc/mplayerc.ncb b/src/apps/mplayerc/mplayerc.ncb
new file mode 100644
index 000000000..940bbfc4f
--- /dev/null
+++ b/src/apps/mplayerc/mplayerc.ncb
Binary files differ
diff --git a/src/apps/mplayerc/mplayerc.rc b/src/apps/mplayerc/mplayerc.rc
new file mode 100644
index 000000000..014999ae4
--- /dev/null
+++ b/src/apps/mplayerc/mplayerc.rc
@@ -0,0 +1,2825 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#endif\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_SELECTMEDIATYPE DIALOGEX 0, 0, 225, 47
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Select Media Type"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ COMBOBOX IDC_COMBO1,7,7,211,120,CBS_DROPDOWN | WS_VSCROLL |
+ WS_TABSTOP
+ DEFPUSHBUTTON "OK",IDOK,114,26,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,168,26,50,14
+END
+
+IDD_OPENCAPDEVICE_DLG DIALOGEX 0, 0, 226, 131
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Select Capture Device"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "The following input devices were found on your system:",
+ IDC_STATIC,12,7,200,11
+ LTEXT "Video",IDC_STATIC,12,23,18,8
+ COMBOBOX IDC_COMBO1,47,20,165,30,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ WS_VSCROLL | WS_TABSTOP
+ LTEXT "Audio",IDC_STATIC,12,41,19,8
+ COMBOBOX IDC_COMBO2,47,38,165,30,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "OK",IDOK,60,110,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,115,110,50,14
+ LTEXT "Some capture cards can output audio directly and not through the audio card. In that case you can leave the audio input selection empty.",
+ IDC_STATIC,12,76,200,24
+ LTEXT "Country",IDC_STATIC,12,58,27,8
+ COMBOBOX IDC_COMBO9,47,56,165,102,CBS_DROPDOWNLIST |
+ CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+END
+
+IDD_CAPTURE_DLG DIALOGEX 0, 0, 127, 289
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "Video",IDC_STATIC1,3,1,116,59
+ COMBOBOX IDC_COMBO4,10,10,62,116,CBS_DROPDOWNLIST | WS_DISABLED |
+ WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_EDIT3,74,10,38,13,ES_RIGHT | ES_AUTOHSCROLL |
+ WS_DISABLED
+ COMBOBOX IDC_COMBO1,10,26,37,89,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_COMBO5,50,26,62,89,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_EDIT1,10,43,37,13,ES_RIGHT | ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS | WS_DISABLED,35,46,11,14
+ EDITTEXT IDC_EDIT2,50,43,35,13,ES_RIGHT | ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN2,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS | WS_DISABLED,74,46,11,14
+ PUSHBUTTON "Set",IDC_BUTTON1,89,43,23,13
+ GROUPBOX "Audio",IDC_STATIC,3,61,116,43
+ COMBOBOX IDC_COMBO3,10,71,62,99,CBS_DROPDOWNLIST | WS_DISABLED |
+ WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_COMBO2,74,71,38,98,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_COMBO6,10,87,102,118,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Output",IDC_STATIC,3,105,116,171
+ CONTROL "Record Video",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,10,114,58,10
+ CONTROL "Preview",IDC_CHECK2,"Button",BS_AUTO3STATE | WS_TABSTOP,
+ 72,114,41,10
+ COMBOBOX IDC_COMBO7,10,126,102,62,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ COMBOBOX IDC_COMBO9,10,142,37,89,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_COMBO10,50,142,62,89,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,10,158,104,1
+ CONTROL "Record Audio",IDC_CHECK3,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,10,161,59,10
+ CONTROL "Preview",IDC_CHECK4,"Button",BS_AUTO3STATE | WS_TABSTOP,
+ 72,161,41,10
+ COMBOBOX IDC_COMBO8,10,173,102,62,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ COMBOBOX IDC_COMBO12,10,189,37,98,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_COMBO11,50,189,62,118,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,10,205,104,1
+ LTEXT "V/A Buffers:",IDC_STATIC,10,211,40,8
+ EDITTEXT IDC_EDIT5,52,209,28,12,ES_CENTER | ES_AUTOHSCROLL |
+ ES_NUMBER
+ EDITTEXT IDC_EDIT6,83,209,28,12,ES_CENTER | ES_AUTOHSCROLL |
+ ES_NUMBER
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,10,225,104,1
+ EDITTEXT IDC_EDIT4,10,231,86,13,ES_AUTOHSCROLL | ES_READONLY
+ PUSHBUTTON "...",IDC_BUTTON3,98,231,14,13
+ CONTROL "Audio to wav",IDC_CHECK5,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,10,260,55,10
+ PUSHBUTTON "Record",IDC_BUTTON2,74,259,38,13,WS_DISABLED | WS_GROUP
+ COMBOBOX IDC_COMBO14,10,245,102,52,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+END
+
+IDD_PPAGEAUDIOSWITCHER DIALOGEX 0, 0, 296, 198
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "Enable built-in audio switcher filter (needs re-opening, disables morgan switcher)",
+ IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,5,273,
+ 10
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,18,282,1
+ CONTROL "Down-sample to 44100 Hz",IDC_CHECK3,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,35,99,10
+ CONTROL "Audio time shift (ms):",IDC_CHECK4,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,48,82,10
+ EDITTEXT IDC_EDIT2,96,47,46,13,ES_AUTOHSCROLL,WS_EX_RIGHT
+ CONTROL "",IDC_SPIN2,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS | UDS_HOTTRACK,144,46,11,14
+ CONTROL "Enable custom channel mapping",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,61,117,10
+ LTEXT "Speaker configuration for ",IDC_STATIC1,7,76,84,8
+ EDITTEXT IDC_EDIT1,95,74,29,13,ES_CENTER | ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_WRAP |
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,183,73,11,
+ 14
+ LTEXT "input channels:",IDC_STATIC2,131,76,51,8
+ CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT |
+ LVS_OWNERDRAWFIXED | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER |
+ WS_BORDER | WS_TABSTOP,7,93,282,94
+ CTEXT "Hold shift for immediate changes when clicking something ",
+ IDC_STATIC3,7,189,282,8
+ CONTROL "Normalize",IDC_CHECK5,"Button",BS_AUTOCHECKBOX |
+ WS_GROUP | WS_TABSTOP,7,23,47,8
+ LTEXT "Boost:",IDC_STATIC,129,23,19,8
+ CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,152,23,137,11
+ CONTROL "Regain volume",IDC_CHECK6,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,59,22,59,10
+END
+
+IDD_GOTO_DLG DIALOGEX 0, 0, 157, 113
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Go To..."
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Enter at most four numbers separated by anything but digits. One number only means ms, two numbers mean sec and ms, etc.",
+ IDC_STATIC,7,7,143,27
+ LTEXT "Time",IDC_STATIC,7,40,16,8
+ EDITTEXT IDC_EDIT1,31,37,83,14,ES_AUTOHSCROLL
+ DEFPUSHBUTTON "Go!",IDC_OK1,119,37,31,14
+ LTEXT "Enter two numbers to jump to a specified frame, the first is the frame number, the second is the frame-rate.",
+ IDC_STATIC,7,62,143,26
+ LTEXT "Frame",IDC_STATIC,7,95,20,8
+ EDITTEXT IDC_EDIT2,31,92,83,14,ES_AUTOHSCROLL
+ DEFPUSHBUTTON "Go!",IDC_OK2,119,92,31,14
+END
+
+IDD_OPEN_DLG DIALOGEX 0, 0, 241, 87
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Open"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ ICON IDR_MAINFRAME,IDC_STATIC,9,8,21,20
+ LTEXT "Type the address of a movie or audio file (on the Internet or your computer) and the player will open it for you.",
+ IDC_STATIC1,33,9,149,28
+ LTEXT "Open:",IDC_STATIC,7,52,21,8
+ COMBOBOX IDC_COMBO1,33,50,149,76,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "Browse...",IDC_BUTTON1,187,49,47,14
+ LTEXT "Dub:",IDC_STATIC,7,71,16,8
+ COMBOBOX IDC_COMBO2,33,68,149,20,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "Browse...",IDC_BUTTON2,187,67,47,14
+ DEFPUSHBUTTON "OK",IDOK,187,9,47,14,WS_GROUP
+ PUSHBUTTON "Cancel",IDCANCEL,187,25,47,14
+ CONTROL "Add to playlist without opening",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,33,37,115,10
+END
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 222, 89
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "About"
+FONT 8, "MS Shell Dlg", 400, 0, 0xB1
+BEGIN
+ ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
+ LTEXT "Media Player Classic",IDC_STATIC1,40,10,126,8,
+ SS_NOPREFIX
+ LTEXT "Copyright (C) 2002-2006 Gabest",IDC_STATIC,40,21,113,8
+ LTEXT "Version: 6.4.8.8",IDC_STATIC,40,33,92,8
+ PUSHBUTTON "OK",IDOK,160,8,50,14,WS_GROUP
+ LTEXT "This program is freeware and released under the GNU General Public License.\nDistribution in Codec Packs is allowed, but the author (Gabest) is not liable for the additional content.",
+ IDC_STATIC,11,47,199,34
+END
+
+IDD_PLAYERSTATUSBAR DIALOGEX 0, 0, 183, 15
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+END
+
+IDD_PLAYERSEEKBAR DIALOGEX 0, 0, 254, 12
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+END
+
+IDD_PLAYERINFOBAR DIALOGEX 0, 0, 183, 12
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+END
+
+IDD_PPAGEPLAYER DIALOGEX 0, 0, 296, 198
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "Open options",IDC_STATIC,5,7,117,119
+ CONTROL "Use the same player for each media file",IDC_RADIO1,
+ "Button",BS_AUTORADIOBUTTON | BS_MULTILINE | WS_GROUP,15,
+ 20,93,20
+ CONTROL "Open a new player for each media file played",
+ IDC_RADIO2,"Button",BS_AUTORADIOBUTTON | BS_MULTILINE,15,
+ 63,98,15
+ ICON IDI_SINGLE,IDC_STATIC,51,40,20,20,SS_CENTERIMAGE
+ ICON IDI_MULTI,IDC_STATIC,51,84,20,20,SS_CENTERIMAGE
+ CONTROL "Launch files in fullscreen",IDC_CHECK11,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,15,109,93,10
+ GROUPBOX "Title bar",IDC_STATIC,5,130,117,61
+ CONTROL "Display full path",IDC_RADIO3,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP,16,143,67,10
+ CONTROL "File name only",IDC_RADIO4,"Button",BS_AUTORADIOBUTTON,
+ 16,154,61,10
+ CONTROL "Don't prefix anything",IDC_RADIO5,"Button",
+ BS_AUTORADIOBUTTON,16,165,83,10
+ GROUPBOX "Other",IDC_STATIC,130,7,159,184,WS_GROUP
+ CONTROL "Always on top",IDC_CHECK2,"Button",BS_AUTO3STATE |
+ WS_GROUP | WS_TABSTOP,140,19,61,10
+ CONTROL "Tray icon",IDC_CHECK3,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,140,32,45,10
+ CONTROL "Show controls in fullscreen for",IDC_CHECK4,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,140,45,112,10
+ EDITTEXT IDC_EDIT1,152,60,32,13,ES_CENTER | ES_AUTOHSCROLL |
+ ES_READONLY | ES_NUMBER
+ CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS | UDS_HOTTRACK,175,61,11,14
+ LTEXT "sec(s)",IDC_STATIC1,188,62,20,8
+ LTEXT "0: auto-hide\n-1: don't hide",IDC_STATIC2,218,58,48,17
+ CONTROL "Exit fullscreen at the end of playback",IDC_CHECK5,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,140,79,135,10
+ CONTROL "Remember last window position",IDC_CHECK6,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,140,92,127,10
+ CONTROL "Remember last window size",IDC_CHECK7,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,140,105,127,10
+ CONTROL "Snap to desktop edges",IDC_CHECK12,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,140,118,89,10
+ CONTROL "Store settings to .ini file",IDC_CHECK8,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,140,131,92,10
+ CONTROL "Keep history of recently opened files",IDC_CHECK1,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,140,144,133,10
+ CONTROL "Hide CD-ROMs menu",IDC_CHECK10,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,140,157,82,10
+ CONTROL "Process priority above normal",IDC_CHECK9,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,140,170,111,10
+ CONTROL "Replace file name with title",IDC_CHECK13,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,15,177,101,10
+END
+
+IDD_PPAGEDVD DIALOGEX 0, 0, 296, 193
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "Location of the DVD drive or the ""VIDEO_TS"" folder",
+ IDC_STATIC,5,7,235,66
+ CONTROL "Default",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP,15,21,39,10
+ CONTROL "User defined path:",IDC_RADIO2,"Button",
+ BS_AUTORADIOBUTTON,15,35,76,10
+ EDITTEXT IDC_DVDPATH,29,50,180,14,ES_AUTOHSCROLL | WS_GROUP
+ PUSHBUTTON "...",IDC_BUTTON1,215,50,15,14
+ GROUPBOX "Prefered language for DVD Navigator and the external OGM Splitter",
+ IDC_STATIC,5,77,235,73
+ CONTROL "Menu",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
+ 15,95,33,10
+ CONTROL "Audio",IDC_RADIO4,"Button",BS_AUTORADIOBUTTON,15,111,34,
+ 10
+ CONTROL "Subtitles",IDC_RADIO5,"Button",BS_AUTORADIOBUTTON,15,
+ 127,43,10
+ LISTBOX IDC_LIST1,74,90,156,53,WS_VSCROLL | WS_GROUP |
+ WS_TABSTOP
+ GROUPBOX "Audio channels",IDC_STATIC,5,155,235,32
+ CONTROL "Automatically set speaker count for the ivideo ac3 decoder",
+ IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,169,
+ 204,10
+END
+
+IDD_PPAGEPLAYBACK DIALOGEX 0, 0, 296, 198
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "Audio",IDC_STATIC,5,7,284,58
+ LTEXT "Volume",IDC_STATIC,66,19,24,8
+ LTEXT "Min",IDC_STATIC,27,38,12,8
+ CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_TABSTOP,41,31,75,24
+ LTEXT "Max",IDC_STATIC,123,38,14,8
+ LTEXT "Balance",IDC_STATIC,196,19,26,8
+ LTEXT "L",IDC_STATIC,160,39,8,8
+ CONTROL "",IDC_SLIDER2,"msctls_trackbar32",TBS_AUTOTICKS |
+ WS_TABSTOP,172,36,75,19
+ LTEXT "R",IDC_STATIC,252,39,8,8
+ GROUPBOX "Playback",IDC_STATIC,5,67,114,71
+ CONTROL "Play",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
+ 14,86,29,10
+ CONTROL "Repeat forever",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,
+ 14,102,65,10
+ CONTROL "Rewind when done playing",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,14,119,101,10
+ EDITTEXT IDC_EDIT1,52,85,20,13,ES_AUTOHSCROLL | ES_NUMBER
+ LTEXT "time(s)",IDC_STATIC1,81,87,23,8
+ GROUPBOX "Output",IDC_STATIC,126,67,163,71
+ CONTROL "Auto-zoom:",IDC_CHECK5,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,137,85,48,10
+ COMBOBOX IDC_COMBO1,193,83,49,47,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "Change fullscreen resolution:",IDC_CHECK4,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,137,102,109,10
+ COMBOBOX IDC_COMBO2,156,116,112,64,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ GROUPBOX "Open settings",IDC_STATIC,5,140,284,43
+ CONTROL "Use worker thread to construct the filter graph",
+ IDC_CHECK7,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,153,
+ 166,10
+ CONTROL "Report pins which fail to render",IDC_CHECK6,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,167,116,10
+ CONTROL "Auto-load audio files",IDC_CHECK2,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,193,153,81,10
+ CONTROL "Auto-load subtitles",IDC_CHECK3,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,193,167,76,10
+END
+
+IDD_PPAGESUBTITLES DIALOGEX 0, 0, 296, 203
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0xEE
+BEGIN
+ GROUPBOX "",IDC_STATIC,5,3,192,38
+ CONTROL "Override placement",IDC_CHECK3,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,14,3,75,10
+ LTEXT "Horizontal:",IDC_STATIC1,14,22,35,8
+ EDITTEXT IDC_EDIT2,54,20,32,12,ES_CENTER | ES_AUTOHSCROLL |
+ ES_READONLY | ES_NUMBER
+ CONTROL "",IDC_SPIN2,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS | UDS_HOTTRACK,74,25,11,14
+ LTEXT "%",IDC_STATIC2,88,22,8,8
+ LTEXT "Vertical:",IDC_STATIC3,107,22,26,8
+ EDITTEXT IDC_EDIT3,139,20,32,12,ES_CENTER | ES_AUTOHSCROLL |
+ ES_READONLY | ES_NUMBER
+ CONTROL "",IDC_SPIN3,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS | UDS_HOTTRACK,159,26,11,14
+ LTEXT "%",IDC_STATIC4,173,22,8,8
+ GROUPBOX "Texture settings (open the video again to see the changes)",
+ IDC_STATIC,5,43,284,55
+ LTEXT "Number of subpictures to buffer ahead:",IDC_STATIC,14,
+ 60,128,8
+ EDITTEXT IDC_EDIT1,147,58,32,12,ES_CENTER | ES_AUTOHSCROLL |
+ ES_READONLY | ES_NUMBER
+ CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS | UDS_HOTTRACK,168,63,11,14
+ LTEXT "Set 0 to disable buffering\n(not recommended)",
+ IDC_STATIC,191,55,90,17
+ LTEXT "Maximum texture resolution:",IDC_STATIC,14,79,92,8
+ LTEXT "Subtitling for DirectShow is available when the video renderer called ""VMR7 (renderless)"" or ""VMR9 (renderless)"" is set. VMR7 requires Windows XP, VMR9 requires DirectX 9, and both require a HW accelerated D3D video card.",
+ IDC_STATIC,14,148,267,25
+ GROUPBOX "Before you ask",IDC_STATIC,5,136,284,65
+ LTEXT "If you override and enable full-screen antialiasing somewhere at your videocard's settings, subtitles aren't going to look any better but it will surely eat your cpu.",
+ IDC_STATIC,14,110,267,19
+ COMBOBOX IDC_COMBO1,111,77,68,45,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ GROUPBOX "Warning",IDC_STATIC,5,99,284,35
+ LTEXT "RealMedia and QuickTime formats can be subtitled by setting their special DirectX 7 or DirectX 9 renderers.",
+ IDC_STATIC,14,178,267,16
+ CONTROL "Round up to power of two",IDC_CHECK_SPCPOW2TEX,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,184,79,97,10
+END
+
+IDD_PPAGESUBDB DIALOGEX 0, 0, 296, 203
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0xEE
+BEGIN
+ LTEXT "Base URL of the online subtitle database:",IDC_STATIC,5,
+ 8,133,8
+ COMBOBOX IDC_COMBO1,29,22,205,30,CBS_DROPDOWN | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "Test",IDC_BUTTON1,239,21,50,14
+ LTEXT "http://",IDC_STATIC,5,24,22,8
+END
+
+IDD_PPAGEFORMATS DIALOGEX 0, 0, 296, 198
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL |
+ LVS_SORTASCENDING | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER |
+ WS_BORDER | WS_TABSTOP,13,15,268,97
+ GROUPBOX "File extensions",IDC_STATIC,6,4,283,135
+ EDITTEXT IDC_EDIT1,13,118,192,14,ES_AUTOHSCROLL
+ PUSHBUTTON "Default",IDC_BUTTON2,210,118,34,14
+ PUSHBUTTON "Set",IDC_BUTTON_EXT_SET,247,118,34,14
+ GROUPBOX "Real-Time Streaming Protocol handler (for rtsp://... URLs)",
+ IDC_STATIC,6,141,283,27
+ CONTROL "RealMedia",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP,14,153,49,10
+ CONTROL "QuickTime",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,66,
+ 153,48,10
+ CONTROL "DirectShow",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,117,
+ 153,52,10
+ CONTROL "Look file extension first",IDC_CHECK5,"Button",
+ BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,191,153,90,10
+ CONTROL "Video",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 13,183,31,10
+ CONTROL "Music",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 45,183,31,10
+ CONTROL "DVD",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 78,183,29,10
+ CONTROL "Audio CD",IDC_CHECK3,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,108,183,43,10
+ PUSHBUTTON "&Video",IDC_BUTTON4,176,180,33,14
+ PUSHBUTTON "A&udio",IDC_BUTTON3,212,180,33,14
+ PUSHBUTTON "A&ll",IDC_BUTTON1,248,180,33,14
+ GROUPBOX "Autoplay (XP only)",IDC_STATIC1,6,170,151,28
+END
+
+IDD_PPAGETWEAKS DIALOGEX 0, 0, 296, 178
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "Don't use XP-theming on the player controls (needs restart)",
+ IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,9,207,
+ 10
+ CONTROL "Use the WM ASF Reader for Windows Media files (enables faster seeking, but won't seek with incomplete files at all)",
+ IDC_CHECK2,"Button",BS_AUTOCHECKBOX | BS_MULTILINE |
+ WS_TABSTOP,7,25,260,17
+ GROUPBOX "Jump distances (small, medium, large in ms)",IDC_STATIC,
+ 7,50,202,34
+ EDITTEXT IDC_EDIT1,15,62,40,14,ES_RIGHT | ES_AUTOHSCROLL |
+ ES_NUMBER
+ EDITTEXT IDC_EDIT2,64,62,40,14,ES_RIGHT | ES_AUTOHSCROLL |
+ ES_NUMBER
+ EDITTEXT IDC_EDIT3,110,62,40,14,ES_RIGHT | ES_AUTOHSCROLL |
+ ES_NUMBER
+ PUSHBUTTON "Default",IDC_BUTTON1,158,62,44,14
+ CONTROL "Free window resizing",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,90,83,10
+ CONTROL "Send ""Now Playing"" information to MSN Messenger",
+ IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,106,
+ 177,10
+ CONTROL "Send ""Now Playing"" information to mIRC through GTSdll",
+ IDC_CHECK5,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,122,
+ 193,10
+ LTEXT "Click here to download GTSdll",IDC_STATICLINKGTS,19,134,
+ 95,8
+END
+
+IDD_PPAGEEXTERNALFILTERS DIALOGEX 0, 0, 296, 200
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LISTBOX IDC_LIST1,6,5,208,102,LBS_OWNERDRAWFIXED |
+ LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
+ WS_TABSTOP
+ PUSHBUTTON "Add Filter...",IDC_BUTTON1,220,5,69,13
+ PUSHBUTTON "Remove",IDC_BUTTON2,220,20,69,13
+ CONTROL "Prefer",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP,220,39,53,10
+ CONTROL "Block",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,220,50,53,
+ 10
+ CONTROL "Set merit:",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,220,
+ 61,47,10
+ EDITTEXT IDC_EDIT1,220,73,69,12,ES_RIGHT | ES_AUTOHSCROLL |
+ WS_GROUP
+ PUSHBUTTON "Up",IDC_BUTTON3,220,95,33,13
+ PUSHBUTTON "Down",IDC_BUTTON4,256,95,33,13
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,6,112,283,1
+ CONTROL "",IDC_TREE2,"SysTreeView32",TVS_HASBUTTONS |
+ TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS |
+ WS_BORDER | WS_TABSTOP,6,117,208,81
+ PUSHBUTTON "Add Media Type...",IDC_BUTTON5,220,117,69,13
+ PUSHBUTTON "Add Sub Type...",IDC_BUTTON6,220,132,69,13
+ PUSHBUTTON "Delete",IDC_BUTTON7,220,147,69,13
+ PUSHBUTTON "Reset List",IDC_BUTTON8,220,185,69,13
+END
+
+IDD_FILEPROPDETAILS DIALOGEX 0, 0, 234, 202
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ ICON "",IDC_DEFAULTICON,8,8,20,20,SS_REALSIZEIMAGE
+ EDITTEXT IDC_EDIT1,35,16,186,12,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_BORDER
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,8,35,213,1
+ LTEXT "Type:",IDC_STATIC,40,42,20,8
+ EDITTEXT IDC_EDIT4,73,42,148,13,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_BORDER
+ LTEXT "Size:",IDC_STATIC,44,55,16,8
+ EDITTEXT IDC_EDIT3,73,55,148,13,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_BORDER
+ LTEXT "Media length:",IDC_STATIC,16,68,44,8
+ EDITTEXT IDC_EDIT2,73,68,148,13,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_BORDER
+ LTEXT "Video size:",IDC_STATIC,25,81,35,8
+ EDITTEXT IDC_EDIT5,73,81,148,13,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_BORDER
+ LTEXT "Created:",IDC_STATIC,30,94,30,8
+ EDITTEXT IDC_EDIT6,73,94,148,13,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_BORDER
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,8,114,213,1
+ EDITTEXT IDC_EDIT7,8,121,213,69,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_READONLY | WS_VSCROLL | WS_HSCROLL
+END
+
+IDD_FILEPROPCLIP DIALOGEX 0, 0, 234, 202
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ ICON "",IDC_DEFAULTICON,8,8,20,20,SS_REALSIZEIMAGE
+ EDITTEXT IDC_EDIT1,35,16,186,12,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_BORDER
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,8,35,213,1
+ LTEXT "Clip:",IDC_STATIC,8,42,15,8
+ EDITTEXT IDC_EDIT4,58,42,163,13,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_BORDER
+ LTEXT "Author:",IDC_STATIC,8,55,26,8
+ EDITTEXT IDC_EDIT3,58,55,163,13,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_BORDER
+ LTEXT "Copyright:",IDC_STATIC,8,68,35,8
+ EDITTEXT IDC_EDIT2,58,68,163,13,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_BORDER
+ LTEXT "Rating:",IDC_STATIC,8,81,24,8
+ EDITTEXT IDC_EDIT5,58,81,163,13,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_BORDER
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,8,101,213,1
+ LTEXT "Location:",IDC_STATIC,8,108,30,8
+ EDITTEXT IDC_EDIT6,58,108,163,12,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_BORDER
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,8,123,213,1
+ LTEXT "Description:",IDC_STATIC,8,132,39,8
+ EDITTEXT IDC_EDIT7,58,132,144,47,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_READONLY
+END
+
+IDD_FAVADD DIALOGEX 0, 0, 252, 70
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Add Favorite"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "Choose a name for your shortcut:",IDC_STATIC,7,7,238,36
+ COMBOBOX IDC_COMBO1,15,21,222,77,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ WS_VSCROLL | WS_TABSTOP
+ CONTROL "Remember position",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,15,51,77,10
+ PUSHBUTTON "Cancel",IDCANCEL,139,49,50,14
+ DEFPUSHBUTTON "OK",IDOK,195,49,50,14
+END
+
+IDD_FAVORGANIZE DIALOGEX 0, 0, 276, 174
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Organize Favorites"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "",IDC_TAB1,"SysTabControl32",0x0,7,7,204,160
+ CONTROL "",IDC_LIST2,"SysListView32",LVS_REPORT | LVS_SINGLESEL |
+ LVS_EDITLABELS | LVS_OWNERDRAWFIXED | LVS_ALIGNLEFT |
+ LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,10,22,197,
+ 141,WS_EX_CLIENTEDGE
+ PUSHBUTTON "Rename",IDC_BUTTON1,219,19,50,14
+ PUSHBUTTON "Move Up",IDC_BUTTON3,219,41,50,14
+ PUSHBUTTON "Move Down",IDC_BUTTON4,219,59,50,14
+ PUSHBUTTON "Delete",IDC_BUTTON2,219,82,50,14
+ DEFPUSHBUTTON "OK",IDOK,219,153,50,14
+END
+
+IDD_PNSPRESET_DLG DIALOGEX 0, 0, 203, 121
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Pan&Scan Presets"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LISTBOX IDC_LIST1,7,7,123,50,LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
+ WS_TABSTOP
+ EDITTEXT IDC_EDIT1,7,60,189,13,ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT2,135,18,29,12,ES_CENTER | ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT3,167,18,29,12,ES_CENTER | ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT4,135,44,29,12,ES_CENTER | ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT5,167,44,29,12,ES_CENTER | ES_AUTOHSCROLL
+ PUSHBUTTON "New",IDC_BUTTON2,7,77,33,12
+ PUSHBUTTON "Delete",IDC_BUTTON3,41,77,33,12
+ PUSHBUTTON "Up",IDC_BUTTON4,85,77,33,12
+ PUSHBUTTON "Down",IDC_BUTTON5,119,77,33,12
+ PUSHBUTTON "&Set",IDC_BUTTON1,163,77,33,12
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,8,93,190,1
+ PUSHBUTTON "&Cancel",IDCANCEL,49,100,50,14
+ PUSHBUTTON "&Save",IDOK,105,100,50,14
+ LTEXT "Pos: 0.0 -> 1.0",IDC_STATIC,135,7,61,8
+ LTEXT "Zoom: 0.2 -> 3.0",IDC_STATIC,135,33,61,8
+END
+
+IDD_PPAGEACCELTBL DIALOGEX 0, 0, 296, 198
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "",IDC_PLACEHOLDER,"Static",SS_BLACKFRAME | NOT
+ WS_VISIBLE,5,5,284,152
+ CONTROL "",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,
+ 165,10,8
+ LTEXT "WinLIRC:",IDC_STATICLINK,19,165,30,8
+ EDITTEXT IDC_EDIT1,53,163,77,13,ES_AUTOHSCROLL
+ CONTROL "",IDC_CHECK9,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,
+ 182,10,8
+ LTEXT "uICE:",IDC_STATICLINK2,19,182,19,8
+ EDITTEXT IDC_EDIT2,53,180,77,13,ES_AUTOHSCROLL
+ PUSHBUTTON "Select All",IDC_BUTTON1,230,162,59,14
+ PUSHBUTTON "Reset Selected",IDC_BUTTON2,230,179,59,14
+END
+
+IDD_MEDIATYPES_DLG DIALOGEX 0, 0, 296, 219
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+EXSTYLE WS_EX_TOOLWINDOW
+CAPTION "Warning"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Media Player Classic could not render some of the pins in the graph, you may not have the needed codecs or filters installed on the system.",
+ IDC_STATIC1,7,7,282,18
+ LTEXT "The following pin(s) failed to find a connectable filter:",
+ IDC_STATIC2,7,28,282,11
+ COMBOBOX IDC_COMBO1,7,39,282,87,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ EDITTEXT IDC_EDIT1,7,55,282,138,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_READONLY | WS_VSCROLL | WS_HSCROLL
+ PUSHBUTTON "Look for codecs on the net",IDC_BUTTON1,7,198,109,14
+ DEFPUSHBUTTON "Close",IDOK,239,198,50,14
+END
+
+IDD_SAVE_DLG DIALOGEX 0, 0, 250, 84
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Saving..."
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "",IDC_ANIMATE1,"SysAnimate32",ACS_CENTER |
+ ACS_TRANSPARENT | WS_TABSTOP,7,3,187,30
+ CONTROL "Static",IDC_FROMTO,"Static",SS_LEFTNOWORDWRAP |
+ WS_GROUP,7,38,235,17
+ CONTROL "",IDC_PROGRESS1,"msctls_progress32",WS_BORDER,7,63,190,
+ 8
+ LTEXT "",IDC_REPORT,7,74,189,8
+ PUSHBUTTON "Cancel",IDCANCEL,203,62,39,14
+END
+
+IDD_SAVETEXTFILEDIALOGTEMPL DIALOGEX 0, 0, 304, 20
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_CLIPSIBLINGS |
+ WS_CLIPCHILDREN
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Encoding:",IDC_STATIC,68,2,32,8
+ COMBOBOX IDC_COMBO1,130,0,164,46,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+END
+
+IDD_SAVETEXTFILEDIALOGTEMPL_400 DIALOGEX 0, 0, 222, 18
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_CLIPSIBLINGS |
+ WS_CLIPCHILDREN
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Encoding:",IDC_STATIC,5,2,32,8
+ COMBOBOX IDC_COMBO1,54,0,155,66,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+END
+
+IDD_SAVETHUMBSDIALOGTEMPL DIALOGEX 0, 0, 304, 35
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_CLIPSIBLINGS |
+ WS_CLIPCHILDREN
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Thumbnails:",IDC_STATIC,68,2,39,8
+ EDITTEXT IDC_EDIT1,130,0,30,13,ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,145,0,11,14
+ EDITTEXT IDC_EDIT2,187,0,30,13,ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN2,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,203,0,11,14
+ LTEXT "rows",IDC_STATIC,164,2,16,8
+ LTEXT "columns",IDC_STATIC,221,2,26,8
+ EDITTEXT IDC_EDIT3,130,17,36,13,ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN3,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,146,17,11,14
+ LTEXT "Image width:",IDC_STATIC,68,19,43,8
+ LTEXT "pixels",IDC_STATIC,170,19,19,8
+END
+
+IDD_SAVETHUMBSDIALOGTEMPL_400 DIALOGEX 0, 0, 222, 33
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_CLIPSIBLINGS |
+ WS_CLIPCHILDREN
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Thumbnails:",IDC_STATIC,5,2,39,8
+ EDITTEXT IDC_EDIT1,54,0,30,13,ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,69,0,11,14
+ EDITTEXT IDC_EDIT2,111,0,30,13,ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN2,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,127,0,11,14
+ LTEXT "rows",IDC_STATIC,88,2,16,8
+ LTEXT "columns",IDC_STATIC,145,2,26,8
+ EDITTEXT IDC_EDIT3,54,16,36,13,ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN3,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,70,16,11,14
+ LTEXT "Image width:",IDC_STATIC,5,18,43,8
+ LTEXT "pixels",IDC_STATIC,95,17,19,8
+END
+
+IDD_COMPROPERTYPAGE DIALOGEX 0, 0, 5, 5
+STYLE DS_SETFONT | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+END
+
+IDD_ADDREGFILTER DIALOGEX 0, 0, 285, 182
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MAXIMIZEBOX | WS_POPUP |
+ WS_CAPTION | WS_SYSMENU
+CAPTION "Select Filter"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "",IDC_LIST2,"SysListView32",LVS_LIST | LVS_SINGLESEL |
+ LVS_SORTASCENDING | LVS_ALIGNLEFT | WS_TABSTOP,5,5,275,
+ 154,WS_EX_CLIENTEDGE
+ PUSHBUTTON "Browse...",IDC_BUTTON1,5,163,50,14
+ DEFPUSHBUTTON "OK",IDOK,177,163,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,230,163,50,14
+END
+
+IDD_PPAGESUBSTYLE DIALOGEX 0, 0, 296, 198
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "Font",IDC_STATIC,4,2,106,123
+ PUSHBUTTON "Font",IDC_BUTTON1,11,13,89,13
+ COMBOBOX IDC_COMBO1,11,30,90,52,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ LTEXT "Spacing",IDC_STATIC,11,50,26,8
+ EDITTEXT IDC_EDIT3,66,48,35,13,ES_RIGHT | ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN3,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,93,48,11,14
+ LTEXT "Angle (z,°)",IDC_STATIC,11,69,36,8
+ EDITTEXT IDC_EDIT4,66,67,35,13,ES_RIGHT | ES_AUTOHSCROLL |
+ ES_NUMBER
+ CONTROL "",IDC_SPIN10,"msctls_updown32",UDS_WRAP |
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS,93,67,11,14
+ LTEXT "Scale (x,%)",IDC_STATIC,11,88,39,8
+ EDITTEXT IDC_EDIT5,66,86,35,13,ES_RIGHT | ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN4,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,93,86,11,14
+ LTEXT "Scale (y,%)",IDC_STATIC,11,107,39,8
+ EDITTEXT IDC_EDIT6,66,105,35,13,ES_RIGHT | ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN5,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,93,105,11,14
+ GROUPBOX "Border Style",IDC_STATIC,4,127,106,68
+ CONTROL "Outline",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP,11,140,39,10
+ CONTROL "Opaque box",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,50,
+ 140,52,10
+ LTEXT "Border width",IDC_STATIC,13,158,42,8
+ EDITTEXT IDC_EDIT1,66,155,35,13,ES_RIGHT | ES_AUTOHSCROLL |
+ ES_NUMBER
+ CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,94,154,11,14
+ LTEXT "Shadow depth",IDC_STATIC,13,177,47,8
+ EDITTEXT IDC_EDIT2,66,174,35,13,ES_RIGHT | ES_AUTOHSCROLL |
+ ES_NUMBER
+ CONTROL "",IDC_SPIN2,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,93,175,11,14
+ GROUPBOX "Screen Alignment && Margins",IDC_STATIC,116,2,174,66
+ CONTROL "",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON | WS_GROUP,124,
+ 37,11,8
+ CONTROL "",IDC_RADIO4,"Button",BS_AUTORADIOBUTTON,136,37,11,8
+ CONTROL "",IDC_RADIO5,"Button",BS_AUTORADIOBUTTON,148,37,11,8
+ CONTROL "",IDC_RADIO6,"Button",BS_AUTORADIOBUTTON,124,26,11,8
+ CONTROL "",IDC_RADIO7,"Button",BS_AUTORADIOBUTTON,136,26,11,8
+ CONTROL "",IDC_RADIO8,"Button",BS_AUTORADIOBUTTON,148,26,11,8
+ CONTROL "",IDC_RADIO9,"Button",BS_AUTORADIOBUTTON,124,15,11,8
+ CONTROL "",IDC_RADIO10,"Button",BS_AUTORADIOBUTTON,136,15,11,8
+ CONTROL "",IDC_RADIO11,"Button",BS_AUTORADIOBUTTON,148,15,11,8
+ LTEXT "Left",IDC_STATIC,166,17,14,8
+ EDITTEXT IDC_EDIT7,188,14,30,14,ES_RIGHT | ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN6,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,217,14,11,14
+ LTEXT "Right",IDC_STATIC,166,34,18,8
+ EDITTEXT IDC_EDIT8,188,32,30,14,ES_RIGHT | ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN7,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,217,32,11,14
+ LTEXT "Top",IDC_STATIC,223,17,13,8
+ EDITTEXT IDC_EDIT9,251,14,30,14,ES_RIGHT | ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN8,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,280,12,11,14
+ LTEXT "Bottom",IDC_STATIC,223,34,24,8
+ EDITTEXT IDC_EDIT10,251,32,30,14,ES_RIGHT | ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN9,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,280,32,11,14
+ GROUPBOX "Colors && Transparency",IDC_STATIC,116,70,174,108
+ LTEXT "Primary",IDC_STATIC,123,95,25,8
+ CONTROL "",IDC_COLORPRI,"Static",SS_OWNERDRAW | SS_NOTIFY,165,92,
+ 16,14,WS_EX_DLGMODALFRAME
+ CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,187,94,92,12
+ LTEXT "Secondary",IDC_STATIC,123,112,34,8
+ CONTROL "",IDC_COLORSEC,"Static",SS_OWNERDRAW | SS_NOTIFY,165,
+ 109,16,14,WS_EX_DLGMODALFRAME
+ CONTROL "",IDC_SLIDER2,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,187,111,92,12
+ LTEXT "Outline",IDC_STATIC,123,129,24,8
+ CONTROL "",IDC_COLOROUTL,"Static",SS_OWNERDRAW | SS_NOTIFY,165,
+ 126,16,14,WS_EX_DLGMODALFRAME
+ CONTROL "",IDC_SLIDER3,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,187,128,92,12
+ LTEXT "Shadow",IDC_STATIC,123,146,26,8
+ CONTROL "",IDC_COLORSHAD,"Static",SS_OWNERDRAW | SS_NOTIFY,165,
+ 143,16,14,WS_EX_DLGMODALFRAME
+ CONTROL "",IDC_SLIDER4,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,187,145,92,12
+ CONTROL "Link alpha channels",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,195,161,76,10
+ LTEXT "100%",IDC_STATIC,265,83,20,8
+ LTEXT "0%",IDC_STATIC,190,83,12,8
+ CONTROL "Position subtitles relative to the video frame",
+ IDC_CHECK_RELATIVETO,"Button",BS_AUTO3STATE | WS_TABSTOP,
+ 125,51,157,10
+END
+
+IDD_PPAGEINTERNALFILTERS DIALOGEX 0, 0, 296, 200
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "Source Filters",IDC_STATIC,5,33,130,159
+ LTEXT "If you would like to use the stand-alone version from these filters or a some other replacement, disable them here. Filters written bold can be double-clicked to show their property pages.",
+ IDC_STATIC,5,4,269,25
+ LISTBOX IDC_LIST1,11,44,118,142,LBS_OWNERDRAWFIXED |
+ LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
+ WS_TABSTOP
+ GROUPBOX "Transform Filters",IDC_STATIC,144,33,130,159
+ LISTBOX IDC_LIST2,150,44,118,142,LBS_OWNERDRAWFIXED |
+ LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
+ WS_TABSTOP
+END
+
+IDD_PPAGELOGO DIALOGEX 0, 0, 296, 203
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0xEE
+BEGIN
+ CONTROL "",IDC_LOGOPREVIEW,"Static",SS_BITMAP | SS_CENTERIMAGE,5,
+ 5,284,150
+ CONTROL "Internal:",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP,5,164,44,10
+ CONTROL "External:",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,5,181,
+ 45,10
+ EDITTEXT IDC_LOGOFILENAME,51,179,182,14,ES_AUTOHSCROLL |
+ ES_READONLY
+ CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_ARROWKEYS | UDS_HORZ,
+ 51,163,36,12
+ PUSHBUTTON "Browse...",IDC_BUTTON2,239,179,50,14
+ RTEXT "",IDC_AUTHOR,95,164,194,9
+END
+
+IDD_PPAGEOUTPUT DIALOGEX 0, 0, 296, 203
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0xEE
+BEGIN
+ GROUPBOX "DirectShow Video",IDC_STATIC,5,2,95,126
+ CONTROL "System Default",IDC_DSSYSDEF,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP,13,15,65,10
+ CONTROL "Old Renderer",IDC_DSOLD,"Button",BS_AUTORADIOBUTTON,13,
+ 26,59,10
+ CONTROL "Overlay Mixer *",IDC_DSOVERLAYMIXER,"Button",
+ BS_AUTORADIOBUTTON,13,37,67,10
+ CONTROL "VMR7 (windowed)",IDC_DSVMR7WIN,"Button",
+ BS_AUTORADIOBUTTON,13,48,73,10
+ CONTROL "VMR9 (windowed)",IDC_DSVMR9WIN,"Button",
+ BS_AUTORADIOBUTTON,13,59,73,10
+ CONTROL "VMR7 (renderless) **",IDC_DSVMR7REN,"Button",
+ BS_AUTORADIOBUTTON,13,70,85,10
+ CONTROL "VMR9 (renderless) **",IDC_DSVMR9REN,"Button",
+ BS_AUTORADIOBUTTON,13,81,85,10
+ CONTROL "Haali's Video Renderer",IDC_DSDXR,"Button",
+ BS_AUTORADIOBUTTON,13,92,83,10
+ CONTROL "Null (anything)",IDC_DSNULL_COMP,"Button",
+ BS_AUTORADIOBUTTON,13,103,63,10
+ CONTROL "Null (uncompressed)",IDC_DSNULL_UNCOMP,"Button",
+ BS_AUTORADIOBUTTON,13,114,81,10
+ GROUPBOX "RealMedia Video",IDC_STATIC,105,2,89,50
+ CONTROL "System Default *",IDC_RMSYSDEF,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP,113,14,71,10
+ CONTROL "DirectX 7 **",IDC_RMDX7,"Button",BS_AUTORADIOBUTTON,113,
+ 25,55,10
+ CONTROL "DirectX 9 **",IDC_RMDX9,"Button",BS_AUTORADIOBUTTON,113,
+ 36,55,10
+ GROUPBOX "QuickTime Video",IDC_STATIC,199,2,89,50
+ CONTROL "System Default *",IDC_QTSYSDEF,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP,207,14,71,10
+ CONTROL "DirectX 7 **",IDC_QTDX7,"Button",BS_AUTORADIOBUTTON,207,
+ 25,55,10
+ CONTROL "DirectX 9 **",IDC_QTDX9,"Button",BS_AUTORADIOBUTTON,207,
+ 36,55,10
+ GROUPBOX """VMR7/9 (renderless)"" && ""DirectX 7/9"" settings",
+ IDC_STATIC,105,53,183,75
+ CONTROL "Use regular offscreen plain surfaces",IDC_REGULARSURF,
+ "Button",BS_AUTORADIOBUTTON | WS_GROUP,113,64,131,10
+ CONTROL "Use texture surfaces and render video in 2D",
+ IDC_TEXTURESURF2D,"Button",BS_AUTORADIOBUTTON,113,75,158,
+ 10
+ CONTROL "Use texture surfaces and render video in 3D ***",
+ IDC_TEXTURESURF3D,"Button",BS_AUTORADIOBUTTON,113,86,172,
+ 10
+ LTEXT "Resizer:",IDC_STATIC,134,99,27,8
+ COMBOBOX IDC_DX9RESIZER_COMBO,163,98,94,49,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "DirectShow Audio",IDC_STATIC,5,129,283,28
+ COMBOBOX IDC_COMBO1,14,139,266,66,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "Lock back-buffer before presenting (may fix broken vertical syncronization)",
+ IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,160,
+ 263,10
+ LTEXT "* Saving images won't work with these renderers",
+ IDC_STATIC,13,171,158,8
+ LTEXT "** Required for loading subtitles",IDC_STATIC,13,181,
+ 104,8
+ LTEXT "*** Required for image rotation and pixelshaders (DX9-only)",
+ IDC_STATIC,13,190,195,8
+ CONTROL "VMR9 mixer mode",IDC_DSVMR9LOADMIXER,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,113,113,73,10
+ CONTROL "YUV mixing",IDC_DSVMR9YUVMIXER,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,191,113,51,10
+END
+
+IDD_AUTH_DLG DIALOGEX 0, 0, 213, 146
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Authentication needed"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,100,125,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,154,125,50,14
+ CONTROL 337,IDC_STATIC,"Static",SS_BITMAP,0,0,213,37
+ LTEXT "Restricted area",IDC_STATIC,13,48,50,8
+ LTEXT "Username:",IDC_STATIC,13,66,36,8
+ LTEXT "Password:",IDC_STATIC,13,83,34,8
+ COMBOBOX IDC_COMBO1,75,64,129,56,CBS_DROPDOWN | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_EDIT3,75,81,129,13,ES_PASSWORD | ES_AUTOHSCROLL
+ CONTROL "Remember my password",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,75,99,94,10
+END
+
+IDD_PPAGEWEBSERVER DIALOGEX 0, 0, 296, 178
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "Listen on port:",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,7,4,63,10
+ EDITTEXT IDC_EDIT1,71,3,40,12,ES_AUTOHSCROLL
+ LTEXT "Launch in web browser...",IDC_STATIC1,129,5,152,8
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,19,282,1
+ CONTROL "Enable compression",IDC_CHECK3,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,7,25,79,10
+ CONTROL "Print debug info",IDC_CHECK2,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,7,51,67,10
+ CONTROL "Serve pages from:",IDC_CHECK4,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,7,72,75,10
+ EDITTEXT IDC_EDIT2,7,85,183,14,ES_AUTOHSCROLL
+ PUSHBUTTON "Browse...",IDC_BUTTON1,194,85,45,14
+ PUSHBUTTON "Deploy...",IDC_BUTTON2,243,85,46,14
+ CONTROL "Allow access from localhost only",IDC_CHECK5,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,38,118,10
+ LTEXT "CGI handlers: (.ext1=path1;.ext2=path2;...)",IDC_STATIC,
+ 8,132,148,8
+ EDITTEXT IDC_EDIT3,7,144,282,14,ES_AUTOHSCROLL
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,65,281,1
+ LTEXT "Default page:",IDC_STATIC,7,103,45,8
+ EDITTEXT IDC_EDIT9,7,114,282,14,ES_AUTOHSCROLL
+END
+
+IDD_SUBTITLEDL_DLG DIALOGEX 0, 0, 377, 158
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Subtitles available online"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "Download && Open",IDOK,272,136,98,14
+ CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT |
+ WS_BORDER | WS_TABSTOP,7,7,363,124
+ CONTROL "Replace currently loaded subtitles",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,138,124,10
+END
+
+IDD_FILEPROPRES DIALOGEX 0, 0, 234, 202
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ ICON "",IDC_DEFAULTICON,8,8,21,20,SS_REALSIZEIMAGE
+ EDITTEXT IDC_EDIT1,35,16,186,12,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_BORDER
+ CONTROL "",-1,"Static",SS_ETCHEDHORZ,8,35,213,1
+ PUSHBUTTON "Save As...",IDC_BUTTON1,8,182,50,14
+ CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL |
+ LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_ALIGNLEFT |
+ WS_BORDER | WS_TABSTOP,8,43,213,134
+END
+
+IDD_SHADERCOMBINE_DLG DIALOGEX 0, 0, 225, 153
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Shader Combiner"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LISTBOX IDC_LIST1,7,7,157,117,LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
+ WS_TABSTOP
+ DEFPUSHBUTTON "OK",IDOK,168,7,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,168,23,50,14
+ PUSHBUTTON "Move &Up",IDC_BUTTON1,168,57,50,14
+ PUSHBUTTON "Move &Down",IDC_BUTTON4,168,73,50,14
+ PUSHBUTTON "&Remove",IDC_BUTTON3,168,110,50,14
+ CONTROL "",IDC_STATIC1,"Static",SS_ETCHEDHORZ,7,128,211,1
+ COMBOBOX IDC_COMBO1,7,133,157,120,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ PUSHBUTTON "&Add",IDC_BUTTON2,168,132,50,14
+END
+
+IDD_SHADEREDITOR_DLG DIALOGEX 0, 0, 198, 71
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ COMBOBOX IDC_COMBO1,0,0,115,51,CBS_DROPDOWN | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_EDIT1,0,15,198,27,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ COMBOBOX IDC_COMBO2,117,0,47,42,CBS_DROPDOWN | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_EDIT2,0,44,198,26,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_READONLY | WS_VSCROLL
+ PUSHBUTTON "Delete",IDC_BUTTON1,166,0,32,13
+END
+
+IDD_SHADERAUTOCOMPLETE_DLG DIALOGEX 0, 0, 99, 81
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_SYSMENU | WS_THICKFRAME
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LISTBOX IDC_LIST1,0,0,99,81,LBS_SORT | LBS_NOINTEGRALHEIGHT |
+ NOT WS_BORDER | WS_VSCROLL | WS_TABSTOP
+END
+
+IDD_CONVERT_DLG DIALOGEX 0, 0, 322, 190
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP |
+ WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_ACCEPTFILES
+CAPTION "DSM Converter - Right click the empty area to add media files"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "",IDC_TREE1,"SysTreeView32",TVS_HASBUTTONS |
+ TVS_LINESATROOT | TVS_SHOWSELALWAYS | WS_BORDER |
+ WS_TABSTOP,5,5,312,138
+ PUSHBUTTON "Save &As...",IDC_BUTTON1,267,146,50,14
+ EDITTEXT IDC_EDIT1,5,146,259,14,ES_AUTOHSCROLL | ES_READONLY
+ PUSHBUTTON "Start",IDC_BUTTON2,83,171,50,14
+ PUSHBUTTON "Pause",IDC_BUTTON3,136,171,50,14
+ PUSHBUTTON "Stop",IDC_BUTTON4,188,171,50,14
+ CONTROL "",IDC_HLINE,"Static",SS_ETCHEDHORZ,5,165,310,1
+END
+
+IDD_CONVERTPROPS_DLG DIALOGEX 0, 0, 266, 145
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Properties"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ PUSHBUTTON "OK",IDOK,81,125,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,133,125,50,14
+ COMBOBOX IDC_COMBO1,7,7,48,82,CBS_DROPDOWN | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_EDIT1,56,7,167,13,ES_AUTOHSCROLL
+ DEFPUSHBUTTON "Set",IDC_BUTTON1,225,7,34,13
+ CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL |
+ LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER |
+ WS_TABSTOP,7,22,252,98
+END
+
+IDD_CONVERTRES_DLG DIALOGEX 0, 0, 230, 126
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Resource"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,64,106,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,116,106,50,14
+ COMBOBOX IDC_COMBO1,7,40,216,30,CBS_DROPDOWN | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_EDIT2,7,65,216,36,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_WANTRETURN
+ EDITTEXT IDC_EDIT3,7,16,216,13,ES_AUTOHSCROLL
+ LTEXT "Name",IDC_STATIC,7,6,19,8
+ LTEXT "Mime",IDC_STATIC,7,30,17,8
+ LTEXT "Description",IDC_STATIC,7,55,36,8
+END
+
+IDD_CONVERTCHAP_DLG DIALOGEX 0, 0, 213, 46
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Chapter"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,55,25,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,107,25,50,14
+ EDITTEXT IDC_EDIT2,72,7,134,13,ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT1,7,7,61,13,ES_AUTOHSCROLL
+END
+
+IDD_PPAGECASIMIR DIALOGEX 0, 0, 296, 203
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0xEE
+BEGIN
+ GROUPBOX "Video",IDC_STATIC,5,2,283,48
+ CONTROL "Automatic refresh rate",IDC_AUTO_REFRESHRATE_CHECK,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,32,98,10
+ CONTROL "Direct3D Fullscreen",IDC_FULLSCREEN_MONITOR_CHECK,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,18,77,10
+ GROUPBOX " VMR9 Color controls ",IDC_STATIC,5,91,283,109
+ CONTROL "",IDC_SLI_CONTRAST,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOOLTIPS | WS_DISABLED | WS_TABSTOP,55,105,233,13
+ LTEXT "Contrast",IDC_STATIC,13,107,29,8
+ LTEXT "Brightness",IDC_STATIC,13,126,34,8
+ LTEXT "Hue",IDC_STATIC,13,145,14,8
+ LTEXT "Saturation",IDC_STATIC,13,164,34,8
+ CONTROL "",IDC_SLI_BRIGHTNESS,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOOLTIPS | WS_DISABLED | WS_TABSTOP,55,124,233,13
+ CONTROL "",IDC_SLI_HUE,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOOLTIPS | WS_DISABLED | WS_TABSTOP,55,143,233,13
+ CONTROL "",IDC_SLI_SATURATION,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOOLTIPS | WS_DISABLED | WS_TABSTOP,55,162,233,13
+ PUSHBUTTON "Reset",IDC_RESET,13,182,59,14
+ CONTROL "Remember DVD position",IDC_DVD_POS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,134,19,92,10
+ CONTROL "Remember File position",IDC_FILE_POS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,134,34,89,10
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_SELECTMEDIATYPE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 218
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 40
+ END
+
+ IDD_OPENCAPDEVICE_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 219
+ VERTGUIDE, 12
+ VERTGUIDE, 47
+ VERTGUIDE, 212
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 124
+ END
+
+ IDD_CAPTURE_DLG, DIALOG
+ BEGIN
+ RIGHTMARGIN, 125
+ VERTGUIDE, 3
+ VERTGUIDE, 10
+ VERTGUIDE, 47
+ VERTGUIDE, 50
+ VERTGUIDE, 72
+ VERTGUIDE, 74
+ VERTGUIDE, 112
+ VERTGUIDE, 119
+ END
+
+ IDD_PPAGEAUDIOSWITCHER, DIALOG
+ BEGIN
+ VERTGUIDE, 7
+ VERTGUIDE, 289
+ BOTTOMMARGIN, 193
+ END
+
+ IDD_GOTO_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 150
+ VERTGUIDE, 31
+ VERTGUIDE, 114
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 106
+ END
+
+ IDD_OPEN_DLG, DIALOG
+ BEGIN
+ VERTGUIDE, 7
+ VERTGUIDE, 33
+ VERTGUIDE, 182
+ VERTGUIDE, 187
+ VERTGUIDE, 234
+ BOTTOMMARGIN, 86
+ HORZGUIDE, 9
+ END
+
+ IDD_ABOUTBOX, DIALOG
+ BEGIN
+ VERTGUIDE, 40
+ VERTGUIDE, 210
+ END
+
+ IDD_PPAGEPLAYER, DIALOG
+ BEGIN
+ VERTGUIDE, 15
+ VERTGUIDE, 140
+ VERTGUIDE, 289
+ BOTTOMMARGIN, 192
+ END
+
+ IDD_PPAGEDVD, DIALOG
+ BEGIN
+ VERTGUIDE, 5
+ VERTGUIDE, 15
+ VERTGUIDE, 240
+ HORZGUIDE, 57
+ END
+
+ IDD_PPAGEPLAYBACK, DIALOG
+ BEGIN
+ VERTGUIDE, 5
+ VERTGUIDE, 13
+ VERTGUIDE, 137
+ VERTGUIDE, 193
+ VERTGUIDE, 289
+ END
+
+ IDD_PPAGESUBTITLES, DIALOG
+ BEGIN
+ VERTGUIDE, 5
+ VERTGUIDE, 14
+ VERTGUIDE, 281
+ VERTGUIDE, 289
+ BOTTOMMARGIN, 200
+ END
+
+ IDD_PPAGESUBDB, DIALOG
+ BEGIN
+ VERTGUIDE, 5
+ VERTGUIDE, 289
+ BOTTOMMARGIN, 200
+ END
+
+ IDD_PPAGEFORMATS, DIALOG
+ BEGIN
+ VERTGUIDE, 6
+ VERTGUIDE, 13
+ VERTGUIDE, 281
+ VERTGUIDE, 289
+ END
+
+ IDD_PPAGETWEAKS, DIALOG
+ BEGIN
+ RIGHTMARGIN, 289
+ VERTGUIDE, 7
+ VERTGUIDE, 15
+ VERTGUIDE, 289
+ END
+
+ IDD_FILEPROPDETAILS, DIALOG
+ BEGIN
+ VERTGUIDE, 8
+ VERTGUIDE, 60
+ VERTGUIDE, 73
+ VERTGUIDE, 221
+ HORZGUIDE, 42
+ HORZGUIDE, 55
+ HORZGUIDE, 68
+ HORZGUIDE, 81
+ HORZGUIDE, 94
+ END
+
+ IDD_FILEPROPCLIP, DIALOG
+ BEGIN
+ VERTGUIDE, 8
+ VERTGUIDE, 35
+ VERTGUIDE, 58
+ VERTGUIDE, 221
+ HORZGUIDE, 42
+ HORZGUIDE, 55
+ HORZGUIDE, 68
+ HORZGUIDE, 81
+ HORZGUIDE, 108
+ END
+
+ IDD_FAVADD, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 245
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 63
+ END
+
+ IDD_FAVORGANIZE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 269
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 167
+ END
+
+ IDD_PNSPRESET_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 196
+ VERTGUIDE, 135
+ VERTGUIDE, 168
+ VERTGUIDE, 196
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 114
+ END
+
+ IDD_PPAGEACCELTBL, DIALOG
+ BEGIN
+ VERTGUIDE, 5
+ VERTGUIDE, 289
+ BOTTOMMARGIN, 197
+ HORZGUIDE, 169
+ HORZGUIDE, 186
+ END
+
+ IDD_MEDIATYPES_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 289
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 212
+ END
+
+ IDD_SAVE_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 242
+ TOPMARGIN, 3
+ BOTTOMMARGIN, 82
+ END
+
+ IDD_SAVETHUMBSDIALOGTEMPL, DIALOG
+ BEGIN
+ VERTGUIDE, 68
+ VERTGUIDE, 130
+ END
+
+ IDD_SAVETHUMBSDIALOGTEMPL_400, DIALOG
+ BEGIN
+ VERTGUIDE, 5
+ VERTGUIDE, 54
+ BOTTOMMARGIN, 30
+ END
+
+ IDD_ADDREGFILTER, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 280
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 177
+ HORZGUIDE, 159
+ END
+
+ IDD_PPAGEINTERNALFILTERS, DIALOG
+ BEGIN
+ VERTGUIDE, 5
+ VERTGUIDE, 274
+ VERTGUIDE, 289
+ HORZGUIDE, 29
+ HORZGUIDE, 33
+ HORZGUIDE, 44
+ HORZGUIDE, 186
+ HORZGUIDE, 192
+ HORZGUIDE, 198
+ END
+
+ IDD_PPAGELOGO, DIALOG
+ BEGIN
+ VERTGUIDE, 5
+ VERTGUIDE, 289
+ BOTTOMMARGIN, 200
+ HORZGUIDE, 5
+ HORZGUIDE, 155
+ HORZGUIDE, 163
+ END
+
+ IDD_PPAGEOUTPUT, DIALOG
+ BEGIN
+ VERTGUIDE, 5
+ VERTGUIDE, 13
+ VERTGUIDE, 288
+ BOTTOMMARGIN, 200
+ END
+
+ IDD_AUTH_DLG, DIALOG
+ BEGIN
+ VERTGUIDE, 13
+ VERTGUIDE, 75
+ VERTGUIDE, 204
+ BOTTOMMARGIN, 139
+ END
+
+ IDD_PPAGEWEBSERVER, DIALOG
+ BEGIN
+ RIGHTMARGIN, 289
+ VERTGUIDE, 7
+ VERTGUIDE, 289
+ END
+
+ IDD_SUBTITLEDL_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 370
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 151
+ END
+
+ IDD_FILEPROPRES, DIALOG
+ BEGIN
+ VERTGUIDE, 8
+ VERTGUIDE, 35
+ VERTGUIDE, 221
+ END
+
+ IDD_SHADERCOMBINE_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 218
+ VERTGUIDE, 164
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 146
+ END
+
+ IDD_SHADEREDITOR_DLG, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 70
+ END
+
+ IDD_CONVERT_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 317
+ VERTGUIDE, 12
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 185
+ END
+
+ IDD_CONVERTPROPS_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 259
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 139
+ END
+
+ IDD_CONVERTRES_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 223
+ TOPMARGIN, 6
+ BOTTOMMARGIN, 120
+ END
+
+ IDD_CONVERTCHAP_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 206
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 39
+ END
+
+ IDD_PPAGECASIMIR, DIALOG
+ BEGIN
+ VERTGUIDE, 5
+ VERTGUIDE, 13
+ VERTGUIDE, 288
+ BOTTOMMARGIN, 200
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_ONOFF BITMAP "res\\onoff.bmp"
+IDB_PLAYERTOOLBAR BITMAP "res\\toolbar1.bmp"
+IDB_MONO BITMAP "res\\mono.bmp"
+IDB_STEREO BITMAP "res\\stereo.bmp"
+IDB_NOAUDIO BITMAP "res\\noaudio.bmp"
+IDB_LOGO0 BITMAP "res\\logo.0.bmp"
+IDB_LOGO1 BITMAP "res\\logo.1.bmp"
+IDB_LOGO2 BITMAP "res\\logo.2.bmp"
+IDB_LOGO3 BITMAP "res\\logo.3.bmp"
+IDB_LOGO4 BITMAP "res\\logo.4.bmp"
+IDB_LOGO5 BITMAP "res\\logo.5.bmp"
+IDB_LOGO6 BITMAP "res\\logo.6.bmp"
+IDB_AUTHHDRPIC BITMAP "res\\authhdrpic.bmp"
+IDB_LOGO7 BITMAP "res\\logo.7.bmp"
+IDB_STREAMTYPES BITMAP "res\\streamtypes.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// FILE
+//
+
+IDF_SHADER_EMPTY FILE "res\\shaders\\empty.psh"
+IDF_SHADER_CONTOUR FILE "res\\shaders\\contour.psh"
+IDF_SHADER_DEINTERLACE FILE "res\\shaders\\deinterlace (blend).psh"
+IDF_SHADER_EMBOSS FILE "res\\shaders\\emboss.psh"
+IDF_SHADER_GRAYSCALE FILE "res\\shaders\\grayscale.psh"
+IDF_SHADER_INVERT FILE "res\\shaders\\invert.psh"
+IDF_SHADER_LETTERBOX FILE "res\\shaders\\letterbox.psh"
+IDF_SHADER_PROCAMP FILE "res\\shaders\\procamp.psh"
+IDF_SHADER_SHARPEN FILE "res\\shaders\\sharpen.psh"
+IDF_SHADER_SPHERE FILE "res\\shaders\\sphere.psh"
+IDF_SHADER_SPOTLIGHT FILE "res\\shaders\\spotlight.psh"
+IDF_SHADER_WAVE FILE "res\\shaders\\wave.psh"
+IDF_DEFAULT_CSS FILE "res\\web\\default.css"
+IDF_VBR_GIF FILE "res\\web\\vbg.gif"
+IDF_VBS_GIF FILE "res\\web\\vbs.GIF"
+IDF_SLIDERBAR_GIF FILE "res\\web\\sliderbar.gif"
+IDF_SLIDERGRIP_GIF FILE "res\\web\\slidergrip.gif"
+IDF_1PIX_GIF FILE "res\\web\\1pix.gif"
+IDF_SLIDERBACK_GIF FILE "res\\web\\sliderback.gif"
+IDF_HEADERICON_PNG FILE "res\\web\\headericon.png"
+IDF_HEADERBACK_PNG FILE "res\\web\\headerback.png"
+IDF_HEADERCLOSE_PNG FILE "res\\web\\headerclose.png"
+IDF_LEFTSIDE_PNG FILE "res\\web\\leftside.png"
+IDF_RIGHTSIDE_PNG FILE "res\\web\\rightside.png"
+IDF_BOTTOMSIDE_PNG FILE "res\\web\\bottomside.png"
+IDF_LEFTBOTTOMSIDE_PNG FILE "res\\web\\leftbottomside.png"
+IDF_RIGHTBOTTOMSIDE_PNG FILE "res\\web\\rightbottomside.png"
+IDF_SEEKBARLEFT_PNG FILE "res\\web\\seekbarleft.png"
+IDF_SEEKBARMID_PNG FILE "res\\web\\seekbarmid.png"
+IDF_SEEKBARRIGHT_PNG FILE "res\\web\\seekbarright.png"
+IDF_SEEKBARGRIP_PNG FILE "res\\web\\seekbargrip.png"
+IDF_LOGO_PNG FILE "res\\web\\logo.png"
+IDF_CONTROLBACK_PNG FILE "res\\web\\controlback.png"
+IDF_CONTROLBUTTONPLAY_PNG FILE "res\\web\\controlbuttonplay.png"
+IDF_CONTROLBUTTONPAUSE_PNG FILE "res\\web\\controlbuttonpause.png"
+IDF_CONTROLBUTTONSTOP_PNG FILE "res\\web\\controlbuttonstop.png"
+IDF_CONTROLBUTTONSKIPBACK_PNG FILE "res\\web\\controlbuttonskipback.png"
+IDF_CONTROLBUTTONDECRATE_PNG FILE "res\\web\\controlbuttondecrate.png"
+IDF_CONTROLBUTTONINCRATE_PNG FILE "res\\web\\controlbuttonincrate.png"
+IDF_CONTROLBUTTONSKIPFORWARD_PNG FILE "res\\web\\controlbuttonskipforward.png"
+IDF_CONTROLBUTTONSTEP_PNG FILE "res\\web\\controlbuttonstep.png"
+IDF_CONTROLVOLUMEON_PNG FILE "res\\web\\controlvolumeon.png"
+IDF_CONTROLVOLUMEOFF_PNG FILE "res\\web\\controlvolumeoff.png"
+IDF_CONTROLVOLUMEBAR_PNG FILE "res\\web\\controlvolumebar.png"
+IDF_CONTROLVOLUMEGRIP_PNG FILE "res\\web\\controlvolumegrip.png"
+IDF_SHADER_RESIZER FILE "res\\shaders\\resizer.psh"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON "res\\icon.ico"
+IDI_SINGLE ICON "res\\single.ico"
+IDI_MULTI ICON "res\\multi.ico"
+IDI_AUDIOCD ICON "res\\Icon_41.ico"
+IDI_DVD ICON "res\\Icon_114.ico"
+IDI_UNKNOWN ICON "res\\Icon_116.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Toolbar
+//
+
+IDB_PLAYERTOOLBAR TOOLBAR 16, 16
+BEGIN
+ BUTTON ID_PLAY_PLAY
+ BUTTON ID_PLAY_PAUSE
+ BUTTON ID_PLAY_STOP
+ BUTTON ID_BUTTONSEP
+ BUTTON ID_NAVIGATE_SKIPBACK
+ BUTTON ID_PLAY_DECRATE
+ BUTTON ID_PLAY_INCRATE
+ BUTTON ID_NAVIGATE_SKIPFORWARD
+ BUTTON ID_BUTTONSEP
+ BUTTON ID_PLAY_FRAMESTEP
+ BUTTON ID_BUTTONSEP
+ BUTTON ID_DUMMYSEPARATOR
+ BUTTON ID_VOLUME_MUTE
+ BUTTON ID_VOLUME_MUTE_ON
+ BUTTON ID_VOLUME_MUTE_DISABLED
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog Info
+//
+
+IDD_PPAGEPLAYBACK DLGINIT
+BEGIN
+ IDC_COMBO1, 0x403, 4, 0
+0x3035, 0x0025,
+ IDC_COMBO1, 0x403, 5, 0
+0x3031, 0x2530, "\000"
+ IDC_COMBO1, 0x403, 5, 0
+0x3032, 0x2530, "\000"
+ IDC_COMBO1, 0x403, 9, 0
+0x7541, 0x6f74, 0x4620, 0x7469, "\000"
+ 0
+END
+
+IDD_PPAGEOUTPUT DLGINIT
+BEGIN
+ IDC_DX9RESIZER_COMBO, 0x403, 17, 0
+0x654e, 0x7261, 0x7365, 0x2074, 0x656e, 0x6769, 0x6268, 0x726f, "\000"
+ IDC_DX9RESIZER_COMBO, 0x403, 9, 0
+0x6942, 0x696c, 0x656e, 0x7261, "\000"
+ IDC_DX9RESIZER_COMBO, 0x403, 18, 0
+0x6942, 0x696c, 0x656e, 0x7261, 0x2820, 0x5350, 0x3220, 0x302e, 0x0029,
+
+ IDC_DX9RESIZER_COMBO, 0x403, 25, 0
+0x6942, 0x7563, 0x6962, 0x2063, 0x3d41, 0x302d, 0x362e, 0x2030, 0x5028,
+0x2053, 0x2e32, 0x2930, "\000"
+ IDC_DX9RESIZER_COMBO, 0x403, 25, 0
+0x6942, 0x7563, 0x6962, 0x2063, 0x3d41, 0x302d, 0x372e, 0x2035, 0x5028,
+0x2053, 0x2e32, 0x2930, "\000"
+ IDC_DX9RESIZER_COMBO, 0x403, 25, 0
+0x6942, 0x7563, 0x6962, 0x2063, 0x3d41, 0x312d, 0x302e, 0x2030, 0x5028,
+0x2053, 0x2e32, 0x2930, "\000"
+ 0
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,1,4,1
+ PRODUCTVERSION 6,4,9,0
+ FILEFLAGSMASK 0x1fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "http://gabest.org/ Modify by Casimir666"
+ VALUE "CompanyName", "Gabest"
+ VALUE "FileDescription", "Media Player Classic"
+ VALUE "FileVersion", "1, 1, 4, 1"
+ VALUE "InternalName", "Media Player Classic"
+ VALUE "LegalCopyright", "Copyright (C) 2002-2006 Gabest"
+ VALUE "OriginalFilename", "mplayerc.EXE"
+ VALUE "ProductName", "Media Player Classic"
+ VALUE "ProductVersion", "6, 4, 9, 0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MAINFRAME MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&Quick Open File...\tCtrl+Q", ID_FILE_OPENQUICK
+ MENUITEM SEPARATOR
+ MENUITEM "&Open File...\tCtrl+O", ID_FILE_OPENMEDIA
+ MENUITEM "Open &DVD...\tCtrl+D", ID_FILE_OPENDVD
+ MENUITEM "Open De&vice...\tCtrl+V", ID_FILE_OPENDEVICE
+ MENUITEM "O&pen Disc", ID_FILE_OPENDISC32774
+ MENUITEM "&Close\tCtrl+C", ID_FILE_CLOSEPLAYLIST
+ MENUITEM SEPARATOR
+ MENUITEM "&Save As...", ID_FILE_SAVE_COPY
+ MENUITEM "Save &Image...", ID_FILE_SAVE_IMAGE
+ MENUITEM "Save Thumbnails...", ID_FILE_SAVE_THUMBNAILS
+ MENUITEM SEPARATOR
+ MENUITEM "&Load Subtitle...\tCtrl+L", ID_FILE_LOAD_SUBTITLE
+ MENUITEM "Save Subtitle...\tCtrl+S", ID_FILE_SAVE_SUBTITLE
+ POPUP "Subtitle Database"
+ BEGIN
+ MENUITEM "Search...", ID_FILE_ISDB_SEARCH
+ MENUITEM "Upload...", ID_FILE_ISDB_UPLOAD
+ MENUITEM "Download...", ID_FILE_ISDB_DOWNLOAD
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "P&roperties", ID_FILE_PROPERTIES
+ MENUITEM SEPARATOR
+ POPUP "Utils"
+ BEGIN
+ MENUITEM "DSM Co&nverter...", ID_FILE_CONVERT
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit\tAlt+X", ID_FILE_EXIT
+ END
+ POPUP "&View"
+ BEGIN
+ MENUITEM "Caption&&Menu\tCtrl+0", ID_VIEW_CAPTIONMENU
+ MENUITEM "&Seek Bar\tCtrl+1", ID_VIEW_SEEKER
+ MENUITEM "Cont&rols\tCtrl+2", ID_VIEW_CONTROLS
+ MENUITEM "&Information\tCtrl+3", ID_VIEW_INFORMATION
+ MENUITEM "S&tatistics\tCtrl+4", ID_VIEW_STATISTICS
+ MENUITEM "St&atus\tCtrl+5", ID_VIEW_STATUS
+ MENUITEM "Subresync\tCtrl+6", ID_VIEW_SUBRESYNC
+ MENUITEM "Playlist\tCtrl+7", ID_VIEW_PLAYLIST
+ MENUITEM "Capture\tCtrl+8", ID_VIEW_CAPTURE
+ MENUITEM "Shader Editor\tCtrl+9", ID_VIEW_SHADEREDITOR
+ POPUP "Presets..."
+ BEGIN
+ MENUITEM "Minimal", ID_VIEW_PRESETS_MINIMAL
+ MENUITEM "Compact", ID_VIEW_PRESETS_COMPACT
+ MENUITEM "Normal", ID_VIEW_PRESETS_NORMAL
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "Fu&ll Screen\tAlt+Enter", ID_VIEW_FULLSCREEN
+ POPUP "&Zoom"
+ BEGIN
+ MENUITEM "&50%\tAlt+1", ID_VIEW_ZOOM_50
+ MENUITEM "&100%\tAlt+2", ID_VIEW_ZOOM_100
+ MENUITEM "&200%\tAlt+3", ID_VIEW_ZOOM_200
+ MENUITEM "Auto Fit\tAlt+4", ID_VIEW_ZOOM_AUTOFIT
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "&Tearing Test\tCtrl+T", ID_VIEW_TEARING_TEST
+ MENUITEM "Remaining Time\tCtrl+I", ID_VIEW_REMAINING_TIME
+ MENUITEM SEPARATOR
+ POPUP "&Video Frame"
+ BEGIN
+ MENUITEM "&Half Size", ID_VIEW_VF_HALF
+ MENUITEM "&Normal Size", ID_VIEW_VF_NORMAL
+ MENUITEM "&Double Size", ID_VIEW_VF_DOUBLE
+ MENUITEM "&Stretch To Window", ID_VIEW_VF_STRETCH
+ MENUITEM "Touch Window From &Inside", ID_VIEW_VF_FROMINSIDE
+ MENUITEM "Touch Window From &Outside", ID_VIEW_VF_FROMOUTSIDE
+ MENUITEM SEPARATOR
+ MENUITEM "&Keep Aspect Ratio", ID_VIEW_VF_KEEPASPECTRATIO
+
+ POPUP "Override Aspect Ratio"
+ BEGIN
+ MENUITEM "Default", ID_ASPECTRATIO_SOURCE
+
+ MENUITEM "4:3", ID_ASPECTRATIO_4_3
+ MENUITEM "5:4", ID_ASPECTRATIO_5_4
+ MENUITEM "16:9", ID_ASPECTRATIO_16_9
+ END
+ MENUITEM "Correct Monitor/Desktop AR Diff",
+ ID_VIEW_VF_COMPMONDESKARDIFF
+
+ END
+ POPUP "Pan&&S&can"
+ BEGIN
+ MENUITEM "Increase Size\tNumpad 9", ID_VIEW_INCSIZE
+ MENUITEM "Decrease Size\tNumpad 1", ID_VIEW_DECSIZE
+ MENUITEM "Increase Width\tNumpad 6", ID_VIEW_INCWIDTH
+ MENUITEM "Decrease Width\tNumpad 4", ID_VIEW_DECWIDTH
+ MENUITEM "Increase Height\tNumpad 8", ID_VIEW_INCHEIGHT
+ MENUITEM "Decrease Height\tNumpad 2", ID_VIEW_DECHEIGHT
+ MENUITEM SEPARATOR
+ MENUITEM "Move Right\tCtrl+Numpad 6", ID_PANSCAN_MOVERIGHT
+ MENUITEM "Move Left\tCtrl+Numpad 4", ID_PANSCAN_MOVELEFT
+ MENUITEM "Move Up\tCtrl+Numpad 8", ID_PANSCAN_MOVEUP
+ MENUITEM "Move Down\tCtrl+Numpad 2", ID_PANSCAN_MOVEDOWN
+ MENUITEM "Center\tCtrl+Numpad 5", ID_PANSCAN_CENTER
+ MENUITEM SEPARATOR
+ MENUITEM "Reset\tNumpad 5", ID_VIEW_RESET
+ END
+ MENUITEM SEPARATOR
+ POPUP "On Top"
+ BEGIN
+ MENUITEM "Never", ID_ONTOP_NEVER
+ MENUITEM "Always", ID_ONTOP_ALWAYS
+ MENUITEM "While Playing", ID_ONTOP_WHILEPLAYING
+ END
+ MENUITEM "&Options...", ID_VIEW_OPTIONS
+ END
+ POPUP "&Play"
+ BEGIN
+ MENUITEM "&Play/Pause\tSpace", ID_PLAY_PLAYPAUSE
+ MENUITEM "&Stop\tPeriod", ID_PLAY_STOP
+ MENUITEM "F&rame Step\tRight", ID_PLAY_FRAMESTEP
+ MENUITEM "&Go To...\tCtrl+G", ID_PLAY_GOTO
+ MENUITEM SEPARATOR
+ MENUITEM "&Decrease Rate\tCtrl+Down", ID_PLAY_DECRATE
+ MENUITEM "&Increase Rate\tCtrl+Up", ID_PLAY_INCRATE
+ MENUITEM "Reset Rate\tCtrl+R", ID_PLAY_RESETRATE
+ MENUITEM SEPARATOR
+ MENUITEM "&Filters", 65535
+ MENUITEM "S&haders", 65535
+ MENUITEM SEPARATOR
+ MENUITEM "&Audio", 65535
+ MENUITEM "Su&btitles", 65535
+ MENUITEM SEPARATOR
+ POPUP "Vol&ume"
+ BEGIN
+ MENUITEM "&Up\tUp Arrow", ID_VOLUME_UP
+ MENUITEM "&Down\tDown Arrow", ID_VOLUME_DOWN
+ MENUITEM "&Mute\tCtrl+M", ID_VOLUME_MUTE
+ END
+ POPUP "After Playback"
+ BEGIN
+ MENUITEM "Close ", ID_AFTERPLAYBACK_CLOSE
+ MENUITEM "Stand By", ID_AFTERPLAYBACK_STANDBY
+ MENUITEM "Hibernate", ID_AFTERPLAYBACK_HIBERNATE
+
+ MENUITEM "Shutdown", ID_AFTERPLAYBACK_SHUTDOWN
+
+ MENUITEM "Log Off", ID_AFTERPLAYBACK_LOGOFF
+ MENUITEM SEPARATOR
+ MENUITEM "Do Nothing", ID_AFTERPLAYBACK_DONOTHING
+
+ END
+ END
+ POPUP "&Navigate"
+ BEGIN
+ MENUITEM "&Previous\tPage Up", ID_NAVIGATE_SKIPBACK
+ MENUITEM "&Next\tPage Down", ID_NAVIGATE_SKIPFORWARD
+ MENUITEM "&Jump To...", 65535
+ MENUITEM SEPARATOR
+ MENUITEM "A&udio Language", 65535
+ MENUITEM "Su&btitle Language", 65535
+ MENUITEM "Video Ang&le", 65535
+ MENUITEM SEPARATOR
+ MENUITEM "Title Menu\tAlt+T", ID_NAVIGATE_TITLEMENU
+ MENUITEM "&Root Menu\tAlt+R", ID_NAVIGATE_ROOTMENU
+ MENUITEM "&Subtitle Menu", ID_NAVIGATE_SUBPICTUREMENU
+ MENUITEM "&Audio Menu", ID_NAVIGATE_AUDIOMENU
+ MENUITEM "An&gle Menu", ID_NAVIGATE_ANGLEMENU
+ MENUITEM "&Chapter Menu", ID_NAVIGATE_CHAPTERMENU
+ END
+ MENUITEM "F&avorites", ID_FAVORITES
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "Home Page", ID_HELP_HOMEPAGE
+ MENUITEM "Documentation (sf.net)", ID_HELP_DOCUMENTATION
+ MENUITEM "Command Line Switches", ID_HELP_SHOWCOMMANDLINESWITCHES
+
+ MENUITEM SEPARATOR
+ MENUITEM "Donate!", ID_HELP_DONATE
+ MENUITEM SEPARATOR
+ MENUITEM "&About...", ID_HELP_ABOUT
+ END
+END
+
+IDR_POPUP MENU
+BEGIN
+ POPUP ""
+ BEGIN
+ MENUITEM "&Play/Pause", ID_PLAY_PLAYPAUSE
+ MENUITEM "&Stop", ID_PLAY_STOP
+ MENUITEM SEPARATOR
+ MENUITEM "Fu&ll Screen", ID_VIEW_FULLSCREEN
+ POPUP "&Zoom"
+ BEGIN
+ MENUITEM "&50%\tAlt+1", ID_VIEW_ZOOM_50
+ MENUITEM "&100%\tAlt+2", ID_VIEW_ZOOM_100
+ MENUITEM "&200%\tAlt+3", ID_VIEW_ZOOM_200
+ MENUITEM "Auto Fit\tAlt+4", ID_VIEW_ZOOM_AUTOFIT
+ END
+ MENUITEM SEPARATOR
+ POPUP "&Video Frame"
+ BEGIN
+ MENUITEM "&Half Size", ID_VIEW_VF_HALF
+ MENUITEM "&Normal Size", ID_VIEW_VF_NORMAL
+ MENUITEM "&Double Size", ID_VIEW_VF_DOUBLE
+ MENUITEM "&Stretch To Window", ID_VIEW_VF_STRETCH
+ MENUITEM "Touch Window From &Inside", ID_VIEW_VF_FROMINSIDE
+ MENUITEM "Touch Window From &Outside", ID_VIEW_VF_FROMOUTSIDE
+ MENUITEM SEPARATOR
+ MENUITEM "&Keep Aspect Ratio", ID_VIEW_VF_KEEPASPECTRATIO
+
+ POPUP "Override Aspect Ratio"
+ BEGIN
+ MENUITEM "Default", ID_ASPECTRATIO_SOURCE
+
+ MENUITEM "4:3", ID_ASPECTRATIO_4_3
+ MENUITEM "5:4", ID_ASPECTRATIO_5_4
+ MENUITEM "16:9", ID_ASPECTRATIO_16_9
+ END
+ MENUITEM "Correct Monitor/Desktop AR Diff",
+ ID_VIEW_VF_COMPMONDESKARDIFF
+
+ END
+ POPUP "Pan&&S&can"
+ BEGIN
+ MENUITEM "Increase Size\tNumpad 9", ID_VIEW_INCSIZE
+ MENUITEM "Decrease Size\tNumpad 1", ID_VIEW_DECSIZE
+ MENUITEM "Increase Width\tNumpad 6", ID_VIEW_INCWIDTH
+ MENUITEM "Decrease Width\tNumpad 4", ID_VIEW_DECWIDTH
+ MENUITEM "Increase Height\tNumpad 8", ID_VIEW_INCHEIGHT
+ MENUITEM "Decrease Height\tNumpad 2", ID_VIEW_DECHEIGHT
+ MENUITEM SEPARATOR
+ MENUITEM "Move Right\tCtrl+Numpad 6", ID_PANSCAN_MOVERIGHT
+ MENUITEM "Move Left\tCtrl+Numpad 4", ID_PANSCAN_MOVELEFT
+ MENUITEM "Move Up\tCtrl+Numpad 8", ID_PANSCAN_MOVEUP
+ MENUITEM "Move Down\tCtrl+Numpad 2", ID_PANSCAN_MOVEDOWN
+ MENUITEM "Center\tCtrl+Numpad 5", ID_PANSCAN_CENTER
+ MENUITEM SEPARATOR
+ MENUITEM "Reset\tNumpad 5", ID_VIEW_RESET
+ END
+ MENUITEM SEPARATOR
+ POPUP "&Navigate"
+ BEGIN
+ MENUITEM "&Previous\tPage Up", ID_NAVIGATE_SKIPBACK
+ MENUITEM "&Next\tPage Down", ID_NAVIGATE_SKIPFORWARD
+ MENUITEM "&Jump To...", 65535
+ MENUITEM SEPARATOR
+ MENUITEM "A&udio Language", 65535
+ MENUITEM "Su&btitle Language", 65535
+ MENUITEM "Video Ang&le", 65535
+ MENUITEM SEPARATOR
+ MENUITEM "&Title Menu", ID_NAVIGATE_TITLEMENU
+ MENUITEM "&Root Menu", ID_NAVIGATE_ROOTMENU
+ MENUITEM "&Subtitle Menu", ID_NAVIGATE_SUBPICTUREMENU
+
+ MENUITEM "&Audio Menu", ID_NAVIGATE_AUDIOMENU
+ MENUITEM "An&gle Menu", ID_NAVIGATE_ANGLEMENU
+ MENUITEM "&Chapter Menu", ID_NAVIGATE_CHAPTERMENU
+ END
+ MENUITEM "&Favorites", 65535
+ MENUITEM SEPARATOR
+ MENUITEM "F&ilters", 65535
+ MENUITEM "S&haders", 65535
+ MENUITEM SEPARATOR
+ MENUITEM "&Audio", 65535
+ MENUITEM "Su&btitles", 65535
+ MENUITEM SEPARATOR
+ POPUP "Vol&ume"
+ BEGIN
+ MENUITEM "&Up\tUp Arrow", ID_VOLUME_UP
+ MENUITEM "&Down\tDown Arrow", ID_VOLUME_DOWN
+ MENUITEM "&Mute\tCtrl+M", ID_VOLUME_MUTE
+ END
+ POPUP "After Playback"
+ BEGIN
+ MENUITEM "Close ", ID_AFTERPLAYBACK_CLOSE
+ MENUITEM "Stand By", ID_AFTERPLAYBACK_STANDBY
+ MENUITEM "Hibernate", ID_AFTERPLAYBACK_HIBERNATE
+
+ MENUITEM "Shutdown", ID_AFTERPLAYBACK_SHUTDOWN
+
+ MENUITEM "Log Off", ID_AFTERPLAYBACK_LOGOFF
+ MENUITEM SEPARATOR
+ MENUITEM "Do Nothing", ID_AFTERPLAYBACK_DONOTHING
+
+ END
+ MENUITEM SEPARATOR
+ POPUP "Vi&ew"
+ BEGIN
+ POPUP "On Top"
+ BEGIN
+ MENUITEM "Never", ID_ONTOP_NEVER
+ MENUITEM "Always", ID_ONTOP_ALWAYS
+ MENUITEM "While Playing", ID_ONTOP_WHILEPLAYING
+
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "Caption&&Menu", ID_VIEW_CAPTIONMENU
+ MENUITEM "Seek Bar", ID_VIEW_SEEKER
+ MENUITEM "Cont&rols", ID_VIEW_CONTROLS
+ MENUITEM "&Information", ID_VIEW_INFORMATION
+ MENUITEM "St&atistics", ID_VIEW_STATISTICS
+ MENUITEM "S&tatus", ID_VIEW_STATUS
+ MENUITEM "Subresync", ID_VIEW_SUBRESYNC
+ MENUITEM "Playlist", ID_VIEW_PLAYLIST
+ MENUITEM "Capture", ID_VIEW_CAPTURE
+ MENUITEM "Shader Editor", ID_VIEW_SHADEREDITOR
+ POPUP "Presets..."
+ BEGIN
+ MENUITEM "Minimal", ID_VIEW_PRESETS_MINIMAL
+
+ MENUITEM "Compact", ID_VIEW_PRESETS_COMPACT
+
+ MENUITEM "Normal", ID_VIEW_PRESETS_NORMAL
+
+ END
+ END
+ MENUITEM "P&roperties", ID_FILE_PROPERTIES
+ MENUITEM "&Options...", ID_VIEW_OPTIONS
+ END
+END
+
+IDR_POPUPMAIN MENU
+BEGIN
+ POPUP ""
+ BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&Quick Open File...\tCtrl+Q", ID_FILE_OPENQUICK
+ MENUITEM SEPARATOR
+ MENUITEM "&Open File...\tCtrl+O", ID_FILE_OPENMEDIA
+ MENUITEM "Open &DVD...\tCtrl+D", ID_FILE_OPENDVD
+ MENUITEM "Open De&vice...\tCtrl+V", ID_FILE_OPENDEVICE
+ MENUITEM "O&pen Disc", 65535
+ MENUITEM "&Close", ID_FILE_CLOSEPLAYLIST
+ MENUITEM SEPARATOR
+ MENUITEM "&Save As...", ID_FILE_SAVE_COPY
+ MENUITEM "Save Image...", ID_FILE_SAVE_IMAGE
+ MENUITEM "Save Thumbnails...", ID_FILE_SAVE_THUMBNAILS
+ MENUITEM SEPARATOR
+ MENUITEM "&Load Subtitle...\tCtrl+L", ID_FILE_LOAD_SUBTITLE
+ MENUITEM "Save Subtitle...\tCtrl+S", ID_FILE_SAVE_SUBTITLE
+ POPUP "Subtitle Database"
+ BEGIN
+ MENUITEM "Search...", ID_FILE_ISDB_SEARCH
+ MENUITEM "Upload...", ID_FILE_ISDB_UPLOAD
+ MENUITEM "Download...", ID_FILE_ISDB_DOWNLOAD
+
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "Prope&rties", ID_FILE_PROPERTIES
+ MENUITEM SEPARATOR
+ POPUP "Utils"
+ BEGIN
+ MENUITEM "DSM Co&nverter...", ID_FILE_CONVERT
+ END
+ END
+ POPUP "&View"
+ BEGIN
+ MENUITEM "Caption&&Menu\tCtrl+0", ID_VIEW_CAPTIONMENU
+ MENUITEM "&Seek Bar\tCtrl+1", ID_VIEW_SEEKER
+ MENUITEM "Cont&rols\tCtrl+2", ID_VIEW_CONTROLS
+ MENUITEM "&Information\tCtrl+3", ID_VIEW_INFORMATION
+ MENUITEM "S&tatistics\tCtrl+4", ID_VIEW_STATISTICS
+ MENUITEM "St&atus\tCtrl+5", ID_VIEW_STATUS
+ MENUITEM "Subresync\tCtrl+6", ID_VIEW_SUBRESYNC
+ MENUITEM "Playlist\tCtrl+7", ID_VIEW_PLAYLIST
+ MENUITEM "Capture\tCtrl+8", ID_VIEW_CAPTURE
+ MENUITEM "Shader Editor\tCtrl+9", ID_VIEW_SHADEREDITOR
+ POPUP "Presets..."
+ BEGIN
+ MENUITEM "Minimal", ID_VIEW_PRESETS_MINIMAL
+
+ MENUITEM "Compact", ID_VIEW_PRESETS_COMPACT
+
+ MENUITEM "Normal", ID_VIEW_PRESETS_NORMAL
+
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "Fu&ll Screen\tAlt+Enter", ID_VIEW_FULLSCREEN
+ POPUP "&Zoom"
+ BEGIN
+ MENUITEM "&50%\tAlt+1", ID_VIEW_ZOOM_50
+ MENUITEM "&100%\tAlt+2", ID_VIEW_ZOOM_100
+ MENUITEM "&200%\tAlt+3", ID_VIEW_ZOOM_200
+ MENUITEM "Auto Fit\tAlt+4", ID_VIEW_ZOOM_AUTOFIT
+ END
+ MENUITEM "&Tearing Test\tCtrl+T", 32769
+ MENUITEM SEPARATOR
+ POPUP "&Video Frame"
+ BEGIN
+ MENUITEM "&Half Size", ID_VIEW_VF_HALF
+ MENUITEM "&Normal Size", ID_VIEW_VF_NORMAL
+ MENUITEM "&Double Size", ID_VIEW_VF_DOUBLE
+ MENUITEM "&Stretch To Window", ID_VIEW_VF_STRETCH
+ MENUITEM "Touch Window From &Inside", ID_VIEW_VF_FROMINSIDE
+
+ MENUITEM "Touch Window From &Outside", ID_VIEW_VF_FROMOUTSIDE
+
+ MENUITEM SEPARATOR
+ MENUITEM "&Keep Aspect Ratio", ID_VIEW_VF_KEEPASPECTRATIO
+
+ POPUP "Override Aspect Ratio"
+ BEGIN
+ MENUITEM "Default", ID_ASPECTRATIO_SOURCE
+
+ MENUITEM "4:3", ID_ASPECTRATIO_4_3
+
+ MENUITEM "5:4", ID_ASPECTRATIO_5_4
+
+ MENUITEM "16:9", ID_ASPECTRATIO_16_9
+
+ END
+ MENUITEM "Correct Monitor/Desktop AR Diff",
+ ID_VIEW_VF_COMPMONDESKARDIFF
+
+ END
+ POPUP "Pan&&S&can"
+ BEGIN
+ MENUITEM "Increase Size\tNumpad 9", ID_VIEW_INCSIZE
+ MENUITEM "Decrease Size\tNumpad 1", ID_VIEW_DECSIZE
+ MENUITEM "Increase Width\tNumpad 6", ID_VIEW_INCWIDTH
+ MENUITEM "Decrease Width\tNumpad 4", ID_VIEW_DECWIDTH
+ MENUITEM "Increase Height\tNumpad 8", ID_VIEW_INCHEIGHT
+ MENUITEM "Decrease Height\tNumpad 2", ID_VIEW_DECHEIGHT
+ MENUITEM SEPARATOR
+ MENUITEM "Move Right\tCtrl+Numpad 6", ID_PANSCAN_MOVERIGHT
+ MENUITEM "Move Left\tCtrl+Numpad 4", ID_PANSCAN_MOVELEFT
+ MENUITEM "Move Up\tCtrl+Numpad 8", ID_PANSCAN_MOVEUP
+ MENUITEM "Move Down\tCtrl+Numpad 2", ID_PANSCAN_MOVEDOWN
+ MENUITEM "Center\tCtrl+Numpad 5", ID_PANSCAN_CENTER
+ MENUITEM SEPARATOR
+ MENUITEM "Reset\tNumpad 5", ID_VIEW_RESET
+ END
+ MENUITEM SEPARATOR
+ POPUP "On Top"
+ BEGIN
+ MENUITEM "Never", ID_ONTOP_NEVER
+ MENUITEM "Always", ID_ONTOP_ALWAYS
+ MENUITEM "While Playing", ID_ONTOP_WHILEPLAYING
+
+ END
+ MENUITEM "&Options...", ID_VIEW_OPTIONS
+ END
+ POPUP "&Play"
+ BEGIN
+ MENUITEM "&Play/Pause\tSpace", ID_PLAY_PLAYPAUSE
+ MENUITEM "&Stop\tPeriod", ID_PLAY_STOP
+ MENUITEM "F&rame Step\tRight", ID_PLAY_FRAMESTEP
+ MENUITEM "&Go To...\tCtrl+G", ID_PLAY_GOTO
+ MENUITEM SEPARATOR
+ MENUITEM "&Decrease Rate\tCtrl+Down", ID_PLAY_DECRATE
+ MENUITEM "&Increase Rate\tCtrl+Up", ID_PLAY_INCRATE
+ MENUITEM "Reset Rate\tCtrl+R", ID_PLAY_RESETRATE
+ END
+ POPUP "&Navigate"
+ BEGIN
+ MENUITEM "&Previous\tPage Up", ID_NAVIGATE_SKIPBACK
+ MENUITEM "&Next\tPage Down", ID_NAVIGATE_SKIPFORWARD
+ MENUITEM "&Jump To...", 65535
+ MENUITEM SEPARATOR
+ MENUITEM "A&udio Language", 65535
+ MENUITEM "Su&btitle Language", 65535
+ MENUITEM "Video Ang&le", 65535
+ MENUITEM SEPARATOR
+ MENUITEM "Title Menu\tAlt+T", ID_NAVIGATE_TITLEMENU
+ MENUITEM "&Root Menu\tAlt+R", ID_NAVIGATE_ROOTMENU
+ MENUITEM "&Subtitle Menu", ID_NAVIGATE_SUBPICTUREMENU
+
+ MENUITEM "&Audio Menu", ID_NAVIGATE_AUDIOMENU
+ MENUITEM "An&gle Menu", ID_NAVIGATE_ANGLEMENU
+ MENUITEM "&Chapter Menu", ID_NAVIGATE_CHAPTERMENU
+ END
+ MENUITEM "&Favorites", 65535
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "Home Page", ID_HELP_HOMEPAGE
+ MENUITEM "Command Line Switches", ID_HELP_SHOWCOMMANDLINESWITCHES
+
+ MENUITEM SEPARATOR
+ MENUITEM "Donate!", ID_HELP_DONATE
+ MENUITEM SEPARATOR
+ MENUITEM "&About...", ID_HELP_ABOUT
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "&Filters", 65535
+ MENUITEM "S&haders", ID__SHADERS
+ MENUITEM SEPARATOR
+ MENUITEM "&Audio", 65535
+ MENUITEM "Su&btitles", 65535
+ MENUITEM SEPARATOR
+ POPUP "Vol&ume"
+ BEGIN
+ MENUITEM "&Up\tUp Arrow", ID_VOLUME_UP
+ MENUITEM "&Down\tDown Arrow", ID_VOLUME_DOWN
+ MENUITEM "&Mute\tCtrl+M", ID_VOLUME_MUTE
+ END
+ POPUP "After Playback"
+ BEGIN
+ MENUITEM "Close ", ID_AFTERPLAYBACK_CLOSE
+ MENUITEM "Stand By", ID_AFTERPLAYBACK_STANDBY
+ MENUITEM "Hibernate", ID_AFTERPLAYBACK_HIBERNATE
+
+ MENUITEM "Shutdown", ID_AFTERPLAYBACK_SHUTDOWN
+
+ MENUITEM "Log Off", ID_AFTERPLAYBACK_LOGOFF
+ MENUITEM SEPARATOR
+ MENUITEM "Do Nothing", ID_AFTERPLAYBACK_DONOTHING
+
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit\tAlt+X", ID_FILE_EXIT
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// AVI
+//
+
+IDR_AVI_FILECOPY AVI "res\\ani.avi"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// HTML
+//
+
+IDR_HTML_INDEX HTML "res\\web\\index.html"
+IDR_HTML_404 HTML "res\\web\\404.html"
+IDR_HTML_BROWSER HTML "res\\web\\browser.html"
+IDR_HTML_CONTROLS HTML "res\\web\\controls.html"
+IDR_HTML_PLAYER HTML "res\\web\\player.html"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDR_MAINFRAME "Media Player Classic (Mod by Casimir666)"
+ IDS_RS_DVDPOS "Remember DVD Pos"
+ IDS_RS_FILEPOS "Remember File Pos"
+ IDS_RS_LASTFULLSCREEN "LastFullScreen"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_SHADER_TOGGLE "Toggle Pixel Shader"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_R_SETTINGS "Settings"
+ IDS_RS_TITLEBARTEXTSTYLE "TitleBarTextStyle"
+ IDS_RS_USEWMASFREADER "UseWMASFReader"
+ IDS_RS_CONTROLSTATE "ControlState"
+ IDS_RS_VOLUME "Volume"
+ IDS_RS_MUTE "Mute"
+ IDS_RS_BALANCE "Balance"
+ IDS_RS_LOOP "Loop"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_VIDRENDDESC "Move the mouse pointer over the choices to see their description."
+ IDS_CONVERT_ADDFILE "Add File..."
+ IDS_CONVERT_PROPERTIES "Properties..."
+ IDS_CONVERT_REMOVE "Remove"
+ IDS_CONVERT_ENABLESTREAM "Enable Stream"
+ IDS_CONVERT_DISABLESTREAM "Disable Stream"
+ IDS_CONVERT_PINPROPERTIES "Pin Properties..."
+ IDS_CONVERT_ADDRESOURCE "Add Resource..."
+ IDS_CONVERT_REMOVEALL "Remove All"
+ IDS_CONVERT_SAVEAS "Save As..."
+ IDS_CONVERT_RESOURCEPROPERTIES "Resource Properties..."
+ IDS_CONVERT_LAUNCHINBROWSER "Launch in Browser..."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_CONVERT_ADDCHAPTER "Add Chapter..."
+ IDS_CONVERT_CHAPTERPROPERTIES "Chapter Properties..."
+ IDS_CONVERT_DEMUXSTREAM "Demux..."
+ IDS_PLAYLIST_OPEN "&Open"
+ IDS_PLAYLIST_ADD "A&dd"
+ IDS_PLAYLIST_REMOVE "&Remove"
+ IDS_PLAYLIST_COPYTOCLIPBOARD "&Copy to clipboard"
+ IDS_PLAYLIST_SAVEAS "&Save As..."
+ IDS_PLAYLIST_SORTBYLABEL "Sort by &label"
+ IDS_PLAYLIST_SORTBYPATH "Sort by &path"
+ IDS_PLAYLIST_RANDOMIZE "R&andomize"
+ IDS_PLAYLIST_RESTORE "R&estore"
+ IDS_SUBRESYNC_SEPARATOR "&Separator"
+ IDS_SUBRESYNC_DELETE "&Delete"
+ IDS_SUBRESYNC_DUPLICATE "D&uplicate"
+ IDS_SUBRESYNC_RESET "&Reset"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_RS_LOOPNUM "LoopNum"
+ IDS_RS_REWIND "Rewind"
+ IDS_RS_ZOOM "Zoom"
+ IDS_RS_MULTIINST "AllowMultipleInstances"
+ IDS_RS_ALWAYSONTOP "AlwaysOnTop"
+ IDS_RS_AUTOZOOM "AutoZoom"
+ IDS_RS_FULLSCREENCTRLS "FullScreenCtrls"
+ IDS_RS_FULLSCREENCTRLSTIMEOUT "FullScreenCtrlsTimeOut"
+ IDS_RS_VMRFLIP "VMRFlip"
+ IDS_RS_DVDPATH "DVDPath"
+ IDS_RS_USEDVDPATH "UseDVDPath"
+ IDS_RS_MENULANG "MenuLang"
+ IDS_RS_AUDIOLANG "AudioLang"
+ IDS_RS_SUBTITLESLANG "SubtitlesLang"
+ IDS_RS_SPLOGFONT "SPDefaultStyle"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_RS_SPOVERRIDEPLACEMENT "SPOverridePlacement"
+ IDS_RS_SPHORPOS "SPHorPos"
+ IDS_RS_SPVERPOS "SPVerPos"
+ IDS_RS_SPCSIZE "SPCSize"
+ IDS_RS_SPCMAXRES "SPCMaxRes"
+ IDS_RS_INTREALMEDIA "IntRealMedia"
+ IDS_RS_DISABLEXPTOOLBARS "DisableXPToolbars"
+ IDS_RS_USEDEDYNAMIC "UseDeDynamic"
+ IDS_RS_DBLCLICKFULLSCREEN "DblClickFullScreen"
+ IDS_RS_EXITFULLSCREENATTHEEND "ExitFullscreenAtTheEnd"
+END
+
+STRINGTABLE
+BEGIN
+ AFX_IDS_APP_TITLE "Media Player Classic (Mod by Casimir666)"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_RS_AUTOSPEAKERCONF "AutoSpeakerConf"
+ IDS_RS_REMEMBERWINDOWPOS "RememberWindowPos"
+ IDS_RS_LASTWINDOWRECT "LastWindowRect"
+ IDS_RS_AUDIORENDERERTYPE "AudioRendererType"
+ IDS_RS_SPEAKERTOCHANNELMAPPING "SpeakerToChannelMapping"
+ IDS_RS_CUSTOMCHANNELMAPPING "CustomChannelMapping"
+ IDS_RS_DOWNSAMPLETO441 "DownSampleTo441"
+ IDS_RS_ENABLEAUDIOSWITCHER "EnableAudioSwitcher"
+ IDS_RS_HIDECAPTIONMENU "HideCaptionMenu"
+ IDS_R_FILTERS "Filters"
+ IDS_RS_DEFAULTVIDEOFRAME "DefaultVideoFrame"
+ IDS_RS_REMEMBERWINDOWSIZE "RememberWindowSize"
+ IDS_RS_REALMEDIARENDERLESS "RealMediaRenderless"
+ IDS_RS_QUICKTIMERENDERER "QuickTimeRenderer"
+ IDS_RS_REALMEDIAFPS "RealMediaFPS"
+ IDS_RS_AUDIOTIMESHIFT "AudioTimeShift"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_RS_SNAPTODESKTOPEDGES "SnapToDesktopEdges"
+ IDS_RS_ENABLESUBTITLES "EnableSubtitles"
+ IDS_RS_MPEGINTERLACED "MPEGInterlaced"
+ IDS_RS_THUMBWIDTH "ThumbWidth"
+ IDS_RS_AUDIONORMALIZE "AudioNormalize"
+ IDS_RS_AUDIOBOOST "AudioBoost"
+ IDS_RS_D3DFULLSCREEN "D3DFullScreen"
+ IDS_RS_MONITOR_AUTOREFRESHRATE "MonitorAutoRefreshRate"
+ IDS_RS_COLOR_BRIGHTNESS "Color Brightness"
+ IDS_RS_COLOR_CONTRAST "Color Contrast"
+ IDS_RS_COLOR_HUE "Color Hue"
+ IDS_RS_COLOR_SATURATION "Color Saturation"
+ IDS_RS_SHADERLIST "Shaders List"
+ IDS_RS_TITLEBARTEXTTITLE "TitleBarTextTitle"
+ IDS_RS_VMR9MIXERYUV "VMRMixerYUV"
+ IDS_RS_AUDIONORMALIZERECOVER "AudioNormalizeRecover"
+END
+
+STRINGTABLE
+BEGIN
+ IDD_PPAGEPLAYBACK "Playback"
+ IDD_PPAGEPLAYER "Player"
+ IDD_PPAGEDVD "Playback::DVD/OGM"
+ IDD_PPAGESUBTITLES "Subtitles"
+ IDD_PPAGEFORMATS "Player::Formats"
+ IDD_PPAGETWEAKS "Tweaks"
+ IDD_PPAGEAUDIOSWITCHER "Internal Filters::Audio Switcher"
+ IDD_PPAGEEXTERNALFILTERS "External Filters"
+END
+
+STRINGTABLE
+BEGIN
+ IDB_LOGO3 "Andrew S. Gildehaus, agildehaus@runbox.com"
+ IDB_LOGO4 "Marcel Hoffs, marcelhoffs@hotmail.com"
+ IDB_LOGO7 "Steven W. Smith, smith78@sbcglobal.net"
+END
+
+STRINGTABLE
+BEGIN
+ IDD_PPAGEACCELTBL "Player::Keys"
+ IDD_PPAGESUBSTYLE "Subtitles::Default Style"
+ IDD_PPAGEINTERNALFILTERS "Internal Filters"
+ IDD_PPAGELOGO "Player::Logo"
+ IDD_PPAGEOUTPUT "Playback::Output"
+ IDD_PPAGEWEBSERVER "Player::Web Interface"
+ IDD_PPAGEAUDIODEC "Internal Filters::Audio Decoders"
+ IDD_PPAGESUBDB "Subtitles::Database"
+END
+
+STRINGTABLE
+BEGIN
+ IDD_FILEPROPDETAILS "Details"
+ IDD_FILEPROPCLIP "Clip"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_RS_ENABLEAUDIOTIMESHIFT "EnableAudioTimeShift"
+ IDS_R_FAVFILES "Favorites\\Files"
+ IDS_R_FAVDVDS "Favorites\\DVDs"
+ IDS_R_FAVDEVICES "Favorites\\Devices"
+ IDS_RS_LOGOFILE "LogoFile"
+ IDS_RS_ENABLEWORKERTHREADFOROPENING "EnableWorkerThreadForOpening"
+ IDS_RS_PNSPRESETS "PnSPresets"
+ IDS_RS_AUTOLOADAUDIO "AutoloadAudio"
+ IDS_RS_AUTOLOADSUBTITLES "AutoloadSubtitles"
+ IDS_RS_SEARCHKEYFRAMES "SearchKeyframes"
+ IDS_RS_ACCELTBL "AccelTbl"
+ IDS_RS_SETFULLSCREENRES "SetFullscreenRes"
+ IDS_RS_FULLSCREENRES "FullscreenRes"
+ IDS_RS_WINLIRCADDR "WinLircAddr"
+ IDS_R_COMMANDS "Commands2"
+ IDS_RS_WINLIRC "UseWinLirc"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_RS_TRAYICON "TrayIcon"
+ IDS_RS_KEEPASPECTRATIO "KeepAspectRatio"
+ IDS_RS_UICEADDR "UICEAddr"
+ IDS_RS_UICE "UseUICE"
+ IDS_RS_JUMPDISTS "JumpDistS"
+ IDS_RS_JUMPDISTM "JumpDistM"
+ IDS_RS_JUMPDISTL "JumpDistL"
+ IDS_RS_REPORTFAILEDPINS "ReportFailedPins"
+ IDS_RS_SRCFILTERS "SrcFilters"
+ IDS_RS_KEEPHISTORY "KeepHistory"
+ IDS_RS_LOGOID "LogoID2"
+ IDS_RS_LOGOEXT "LogoExt"
+ IDS_RS_TRAFILTERS "TraFilters"
+ IDS_RS_MPEGDI "MPEGDI"
+ IDS_RS_MPEGBRIGHT "MPEGBright"
+ IDS_RS_MPEGCONT "MPEGCont"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_RS_MPEGHUE "MPEGHue"
+ IDS_RS_MPEGSAT "MPEGSat"
+ IDS_RS_MPEGFORCEDSUBS "MPEGForcedSubs"
+ IDS_RS_MPEGPLANARYUV "MPEGPlanarYUV"
+ IDS_RS_COMPMONDESKARDIFF "CompMonDeskARDiff"
+ IDS_RS_HIDECDROMSSUBMENU "HideCDROMsSubMenu"
+ IDS_RS_VMRTEXTURE "VMRTexture"
+ IDS_RS_VMR3D "VMR3D"
+ IDS_RS_DSVIDEORENDERERTYPE "DSVidRen"
+ IDS_RS_RMVIDEORENDERERTYPE "RMVidRen"
+ IDS_RS_QTVIDEORENDERERTYPE "QTVidRen"
+ IDS_RS_APSURACEFUSAGE "APSurfaceUsage"
+ IDS_R_LOGINS "Logins"
+ IDS_RS_ENABLEWEBSERVER "EnableWebServer"
+ IDS_RS_WEBSERVERPORT "WebServerPort"
+ IDS_RS_LASTWINDOWTYPE "LastWindowType"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_RS_ONTOP "OnTop"
+ IDS_RS_MPASF "MPASampleFormat"
+ IDS_RS_AC3SC "AC3SpeakerConfig"
+ IDS_RS_AC3DRC "AC3DynamicRangeControl"
+ IDS_RS_WEBSERVERPRINTDEBUGINFO "WebServerPrintDebugIfo"
+ IDS_RS_WEBSERVERUSECOMPRESSION "WebServerUseCompression"
+ IDS_RS_MPANORMALIZE "MPANormalize"
+ IDS_RS_DTSSC "DTSSpeakerConfig"
+ IDS_RS_DTSDRC "DTSDynamicRangeControl"
+ IDS_RS_SNAPSHOTPATH "SnapShotPath"
+ IDS_RS_PRIORITY "Priority"
+ IDS_RS_SNAPSHOTEXT "SnapShotExt"
+ IDS_RS_LAUNCHFULLSCREEN "LaunchFullScreen"
+ IDS_RS_MPABOOST "MpaBoost"
+ IDS_RS_AACSC "AACSpeakerConfig"
+ IDS_RS_VMRSYNCFIX "VMRSyncFix"
+END
+
+STRINGTABLE
+BEGIN
+ IDC_DSSYSDEF "Default video renderer filter for DirectShow. Others will fall back to this one when they can't be loaded for some reason. On Windown XP this is the same as VMR7 (windowed)."
+ IDC_DSOLD "This is the default renderer of Windows 9x/me/2k. Depending on the visiblity of the video window and your video card's abilies, it will switch between GDI, DirectDraw, Overlay rendering modes dynamically."
+ IDC_DSOVERLAYMIXER "Always renders in overlay. Generally only YUV formats are allowed, but they are presented directly without any color conversion to RGB. This is the fastest rendering method of all and the only where you can be sure about full screen video mirroring to tv-out activating."
+ IDC_DSVMR7WIN "The default renderer of Windows XP. Very stable and just a little slower than the Overlay mixer. Uses DirectDraw and runs in Overlay when it can."
+ IDC_DSVMR9WIN "Only available if you have DirectX 9 installed. Has the same abilies as VMR7 (windowed), but it will never use Overlay rendering and because of this it may be a little slower than VMR7 (windowed)."
+ IDC_DSVMR7REN "Same as the VMR7 (windowed), but with the Allocator-Presenter plugin of MPC for subtitling. Overlay video mirroring WILL NOT work. 'True Color' desktop color space recommended."
+ IDC_DSVMR9REN "Same as the VMR9 (windowed), but with the Allocator-Presenter plugin of MPC for subtitling. Overlay video mirroring MIGHT work. 'True Color' desktop color space recommended."
+ IDC_DSNULL_COMP "Connects to any video-like media type and will send the incoming samples to nowhere. Use it when you don't need the video display and want to save the cpu from working unnecessarily."
+ IDC_DSNULL_UNCOMP "Same as the normal Null renderer, but this will only connect to uncompressed types."
+END
+
+STRINGTABLE
+BEGIN
+ IDC_RMSYSDEF "Real's own renderer. SMIL scripts will work, but interaction not likely. Uses DirectDraw and runs in Overlay when it can."
+ IDC_RMDX7 "The output of Real's engine rendered by the DX7-based Allocator-Presenter of VMR7 (renderless)."
+ IDC_RMDX9 "The output of Real's engine rendered by the DX9-based Allocator-Presenter of VMR9 (renderless)."
+ IDC_QTSYSDEF "QuickTime's own renderer. Gets a little slow when its video area is resized or partially covered by another window. When Overlay is not available it likes to fall back to GDI."
+ IDC_QTDX7 "The output of QuickTime's engine rendered by the DX7-based Allocator-Presenter of VMR7 (renderless)."
+ IDC_QTDX9 "The output of QuickTime's engine rendered by the DX9-based Allocator-Presenter of VMR9 (renderless)."
+ IDC_REGULARSURF "Video surface will be allocated as a regular offscreen surface."
+END
+
+STRINGTABLE
+BEGIN
+ IDC_TEXTURESURF2D "Video surface will be allocated as a texture but still the 2d functions will be used to copy and stretch it onto the backbuffer. Requires a video card which can allocate 32bit, RGBA, non-power-of-two sized textures and at least in the resolution of the video."
+ IDC_TEXTURESURF3D "Video surface will be allocated as a texture and drawn as two triangles in 3d. Antialiasing turned on at the display settings may have a bad effect on the rendering speed."
+ IDC_DX9RESIZER_COMBO "If there is no Pixel Shader 2.0 support, simple bilinear is used automatically."
+ IDC_DSVMR9LOADMIXER "Puts VMR9 (renderless) into mixer mode, this means most of the controls on its property page will work and it will use a separate worker thread to renderer frames."
+ IDC_CHECK_MPEGINTERLACED
+ "Use it together with ""Weave"" if the video renderer can also deinterlace. The currently loaded file has to be opened again."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_SRC_RADGT "6.4.0.0\nRequires smackw32.dll and binkw32.dll"
+ IDS_SRC_CDDA "6.4.0.1\n2K/XP only"
+ IDS_SRC_AVI "6.4.0.6\nNon-interleaved files are not welcome"
+ IDS_SRC_CDXA "6.4.0.1"
+ IDS_SRC_VTS "6.4.0.0\nOpen VTS_xx_0.ifo to load VTS_xx_x.vob files in one piece"
+ IDS_SRC_FLIC "6.4.0.0"
+ IDS_SRC_D2V "6.4.0.0"
+ IDS_SRC_DTSAC3 "6.4.0.1"
+ IDS_SRC_SHOUTCAST "6.4.0.1"
+ IDS_SRC_REALMEDIA "6.4.1.1\nRealMedia format categories must be set to 'DirectShow' to make it load\nDoesn't support streaming"
+ IDS_SRC_MATROSKA "6.4.2.8"
+ IDS_SRC_ROQ "6.4.0.0"
+ IDS_SRC_OGG "6.4.0.2"
+ IDS_SRC_NUT "6.4.0.0\nBased on ""NUT Open Container Format DRAFT 20030906""\nStill very incomplete, if you have or can make test files, please contact me."
+ IDS_SRC_DIRAC "6.4.0.1\nBased on libdirac 0.5.0"
+ IDS_SRC_DSM "6.4.0.5"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_SRC_MPA "6.4.0.2\nSource filter for mp3 and aac"
+ IDS_SRC_MP4 "6.4.0.1"
+ IDS_TRA_RV "6.4.1.0\nRequires RealVideo decoder dlls, RV10 also works with ffdshow"
+ IDS_TRA_RA "6.4.1.0\nRequires RealAudio decoder dlls, DNET also works with ac3filter"
+ IDS_TRA_MPEG1 "6.4.0.1\nBased on libmpeg2 (mpeg1 video decoding is bogus)"
+ IDS_TRA_MPEG2 "6.4.0.1\nBased on libmpeg2"
+ IDS_TRA_MPA "6.4.0.2\nBased on libmad, liba52, libdts, libfaad"
+ IDS_TRA_LPCM "6.4.0.1"
+ IDS_TRA_AC3 "6.4.0.1\nBased on liba52 0.7.4, http://liba52.sourceforge.net/"
+ IDS_TRA_DTS "6.4.0.1\nBased on libdts 0.0.2, http://www.videolan.org/dtsdec.html"
+ IDS_TRA_AAC "6.4.0.1\nBased on libfaad 2.0, http://www.audiocoding.com/"
+ IDS_TRA_DIRAC "6.4.0.1\nBased on libdirac 0.5.0"
+ IDS_TRA_PS2AUD "6.4.0.1\nDecodes audio streams of PSS files"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_RS_ISDB "ISDb"
+ IDS_RS_POW2TEX "SPCPow2Tex"
+ IDS_R_INTERNAL_FILTERS "Internal Filters"
+ IDS_RS_WEBROOT "WebRoot"
+ IDS_RS_WEBSERVERLOCALHOSTONLY "WebServerLocalhostOnly"
+ IDS_RS_ASPECTRATIO_X "AspectRatioX"
+ IDS_RS_ASPECTRATIO_Y "AspectRatioY"
+ IDS_RS_DX9_RESIZER "DX9Resizer"
+ IDS_RS_WEBSERVERCGI "WebServerCGI"
+ IDS_RS_WEBDEFINDEX "WebDefIndex"
+ IDS_RS_FREEWINDOWRESIZING "FreeWindowResizing"
+ IDS_RS_NOTIFYMSN "NotifyMSN2"
+ IDS_RS_NOTIFYGTSDLL "NotifyGTSdll"
+ IDS_RS_VMR9MIXERMODE "VMR9MixerMode"
+ IDS_RS_THUMBROWS "ThumbRows"
+ IDS_RS_THUMBCOLS "ThumbCols"
+END
+
+STRINGTABLE
+BEGIN
+ IDC_CHECK_RELATIVETO "Default state gets inherited to other styles where it is still undefined"
+ IDC_CHECK_SPCPOW2TEX "Unchecking this frees up a little video memory and saves bandwidth on local to video memory transfers, but it may not work with older video cards."
+ IDC_BUTTON_EXT_SET "After clicking this button, the checked state of the format group will reflect the actual file association for mpc. A newly added extension will usually make it grayed, so don't forget to check it again before closing this dialog!"
+END
+
+STRINGTABLE
+BEGIN
+ ID_PLAY_PLAY "Play\nPlay"
+ ID_PLAY_PAUSE "Pause\nPause"
+ ID_PLAY_STOP "Stop\nStop"
+ ID_PLAY_FRAMESTEP "Step\nStep"
+ ID_PLAY_DECRATE "Decrease speed\nDecrease speed"
+ ID_PLAY_INCRATE "Increase speed\nIncrease speed"
+END
+
+STRINGTABLE
+BEGIN
+ ID_VOLUME_MUTE "Mute\nMute"
+ ID_VOLUME_MUTE_ON "Mute\nMute"
+ ID_VOLUME_MUTE_DISABLED "No audio\nNo audio"
+END
+
+STRINGTABLE
+BEGIN
+ ID_NAVIGATE_SKIPBACK "Skip back\nSkip back"
+ ID_NAVIGATE_SKIPFORWARD "Skip forward\nSkip forward"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_SUBRESYNC_ORIGINAL "&Original"
+ IDS_SUBRESYNC_CURRENT "&Current"
+ IDS_SUBRESYNC_EDIT "&Edit"
+ IDS_SUBRESYNC_YES "&Yes"
+ IDS_SUBRESYNC_NO "&No"
+ IDS_SUBRESYNC_DECREASE "&Decrease"
+ IDS_SUBRESYNC_INCREASE "&Increase"
+ IDS_OPTIONS_CAPTION "Options"
+ IDS_SHADER_COMBINE "&Combine..."
+ IDS_SHADER_OFF "Off"
+ IDS_SHADER_POPUP "Shaders"
+ IDS_FAVORITES_POPUP "F&avorites"
+ IDS_JUMPTO_POPUP "Jump To..."
+ IDS_VIDEOANGLE_POPUP "Video Angle"
+ IDS_SUBTITLELANGUAGE_POPUP "Subtitle Language"
+ IDS_AUDIOLANGUAGE_POPUP "Audio Language"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_INFOBAR_LOCATION "Location"
+ IDS_INFOBAR_VIDEO "Video"
+ IDS_INFOBAR_AUDIO "Audio"
+ IDS_INFOBAR_SUBTITLES "Subtitles"
+ IDS_CONTROLS_COMPLETING "Completing..."
+ IDS_AUTOPLAY_PLAYVIDEO "Play Video"
+ IDS_AUTOPLAY_PLAYMUSIC "Play Music"
+ IDS_AUTOPLAY_PLAYAUDIOCD "Play Audio CD"
+ IDS_AUTOPLAY_PLAYDVDMOVIE "Play DVD Movie"
+ IDS_PROPSHEET_PROPERTIES "Properties"
+ IDS_GRAPHBUILDER_AUDIOSWITCHER "Audio Switcher"
+ IDS_SHADER_EDIT "&Edit..."
+END
+
+STRINGTABLE
+BEGIN
+ IDD_FILEPROPRES "Resources"
+ IDD_PPAGECASIMIR "Casimir666"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_SUBTITLES_POPUP "Subtitles"
+ IDS_AUDIO_POPUP "Audio"
+ IDS_FILTERS_POPUP "Filters"
+ IDS_OPENCDROM_POPUP "O&pen Disc"
+ IDS_NAVIGATE_POPUP "Navigate"
+ IDS_VIDEOFRAME_POPUP "Video Frame"
+ IDS_PANSCAN_POPUP "Pan&&Scan"
+ IDS_ASPECTRATIO_POPUP "Aspect Ratio"
+ IDS_ZOOM_POPUP "Zoom"
+ IDS_FAVORITES_ADD "&Add to Favorites..."
+ IDS_FAVORITES_ORGANIZE "&Organize Favorites..."
+ IDS_PLAYLIST_SHUFFLE "Shuffle"
+ IDS_PLAYLIST_REMEBERITEMS "Remember items"
+ IDS_CONTROLS_CLOSING "Closing..."
+ IDS_CONTROLS_PLAYING "Playing"
+ IDS_CONTROLS_PAUSED "Paused"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_CONTROLS_STOPPED "Stopped"
+ IDS_CONTROLS_BUFFERING "Buffering... (%d%%)"
+ IDS_CONTROLS_CAPTURING "Capturing..."
+ IDS_CONTROLS_OPENING "Opening..."
+ IDS_CONTROLS_CLOSED "Closed"
+ IDS_SUBTITLES_OPTIONS "&Options..."
+ IDS_SUBTITLES_STYLES "&Styles..."
+ IDS_SUBTITLES_RELOAD "&Reload"
+ IDS_SUBTITLES_ENABLE "&Enable"
+ IDS_PANSCAN_EDIT "Edit..."
+ IDS_INFOBAR_TITLE "Title"
+ IDS_INFOBAR_AUTHOR "Author"
+ IDS_INFOBAR_COPYRIGHT "Copyright"
+ IDS_INFOBAR_RATING "Rating"
+ IDS_INFOBAR_DESCRIPTION "Description"
+ IDS_INFOBAR_DOMAIN "Domain"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral (Sys. Default) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUSD)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// FILE
+//
+
+IDF_SHADER_EDGE_SHARPEN FILE "res\\shaders\\EdgeSharpen.psh"
+IDF_SHADER_SHARPEN_COMPLEX FILE "res\\shaders\\SharpenComplex.psh"
+#endif // Neutral (Sys. Default) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#include "afxres.rc" // Standard components
+#endif
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/src/apps/mplayerc/mplayerc.sln b/src/apps/mplayerc/mplayerc.sln
new file mode 100644
index 000000000..e954a879a
--- /dev/null
+++ b/src/apps/mplayerc/mplayerc.sln
@@ -0,0 +1,147 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mplayerc", "mplayerc.vcproj", "{8CE7E5D0-C821-47AC-A247-28EC95B34670}"
+ ProjectSection(ProjectDependencies) = postProject
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575} = {1A2DFD1A-3C6C-44D1-909D-294AF646B575}
+ {03208025-D5C2-426A-B0FA-251D4338F30C} = {03208025-D5C2-426A-B0FA-251D4338F30C}
+ {AB494732-EF6D-44D0-BCF8-80FF04858D10} = {AB494732-EF6D-44D0-BCF8-80FF04858D10}
+ {61E6EB4D-2F1A-443B-94B0-E8200B26E99F} = {61E6EB4D-2F1A-443B-94B0-E8200B26E99F}
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4} = {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0} = {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}
+ {FC70988B-1AE5-4381-866D-4F405E28AC42} = {FC70988B-1AE5-4381-866D-4F405E28AC42}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "subtitles", "..\..\subtitles\subtitles.vcproj", "{5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}"
+ ProjectSection(ProjectDependencies) = postProject
+ {D514EA4D-EAFB-47A9-A437-A582CA571251} = {D514EA4D-EAFB-47A9-A437-A582CA571251}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dsutil", "..\..\dsutil\dsutil.vcproj", "{FC70988B-1AE5-4381-866D-4F405E28AC42}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "subpic", "..\..\subpic\subpic.vcproj", "{D514EA4D-EAFB-47A9-A437-A582CA571251}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "decss", "..\..\decss\decss.vcproj", "{1A2DFD1A-3C6C-44D1-909D-294AF646B575}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ResizableLib", "..\..\ui\ResizableLib\ResizableLib.vcproj", "{4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CmdUI", "..\..\ui\CmdUI\CmdUI.vcproj", "{03208025-D5C2-426A-B0FA-251D4338F30C}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sizecbar", "..\..\ui\sizecbar\sizecbar.vcproj", "{61E6EB4D-2F1A-443B-94B0-E8200B26E99F}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TreePropSheet", "..\..\ui\TreePropSheet\TreePropSheet.vcproj", "{AB494732-EF6D-44D0-BCF8-80FF04858D10}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Debug Unicode = Debug Unicode
+ Release = Release
+ Release Unicode = Release Unicode
+ ResourceDLL = ResourceDLL
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {8CE7E5D0-C821-47AC-A247-28EC95B34670}.Debug.ActiveCfg = Debug|Win32
+ {8CE7E5D0-C821-47AC-A247-28EC95B34670}.Debug.Build.0 = Debug|Win32
+ {8CE7E5D0-C821-47AC-A247-28EC95B34670}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {8CE7E5D0-C821-47AC-A247-28EC95B34670}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {8CE7E5D0-C821-47AC-A247-28EC95B34670}.Release.ActiveCfg = Release|Win32
+ {8CE7E5D0-C821-47AC-A247-28EC95B34670}.Release.Build.0 = Release|Win32
+ {8CE7E5D0-C821-47AC-A247-28EC95B34670}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {8CE7E5D0-C821-47AC-A247-28EC95B34670}.Release Unicode.Build.0 = Release Unicode|Win32
+ {8CE7E5D0-C821-47AC-A247-28EC95B34670}.ResourceDLL.ActiveCfg = ResourceDLL|Win32
+ {8CE7E5D0-C821-47AC-A247-28EC95B34670}.ResourceDLL.Build.0 = ResourceDLL|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Debug.ActiveCfg = Debug|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Debug.Build.0 = Debug|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Release.ActiveCfg = Release|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Release.Build.0 = Release|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Release Unicode.Build.0 = Release Unicode|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.ResourceDLL.ActiveCfg = Release Unicode|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Debug.ActiveCfg = Debug|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Debug.Build.0 = Debug|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Release.ActiveCfg = Release|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Release.Build.0 = Release|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.Release Unicode.Build.0 = Release Unicode|Win32
+ {FC70988B-1AE5-4381-866D-4F405E28AC42}.ResourceDLL.ActiveCfg = Release Unicode|Win32
+ {D514EA4D-EAFB-47A9-A437-A582CA571251}.Debug.ActiveCfg = Debug|Win32
+ {D514EA4D-EAFB-47A9-A437-A582CA571251}.Debug.Build.0 = Debug|Win32
+ {D514EA4D-EAFB-47A9-A437-A582CA571251}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {D514EA4D-EAFB-47A9-A437-A582CA571251}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {D514EA4D-EAFB-47A9-A437-A582CA571251}.Release.ActiveCfg = Release|Win32
+ {D514EA4D-EAFB-47A9-A437-A582CA571251}.Release.Build.0 = Release|Win32
+ {D514EA4D-EAFB-47A9-A437-A582CA571251}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {D514EA4D-EAFB-47A9-A437-A582CA571251}.Release Unicode.Build.0 = Release Unicode|Win32
+ {D514EA4D-EAFB-47A9-A437-A582CA571251}.ResourceDLL.ActiveCfg = Release Unicode|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Debug.ActiveCfg = Debug|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Debug.Build.0 = Debug|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Release.ActiveCfg = Release|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Release.Build.0 = Release|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Release Unicode.Build.0 = Release Unicode|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.ResourceDLL.ActiveCfg = Release Unicode|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.ResourceDLL.Build.0 = Release Unicode|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Debug.ActiveCfg = Debug|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Debug.Build.0 = Debug|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Release.ActiveCfg = Release|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Release.Build.0 = Release|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.Release Unicode.Build.0 = Release Unicode|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.ResourceDLL.ActiveCfg = Release Unicode|Win32
+ {4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}.ResourceDLL.Build.0 = Release Unicode|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Debug.ActiveCfg = Debug|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Debug.Build.0 = Debug|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Release.ActiveCfg = Release|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Release.Build.0 = Release|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.Release Unicode.Build.0 = Release Unicode|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.ResourceDLL.ActiveCfg = Release Unicode|Win32
+ {03208025-D5C2-426A-B0FA-251D4338F30C}.ResourceDLL.Build.0 = Release Unicode|Win32
+ {61E6EB4D-2F1A-443B-94B0-E8200B26E99F}.Debug.ActiveCfg = Debug|Win32
+ {61E6EB4D-2F1A-443B-94B0-E8200B26E99F}.Debug.Build.0 = Debug|Win32
+ {61E6EB4D-2F1A-443B-94B0-E8200B26E99F}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {61E6EB4D-2F1A-443B-94B0-E8200B26E99F}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {61E6EB4D-2F1A-443B-94B0-E8200B26E99F}.Release.ActiveCfg = Release|Win32
+ {61E6EB4D-2F1A-443B-94B0-E8200B26E99F}.Release.Build.0 = Release|Win32
+ {61E6EB4D-2F1A-443B-94B0-E8200B26E99F}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {61E6EB4D-2F1A-443B-94B0-E8200B26E99F}.Release Unicode.Build.0 = Release Unicode|Win32
+ {61E6EB4D-2F1A-443B-94B0-E8200B26E99F}.ResourceDLL.ActiveCfg = Release Unicode|Win32
+ {61E6EB4D-2F1A-443B-94B0-E8200B26E99F}.ResourceDLL.Build.0 = Release Unicode|Win32
+ {AB494732-EF6D-44D0-BCF8-80FF04858D10}.Debug.ActiveCfg = Debug|Win32
+ {AB494732-EF6D-44D0-BCF8-80FF04858D10}.Debug.Build.0 = Debug|Win32
+ {AB494732-EF6D-44D0-BCF8-80FF04858D10}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {AB494732-EF6D-44D0-BCF8-80FF04858D10}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {AB494732-EF6D-44D0-BCF8-80FF04858D10}.Release.ActiveCfg = Release|Win32
+ {AB494732-EF6D-44D0-BCF8-80FF04858D10}.Release.Build.0 = Release|Win32
+ {AB494732-EF6D-44D0-BCF8-80FF04858D10}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {AB494732-EF6D-44D0-BCF8-80FF04858D10}.Release Unicode.Build.0 = Release Unicode|Win32
+ {AB494732-EF6D-44D0-BCF8-80FF04858D10}.ResourceDLL.ActiveCfg = Release Unicode|Win32
+ {AB494732-EF6D-44D0-BCF8-80FF04858D10}.ResourceDLL.Build.0 = Release Unicode|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/src/apps/mplayerc/mplayerc.suo b/src/apps/mplayerc/mplayerc.suo
new file mode 100644
index 000000000..a55bd7f7d
--- /dev/null
+++ b/src/apps/mplayerc/mplayerc.suo
Binary files differ
diff --git a/src/apps/mplayerc/mplayerc.vcproj b/src/apps/mplayerc/mplayerc.vcproj
new file mode 100644
index 000000000..8217fc79e
--- /dev/null
+++ b/src/apps/mplayerc/mplayerc.vcproj
@@ -0,0 +1,1927 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="mplayerc"
+ ProjectGUID="{CEAF0A23-A949-443E-BDA4-2F025DD774F6}"
+ SccProjectName=""
+ SccAuxPath=""
+ SccLocalPath=""
+ SccProvider=""
+ Keyword="MFCProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory=".\$(ConfigurationName)"
+ IntermediateDirectory=".\$(OutDir)"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ UseOfATL="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile="$(OutDir)\$(ProjectName).pch"
+ AssemblerListingLocation=".\$(OutDir)/"
+ ObjectFile=".\$(OutDir)/"
+ ProgramDataBaseFileName=".\$(OutDir)/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="Delayimp.lib detours.lib qtmlClient.lib wmstub.lib d3dx9.lib dxguid.lib Dsound.lib strmbaseRU.lib dsutilRU.lib subpicRU.lib subtitlesRU.lib asyncreaderRU.lib audioswitcherRU.lib avi2ac3filterRU.lib bufferfilterRU.lib cddareaderRU.lib cdxareaderRU.lib d2vsourceRU.lib decssfilterRU.lib flicsourceRU.lib dtsac3sourceRU.lib basesourceRU.lib wavdestRU.lib shoutcastsourceRU.lib streamdrivethruRU.lib vtsreaderRU.lib basesplitterRU.lib MatroskaSplitterRU.lib MatroskaMuxerRU.lib RealMediaSplitterRU.lib AviSplitterRU.lib Mpeg2DecFilterRU.lib MpaDecFilterRU.lib RoQSplitterRU.lib OggSplitterRU.lib NutSplitterRU.lib MpegSplitterRU.lib DiracSplitterRU.lib MpaSplitterRU.lib DSMSplitterRU.lib BaseMuxerRU.lib DSMMuxerRU.lib zlibR.lib subtitlesourceRU.lib strmiids.lib MP4SplitterRU.lib udpreaderRU.lib Psapi.lib"
+ OutputFile="$(OutDir)\$(ProjectName).exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ AdditionalLibraryDirectories="../../../lib;../../../lib/wm7;../../../lib/qt6;../../../lib/detours"
+ IgnoreDefaultLibraryNames="MSVCRT"
+ DelayLoadDLLs="d3d9.dll;msimg32.dll;gdiplus.dll"
+ ProgramDatabaseFile="$(OutDir)\$(ProjectName).pdb"
+ SubSystem="2"
+ SupportUnloadOfDelayLoadedDLL="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release_unicode/mplayerc.tlb"/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="..\..\..\bin\upx.exe --best &quot;$(TargetPath)&quot;"
+ ExcludedFromBuild="TRUE"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories=""/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory=".\$(ConfigurationName)"
+ IntermediateDirectory=".\$(OutDir)"
+ ConfigurationType="1"
+ UseOfMFC="2"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;pascal="
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile="$(OutDir)\$(ProjectName).pch"
+ AssemblerListingLocation=".\$(OutDir)/"
+ ObjectFile=".\$(OutDir)/"
+ ProgramDataBaseFileName=".\$(OutDir)/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="Delayimp.lib detours.lib qtmlClient.lib wmstub.lib d3dx9.lib Dsound.lib dxguid.lib strmbaseDU.lib dsutilDU.lib subpicDU.lib subtitlesDU.lib asyncreaderDU.lib audioswitcherDU.lib avi2ac3filterDU.lib bufferfilterDU.lib cddareaderDU.lib cdxareaderDU.lib d2vsourceDU.lib decssfilterDU.lib flicsourceDU.lib dtsac3sourceDU.lib basesourceDU.lib subtitlesourceDU.lib wavdestDU.lib shoutcastsourceDU.lib streamdrivethruDU.lib vtsreaderDU.lib basesplitterDU.lib MatroskaSplitterDU.lib MatroskaMuxerDU.lib RealMediaSplitterDU.lib AviSplitterDU.lib Mpeg2DecFilterDU.lib MpaDecFilterDU.lib RoQSplitterDU.lib OggSplitterDU.lib NutSplitterDU.lib MpegSplitterDU.lib DiracSplitterDU.lib MpaSplitterDU.lib DSMSplitterDU.lib BaseMuxerDU.lib DSMMuxerDU.lib zlibD.lib strmiids.lib MP4SplitterDU.lib udpreaderDU.lib Psapi.lib"
+ OutputFile="$(OutDir)\$(ProjectName).exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="TRUE"
+ AdditionalLibraryDirectories="../../../lib;../../../lib/wm7;../../../lib/qt6;../../../lib/detours"
+ IgnoreDefaultLibraryNames="MSVCRT;LIBCMT;MSVCR71D"
+ DelayLoadDLLs="d3d9.dll;msimg32.dll;gdiplus.dll"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)\$(ProjectName).pdb"
+ SubSystem="2"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName="$(OutDir)\$(ProjectName).tlb"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_AFXDLL;_DEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\$(ConfigurationName)"
+ IntermediateDirectory=".\$(OutDir)"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ FavorSizeOrSpeed="1"
+ OptimizeForProcessor="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile="$(OutDir)\$(ProjectName).pch"
+ AssemblerListingLocation=".\$(OutDir)/"
+ ObjectFile=".\$(OutDir)/"
+ ProgramDataBaseFileName=".\$(OutDir)/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="Delayimp.lib detours.lib qtmlClient.lib wmstub.lib d3dx9.lib Dsound.lib dxguid.lib strmbaseR.lib dsutilR.lib subpicR.lib subtitlesR.lib asyncreaderR.lib audioswitcherR.lib avi2ac3filterR.lib bufferfilterR.lib cddareaderR.lib cdxareaderR.lib d2vsourceR.lib decssfilterR.lib flicsourceR.lib dtsac3sourceR.lib basesourceR.lib wavdestR.lib shoutcastsourceR.lib streamdrivethruR.lib vtsreaderR.lib basesplitterR.lib MatroskaSplitterR.lib MatroskaMuxerR.lib RealMediaSplitterR.lib AviSplitterR.lib Mpeg2DecFilterR.lib MpaDecFilterR.lib RadGtSplitterR.lib RoQSplitterR.lib OggSplitterR.lib NutSplitterR.lib MpegSplitterR.lib DiracSplitterR.lib MpaSplitterR.lib DSMSplitterR.lib BaseMuxerR.lib DSMMuxerR.lib zlibR.lib subtitlesourceR.lib"
+ OutputFile="$(OutDir)\$(ProjectName).exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ AdditionalLibraryDirectories="../../../lib;../../../lib/wm7;../../../lib/qt6;../../../lib/detours"
+ IgnoreDefaultLibraryNames="MSVCRT"
+ DelayLoadDLLs="d3d9.dll;msimg32.dll;gdiplus.dll"
+ ProgramDatabaseFile="$(OutDir)\$(ProjectName).pdb"
+ SubSystem="2"
+ SupportUnloadOfDelayLoadedDLL="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/mplayerc.tlb"/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="..\..\..\bin\upx.exe --best &quot;$(TargetPath)&quot;"
+ ExcludedFromBuild="TRUE"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories=""/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\$(ConfigurationName)"
+ IntermediateDirectory=".\$(OutDir)"
+ ConfigurationType="1"
+ UseOfMFC="2"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile="$(OutDir)\$(ProjectName).pch"
+ AssemblerListingLocation=".\$(OutDir)/"
+ ObjectFile=".\$(OutDir)/"
+ ProgramDataBaseFileName=".\$(OutDir)/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="Delayimp.lib detours.lib qtmlClient.lib wmstub.lib d3dx9.lib Dsound.lib dxguid.lib strmbaseD.lib dsutilD.lib subpicD.lib subtitlesD.lib asyncreaderD.lib audioswitcherD.lib avi2ac3filterD.lib bufferfilterD.lib cddareaderD.lib cdxareaderD.lib d2vsourceD.lib decssfilterD.lib flicsourceD.lib dtsac3sourceD.lib basesourceD.lib subtitlesourceD.lib wavdestD.lib shoutcastsourceD.lib streamdrivethruD.lib vtsreaderD.lib basesplitterD.lib MatroskaSplitterD.lib MatroskaMuxerD.lib RealMediaSplitterD.lib AviSplitterD.lib Mpeg2DecFilterD.lib MpaDecFilterD.lib RadGtSplitterD.lib RoQSplitterD.lib OggSplitterD.lib NutSplitterD.lib MpegSplitterD.lib DiracSplitterD.lib MpaSplitterD.lib DSMSplitterD.lib BaseMuxerD.lib DSMMuxerD.lib zlibD.lib"
+ OutputFile="$(OutDir)\$(ProjectName).exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="TRUE"
+ AdditionalLibraryDirectories="../../../lib;../../../lib/wm7;../../../lib/qt6;../../../lib/detours"
+ IgnoreDefaultLibraryNames="MSVCRT;LIBCMT"
+ DelayLoadDLLs="d3d9.dll;msimg32.dll;gdiplus.dll"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)\$(ProjectName).pdb"
+ SubSystem="2"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName="$(OutDir)\$(ProjectName).tlb"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_AFXDLL;_DEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="ResourceDLL|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ ResourceOnlyDLL="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+ <File
+ RelativePath=".\AuthDlg.cpp">
+ </File>
+ <File
+ RelativePath="BaseGraph.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\ChildView.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="ComPropertyPage.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="ComPropertySheet.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\ConvertChapDlg.cpp">
+ </File>
+ <File
+ RelativePath=".\ConvertDlg.cpp">
+ </File>
+ <File
+ RelativePath=".\ConvertPropsDlg.cpp">
+ </File>
+ <File
+ RelativePath=".\ConvertResDlg.cpp">
+ </File>
+ <File
+ RelativePath="CShockwaveFlash.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\D3DFont.cpp">
+ </File>
+ <File
+ RelativePath=".\DeinterlacerFilter.cpp">
+ </File>
+ <File
+ RelativePath="DX7AllocatorPresenter.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="DX9AllocatorPresenter.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\FakeFilterMapper2.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="FavoriteAddDlg.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="FavoriteOrganizeDlg.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\FGFilter.cpp">
+ </File>
+ <File
+ RelativePath=".\FGManager.cpp">
+ </File>
+ <File
+ RelativePath="FileDropTarget.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="FloatEdit.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\FullscreenWnd.cpp">
+ </File>
+ <File
+ RelativePath="GoToDlg.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\filters\InternalPropertyPage.cpp">
+ </File>
+ <File
+ RelativePath=".\IPinHook.cpp">
+ </File>
+ <File
+ RelativePath=".\ISDb.cpp">
+ </File>
+ <File
+ RelativePath=".\jpeg.cpp">
+ </File>
+ <File
+ RelativePath="KeyProvider.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\LineNumberEdit.cpp">
+ </File>
+ <File
+ RelativePath=".\MacrovisionKicker.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\MainFrm.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="MediaFormats.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="MediaTypesDlg.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\mplayerc.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\mplayerc.rc">
+ </File>
+ <File
+ RelativePath="OpenCapDeviceDlg.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="OpenDlg.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\OpenFileDlg.cpp">
+ </File>
+ <File
+ RelativePath="..\..\filters\PinInfoWnd.cpp">
+ </File>
+ <File
+ RelativePath=".\PixelShaderCompiler.cpp">
+ </File>
+ <File
+ RelativePath="PlayerCaptureBar.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerCaptureDialog.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerInfoBar.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerListCtrl.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerPlaylistBar.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerSeekBar.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PlayerShaderEditorBar.cpp">
+ </File>
+ <File
+ RelativePath="PlayerStatusBar.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerSubresyncBar.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerToolBar.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Playlist.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PnSPresetsDlg.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageAccelTbl.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageAudioSwitcher.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageBase.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PPageCasimir.cpp">
+ </File>
+ <File
+ RelativePath="PPageDVD.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PPageExternalFilters.cpp">
+ </File>
+ <File
+ RelativePath="PPageFileInfoClip.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageFileInfoDetails.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PPageFileInfoRes.cpp">
+ </File>
+ <File
+ RelativePath="PPageFileInfoSheet.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageFormats.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PPageInternalFilters.cpp">
+ </File>
+ <File
+ RelativePath=".\PPageLogo.cpp">
+ </File>
+ <File
+ RelativePath=".\PPageOutput.cpp">
+ </File>
+ <File
+ RelativePath="PPagePlayback.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPagePlayer.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageSheet.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PPageSubDB.cpp">
+ </File>
+ <File
+ RelativePath="PPageSubStyle.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageSubtitles.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageTweaks.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PPageWebServer.cpp">
+ </File>
+ <File
+ RelativePath="QuicktimeGraph.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="RealMediaGraph.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="RealMediaWindowlessSite.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="RegFilterChooserDlg.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="SaveDlg.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="SaveTextFileDialog.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\SaveThumbnailsDialog.cpp">
+ </File>
+ <File
+ RelativePath="SelectMediaType.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\ShaderAutoCompleteDlg.cpp">
+ </File>
+ <File
+ RelativePath=".\ShaderCombineDlg.cpp">
+ </File>
+ <File
+ RelativePath=".\ShaderEditorDlg.cpp">
+ </File>
+ <File
+ RelativePath="ShockwaveGraph.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="StaticLink.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="StatusLabel.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\StdAfx.cpp">
+ <FileConfiguration
+ Name="Release Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\SubtitleDlDlg.cpp">
+ </File>
+ <File
+ RelativePath="TextPassThruFilter.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\VMROSD.cpp">
+ </File>
+ <File
+ RelativePath="VolumeCtrl.cpp">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\WebClientSocket.cpp">
+ </File>
+ <File
+ RelativePath=".\WebServer.cpp">
+ </File>
+ <File
+ RelativePath=".\WebServerSocket.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl">
+ <File
+ RelativePath=".\AuthDlg.h">
+ </File>
+ <File
+ RelativePath="BaseGraph.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\ChildView.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="ComPropertyPage.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="ComPropertySheet.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\ConvertChapDlg.h">
+ </File>
+ <File
+ RelativePath=".\ConvertDlg.h">
+ </File>
+ <File
+ RelativePath=".\ConvertPropsDlg.h">
+ </File>
+ <File
+ RelativePath=".\ConvertResDlg.h">
+ </File>
+ <File
+ RelativePath="CShockwaveFlash.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\D3DFont.h">
+ </File>
+ <File
+ RelativePath=".\DeinterlacerFilter.h">
+ </File>
+ <File
+ RelativePath="DX7AllocatorPresenter.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="DX9AllocatorPresenter.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\FakeFilterMapper2.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="FavoriteAddDlg.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="FavoriteOrganizeDlg.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\FGFilter.h">
+ </File>
+ <File
+ RelativePath=".\FGManager.h">
+ </File>
+ <File
+ RelativePath="FileDropTarget.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="FloatEdit.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\FullscreenWnd.h">
+ </File>
+ <File
+ RelativePath="GoToDlg.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\IGraphBuilder2.h">
+ </File>
+ <File
+ RelativePath=".\IPinHook.h">
+ </File>
+ <File
+ RelativePath="IQTVideoSurface.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\ISDb.h">
+ </File>
+ <File
+ RelativePath=".\jpeg.h">
+ </File>
+ <File
+ RelativePath=".\jpeg_tables.h">
+ </File>
+ <File
+ RelativePath="KeyProvider.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\LineNumberEdit.h">
+ </File>
+ <File
+ RelativePath=".\MacrovisionKicker.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\MainFrm.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="MediaFormats.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="MediaTypesDlg.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\mplayerc.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="OpenCapDeviceDlg.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="OpenDlg.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\OpenFileDlg.h">
+ </File>
+ <File
+ RelativePath=".\PixelShaderCompiler.h">
+ </File>
+ <File
+ RelativePath="PlayerCaptureBar.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerCaptureDialog.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerInfoBar.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerListCtrl.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerPlaylistBar.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerSeekBar.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PlayerShaderEditorBar.h">
+ </File>
+ <File
+ RelativePath="PlayerStatusBar.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerSubresyncBar.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PlayerToolBar.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="Playlist.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PnSPresetsDlg.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageAccelTbl.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageAudioSwitcher.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageBase.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PPageCasimir.h">
+ </File>
+ <File
+ RelativePath="PPageDVD.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PPageExternalFilters.h">
+ </File>
+ <File
+ RelativePath="PPageFileInfoClip.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageFileInfoDetails.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PPageFileInfoRes.h">
+ </File>
+ <File
+ RelativePath="PPageFileInfoSheet.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageFormats.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PPageInternalFilters.h">
+ </File>
+ <File
+ RelativePath=".\PPageLogo.h">
+ </File>
+ <File
+ RelativePath=".\PPageOutput.h">
+ </File>
+ <File
+ RelativePath="PPagePlayback.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPagePlayer.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageSheet.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PPageSubDB.h">
+ </File>
+ <File
+ RelativePath="PPageSubStyle.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageSubtitles.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="PPageTweaks.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\PPageWebServer.h">
+ </File>
+ <File
+ RelativePath="QuicktimeGraph.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="RealMediaGraph.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="RealMediaWindowlessSite.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="RegFilterChooserDlg.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Resource.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="SaveDlg.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="SaveTextFileDialog.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\SaveThumbnailsDialog.h">
+ </File>
+ <File
+ RelativePath="SelectMediaType.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\ShaderAutoCompleteDlg.h">
+ </File>
+ <File
+ RelativePath=".\ShaderCombineDlg.h">
+ </File>
+ <File
+ RelativePath=".\ShaderEditorDlg.h">
+ </File>
+ <File
+ RelativePath="ShockwaveGraph.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="StaticLink.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="StatusLabel.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\StdAfx.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\SubtitleDlDlg.h">
+ </File>
+ <File
+ RelativePath="TextPassThruFilter.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\VMROSD.h">
+ </File>
+ <File
+ RelativePath="VolumeCtrl.h">
+ <FileConfiguration
+ Name="ResourceDLL|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\WebClientSocket.h">
+ </File>
+ <File
+ RelativePath=".\WebServer.h">
+ </File>
+ <File
+ RelativePath=".\WebServerSocket.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+ <File
+ RelativePath="res\ani.avi">
+ </File>
+ <File
+ RelativePath=".\res\authhdrpic.bmp">
+ </File>
+ <File
+ RelativePath="res\icon.ico">
+ </File>
+ <File
+ RelativePath="res\Icon_114.ico">
+ </File>
+ <File
+ RelativePath="res\Icon_116.ico">
+ </File>
+ <File
+ RelativePath="res\Icon_41.ico">
+ </File>
+ <File
+ RelativePath=".\res\logo.0.bmp">
+ </File>
+ <File
+ RelativePath=".\res\logo.1.bmp">
+ </File>
+ <File
+ RelativePath=".\res\logo.2.bmp">
+ </File>
+ <File
+ RelativePath=".\res\logo.3.bmp">
+ </File>
+ <File
+ RelativePath=".\res\logo.4.bmp">
+ </File>
+ <File
+ RelativePath=".\res\logo.5.bmp">
+ </File>
+ <File
+ RelativePath=".\res\logo.6.bmp">
+ </File>
+ <File
+ RelativePath=".\res\logo.7.bmp">
+ </File>
+ <File
+ RelativePath="res\mono.bmp">
+ </File>
+ <File
+ RelativePath="res\mplayerc.manifest">
+ </File>
+ <File
+ RelativePath="res\multi.ico">
+ </File>
+ <File
+ RelativePath="res\noaudio.bmp">
+ </File>
+ <File
+ RelativePath="res\onoff.bmp">
+ </File>
+ <File
+ RelativePath="res\single.ico">
+ </File>
+ <File
+ RelativePath="res\stereo.bmp">
+ </File>
+ <File
+ RelativePath=".\res\streamtypes.bmp">
+ </File>
+ <File
+ RelativePath="res\toolbar1.bmp">
+ </File>
+ <Filter
+ Name="web"
+ Filter="">
+ <File
+ RelativePath=".\res\web\1pix.gif">
+ </File>
+ <File
+ RelativePath=".\res\web\404.html">
+ </File>
+ <File
+ RelativePath=".\res\web\bottomside.PNG">
+ </File>
+ <File
+ RelativePath=".\res\web\browser.html">
+ </File>
+ <File
+ RelativePath=".\res\web\controlback.png">
+ </File>
+ <File
+ RelativePath=".\res\web\controlbuttondecrate.png">
+ </File>
+ <File
+ RelativePath=".\res\web\controlbuttonincrate.png">
+ </File>
+ <File
+ RelativePath=".\res\web\controlbuttonpause.png">
+ </File>
+ <File
+ RelativePath=".\res\web\controlbuttonplay.png">
+ </File>
+ <File
+ RelativePath=".\res\web\controlbuttonskipback.png">
+ </File>
+ <File
+ RelativePath=".\res\web\controlbuttonskipforward.png">
+ </File>
+ <File
+ RelativePath=".\res\web\controlbuttonstep.png">
+ </File>
+ <File
+ RelativePath=".\res\web\controlbuttonstop.png">
+ </File>
+ <File
+ RelativePath=".\res\web\controls.html">
+ </File>
+ <File
+ RelativePath=".\res\web\controlvolumebar.png">
+ </File>
+ <File
+ RelativePath=".\res\web\controlvolumegrip.png">
+ </File>
+ <File
+ RelativePath=".\res\web\controlvolumeoff.png">
+ </File>
+ <File
+ RelativePath=".\res\web\controlvolumeon.png">
+ </File>
+ <File
+ RelativePath=".\res\web\default.css">
+ </File>
+ <File
+ RelativePath=".\res\web\headerback.png">
+ </File>
+ <File
+ RelativePath=".\res\web\headerclose.png">
+ </File>
+ <File
+ RelativePath=".\res\web\headericon.png">
+ </File>
+ <File
+ RelativePath=".\res\web\index.html">
+ </File>
+ <File
+ RelativePath=".\res\web\leftbottomside.png">
+ </File>
+ <File
+ RelativePath=".\res\web\leftside.png">
+ </File>
+ <File
+ RelativePath=".\res\web\logo.png">
+ </File>
+ <File
+ RelativePath=".\res\web\player.html">
+ </File>
+ <File
+ RelativePath=".\res\web\rightbottomside.png">
+ </File>
+ <File
+ RelativePath=".\res\web\rightside.png">
+ </File>
+ <File
+ RelativePath=".\res\web\seekbargrip.png">
+ </File>
+ <File
+ RelativePath=".\res\web\seekbarleft.png">
+ </File>
+ <File
+ RelativePath=".\res\web\seekbarmid.png">
+ </File>
+ <File
+ RelativePath=".\res\web\seekbarright.png">
+ </File>
+ <File
+ RelativePath=".\res\web\sliderback.gif">
+ </File>
+ <File
+ RelativePath=".\res\web\sliderbar.gif">
+ </File>
+ <File
+ RelativePath=".\res\web\slidergrip.gif">
+ </File>
+ <File
+ RelativePath=".\res\web\vbg.gif">
+ </File>
+ <File
+ RelativePath=".\res\web\vbs.GIF">
+ </File>
+ </Filter>
+ <Filter
+ Name="shaders"
+ Filter="">
+ <File
+ RelativePath=".\res\shaders\contour.psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\deinterlace (blend).psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\EdgeSharpen.psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\emboss.psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\empty.psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\grayscale.psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\invert.psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\letterbox.psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\procamp.psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\resizer.psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\sharpen.psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\SharpenComplex.psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\sphere.psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\spotlight.psh">
+ </File>
+ <File
+ RelativePath=".\res\shaders\wave.psh">
+ </File>
+ </Filter>
+ </Filter>
+ <File
+ RelativePath=".\History.txt">
+ </File>
+ </Files>
+ <Globals>
+ <Global
+ Name="DevPartner_IsInstrumented"
+ Value="1"/>
+ <Global
+ Name="RESOURCE_FILE"
+ Value="mplayerc.rc"/>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/apps/mplayerc/mplayerc.vcproj.vspscc b/src/apps/mplayerc/mplayerc.vcproj.vspscc
new file mode 100644
index 000000000..69ee94fb8
--- /dev/null
+++ b/src/apps/mplayerc/mplayerc.vcproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = "relative:apps\\mplayerc"
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
+}
diff --git a/src/apps/mplayerc/mplayerc.vssscc b/src/apps/mplayerc/mplayerc.vssscc
new file mode 100644
index 000000000..69ee94fb8
--- /dev/null
+++ b/src/apps/mplayerc/mplayerc.vssscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = "relative:apps\\mplayerc"
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
+}
diff --git a/src/apps/mplayerc/res/Icon_114.ico b/src/apps/mplayerc/res/Icon_114.ico
new file mode 100644
index 000000000..31c5175ad
--- /dev/null
+++ b/src/apps/mplayerc/res/Icon_114.ico
Binary files differ
diff --git a/src/apps/mplayerc/res/Icon_116.ico b/src/apps/mplayerc/res/Icon_116.ico
new file mode 100644
index 000000000..9c10e4bdd
--- /dev/null
+++ b/src/apps/mplayerc/res/Icon_116.ico
Binary files differ
diff --git a/src/apps/mplayerc/res/Icon_41.ico b/src/apps/mplayerc/res/Icon_41.ico
new file mode 100644
index 000000000..ac42fb931
--- /dev/null
+++ b/src/apps/mplayerc/res/Icon_41.ico
Binary files differ
diff --git a/src/apps/mplayerc/res/ani.avi b/src/apps/mplayerc/res/ani.avi
new file mode 100644
index 000000000..df6050bde
--- /dev/null
+++ b/src/apps/mplayerc/res/ani.avi
Binary files differ
diff --git a/src/apps/mplayerc/res/authhdrpic.bmp b/src/apps/mplayerc/res/authhdrpic.bmp
new file mode 100644
index 000000000..69deb8350
--- /dev/null
+++ b/src/apps/mplayerc/res/authhdrpic.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/icon.ico b/src/apps/mplayerc/res/icon.ico
new file mode 100644
index 000000000..3178cc5a6
--- /dev/null
+++ b/src/apps/mplayerc/res/icon.ico
Binary files differ
diff --git a/src/apps/mplayerc/res/logo.0.bmp b/src/apps/mplayerc/res/logo.0.bmp
new file mode 100644
index 000000000..978a9186b
--- /dev/null
+++ b/src/apps/mplayerc/res/logo.0.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/logo.1.bmp b/src/apps/mplayerc/res/logo.1.bmp
new file mode 100644
index 000000000..3efad7a94
--- /dev/null
+++ b/src/apps/mplayerc/res/logo.1.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/logo.2.bmp b/src/apps/mplayerc/res/logo.2.bmp
new file mode 100644
index 000000000..70ec7af39
--- /dev/null
+++ b/src/apps/mplayerc/res/logo.2.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/logo.3.bmp b/src/apps/mplayerc/res/logo.3.bmp
new file mode 100644
index 000000000..b30c1c198
--- /dev/null
+++ b/src/apps/mplayerc/res/logo.3.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/logo.4.bmp b/src/apps/mplayerc/res/logo.4.bmp
new file mode 100644
index 000000000..e1d73700b
--- /dev/null
+++ b/src/apps/mplayerc/res/logo.4.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/logo.5.bmp b/src/apps/mplayerc/res/logo.5.bmp
new file mode 100644
index 000000000..a1000289f
--- /dev/null
+++ b/src/apps/mplayerc/res/logo.5.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/logo.6.bmp b/src/apps/mplayerc/res/logo.6.bmp
new file mode 100644
index 000000000..26c357f3e
--- /dev/null
+++ b/src/apps/mplayerc/res/logo.6.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/logo.7.bmp b/src/apps/mplayerc/res/logo.7.bmp
new file mode 100644
index 000000000..a750ce2a1
--- /dev/null
+++ b/src/apps/mplayerc/res/logo.7.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/mono.bmp b/src/apps/mplayerc/res/mono.bmp
new file mode 100644
index 000000000..7c9eeb012
--- /dev/null
+++ b/src/apps/mplayerc/res/mono.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/mpc.png b/src/apps/mplayerc/res/mpc.png
new file mode 100644
index 000000000..61230b249
--- /dev/null
+++ b/src/apps/mplayerc/res/mpc.png
Binary files differ
diff --git a/src/apps/mplayerc/res/mplayerc.manifest b/src/apps/mplayerc/res/mplayerc.manifest
new file mode 100644
index 000000000..6e21a7389
--- /dev/null
+++ b/src/apps/mplayerc/res/mplayerc.manifest
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<!--assemblyIdentity
+ version="6.4.0.1"
+ processorArchitecture="X86"
+ name="Gabest.VobSub.MediaPlayerClassic"
+ type="win32"
+/-->
+<description>MediaPlayerClassic</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="X86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+</assembly>
+
diff --git a/src/apps/mplayerc/res/multi.ico b/src/apps/mplayerc/res/multi.ico
new file mode 100644
index 000000000..96584e103
--- /dev/null
+++ b/src/apps/mplayerc/res/multi.ico
Binary files differ
diff --git a/src/apps/mplayerc/res/noaudio.bmp b/src/apps/mplayerc/res/noaudio.bmp
new file mode 100644
index 000000000..f3ea250ec
--- /dev/null
+++ b/src/apps/mplayerc/res/noaudio.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/onoff.bmp b/src/apps/mplayerc/res/onoff.bmp
new file mode 100644
index 000000000..b40c5c9f9
--- /dev/null
+++ b/src/apps/mplayerc/res/onoff.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/shaders/EdgeSharpen.psh b/src/apps/mplayerc/res/shaders/EdgeSharpen.psh
new file mode 100644
index 000000000..6b6c4916b
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/EdgeSharpen.psh
@@ -0,0 +1,63 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define width (p0[0])
+#define height (p0[1])
+#define counter (p0[2])
+#define clock (p0[3])
+#define one_over_width (p1[0])
+#define one_over_height (p1[1])
+
+#define PI acos(-1)
+
+#define NbPixel 1
+
+#define Edge_threshold 0.2
+
+#define Sharpen_val0 2.0
+#define Sharpen_val1 0.125
+
+float4 main(float2 tex : TEXCOORD0) : COLOR
+{
+// taille de NbPixel pixels
+float dx = NbPixel/width;
+float dy = NbPixel/height;
+float4 Res = 0;
+
+// Détection de contour par Prewitt
+ // récuppération des 9 points
+ // [ 1, 2, 3 ]
+ // [ 4, 0, 5 ]
+ // [ 6, 7, 8 ]
+ float4 c0 = tex2D(s0, tex);
+ float4 c1 = tex2D(s0, tex + float2(-dx,-dy));
+ float4 c2 = tex2D(s0, tex + float2(0,-dy));
+ float4 c3 = tex2D(s0, tex + float2(dx,-dy));
+ float4 c4 = tex2D(s0, tex + float2(-dx,0));
+ float4 c5 = tex2D(s0, tex + float2(dx,0));
+ float4 c6 = tex2D(s0, tex + float2(-dx,dy));
+ float4 c7 = tex2D(s0, tex + float2(0,dy));
+ float4 c8 = tex2D(s0, tex + float2(dx,dy));
+
+ // Calcul des 3 vecteurs dérivé (hor,vert, diag1, diag2)
+ float4 delta1 = (c6+c4+c1-c3-c5-c8);
+ float4 delta2 = (c4+c1+c2-c5-c8-c7);
+ float4 delta3 = (c1+c2+c3-c8-c7-c6);
+ float4 delta4 = (c2+c3+c5-c7-c6-c4);
+
+ // calcul du Prewitt
+ float value = length(abs(delta1) + abs(delta2) + abs(delta3) + abs(delta4))/6;
+
+// Si c'est un contour (vector lenght > Edge_threshold) => filtre de sharpen
+ if(value > Edge_threshold )
+ {
+ Res = c0 * Sharpen_val0 - (c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 ) * Sharpen_val1 ;
+ // Pour voir les contour en rouge ...
+ //Res = float4( 1.0, 0.0, 0.0, 0.0 );
+
+ return Res;
+ }
+ else
+ return c0;
+} \ No newline at end of file
diff --git a/src/apps/mplayerc/res/shaders/SharpenComplex.psh b/src/apps/mplayerc/res/shaders/SharpenComplex.psh
new file mode 100644
index 000000000..5b1179820
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/SharpenComplex.psh
@@ -0,0 +1,82 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define width (p0[0])
+#define height (p0[1])
+
+#define dx (p1[0])
+#define dy (p1[1])
+
+float4 main( float2 tex : TEXCOORD0 ) : COLOR
+{
+// definition des pixels : original, flouté, corigé, final
+float4 ori;
+float4 flou;
+float4 cori;
+float4 final;
+
+////////////////////////////////////////////////////
+// récuppération de la matrice de 9 points
+// [ 1, 2 , 3 ]
+// [ 4,ori, 5 ]
+// [ 6, 7 , 8 ]
+
+ ori = tex2D(s0, tex);
+ float4 c1 = tex2D(s0, tex + float2(-dx,-dy));
+ float4 c2 = tex2D(s0, tex + float2(0,-dy));
+ float4 c3 = tex2D(s0, tex + float2(dx,-dy));
+ float4 c4 = tex2D(s0, tex + float2(-dx,0));
+ float4 c5 = tex2D(s0, tex + float2(dx,0));
+ float4 c6 = tex2D(s0, tex + float2(-dx,dy));
+ float4 c7 = tex2D(s0, tex + float2(0,dy));
+ float4 c8 = tex2D(s0, tex + float2(dx,dy));
+
+////////////////////////////////////////////////////
+// calcul image floue (filtre gaussien)
+ // pour normaliser les valeurs, il faut diviser par la somme des coef
+ // 1/(1+2+1+2+4+2+1+2+1) = 1/ 16 = .0625
+ flou = (c1+c3+c6+c8 + 2*(c2+c4+c5+c7)+ 4*ori)*0.0625;
+
+// soustraction de l'image flou à l'image originale
+ cori = 2*ori - flou;
+
+////////////////////////////////////////////////////
+// détection des contours
+float delta1;
+float delta2;
+float value;
+
+// par filtre de sobel
+ // Gradient horizontal
+ // [ -1, 0 ,1 ]
+ // [ -2, 0, 2 ]
+ // [ -1, 0 ,1 ]
+ delta1 = (c3 + 2*c5 + c8)-(c1 + 2*c4 + c6);
+
+ // Gradient vertical
+ // [ -1,- 2,-1 ]
+ // [ 0, 0, 0 ]
+ // [ 1, 2, 1 ]
+ delta2 = (c6 + 2*c7 + c8)-(c1 + 2*c2 + c3);
+
+ // calcul
+ value = sqrt( mul(delta1,delta1) + mul(delta2,delta2) ) ;
+
+ if( value >.3 )
+ {
+////////////////////////////////////////////////////
+// si contour, sharpen
+#define Sharpen_val0 2.0
+#define Sharpen_val1 0.125
+ final = ori*2 - (c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 ) * 0.125 ;
+// final= float4(1,0,0,0);
+ return final;
+ }
+ else
+ {
+////////////////////////////////////////////////////
+// sinon, image corrigée
+ return cori;
+ }
+} \ No newline at end of file
diff --git a/src/apps/mplayerc/res/shaders/contour.psh b/src/apps/mplayerc/res/shaders/contour.psh
new file mode 100644
index 000000000..7b0480d50
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/contour.psh
@@ -0,0 +1,30 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define width (p0[0])
+#define height (p0[1])
+#define counter (p0[2])
+#define clock (p0[3])
+#define one_over_width (p1[0])
+#define one_over_height (p1[1])
+
+#define PI acos(-1)
+
+float4 main(float2 tex : TEXCOORD0) : COLOR
+{
+ float dx = 4/width;
+ float dy = 4/height;
+
+ float4 c2 = tex2D(s0, tex + float2(0,-dy));
+ float4 c4 = tex2D(s0, tex + float2(-dx,0));
+ float4 c5 = tex2D(s0, tex + float2(0,0));
+ float4 c6 = tex2D(s0, tex + float2(dx,0));
+ float4 c8 = tex2D(s0, tex + float2(0,dy));
+
+ float4 c0 = (-c2-c4+c5*4-c6-c8);
+ if(length(c0) < 1.0) c0 = float4(0,0,0,0);
+ else c0 = float4(1,1,1,0);
+
+ return c0;
+}
diff --git a/src/apps/mplayerc/res/shaders/deinterlace (blend).psh b/src/apps/mplayerc/res/shaders/deinterlace (blend).psh
new file mode 100644
index 000000000..2dc2606e5
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/deinterlace (blend).psh
@@ -0,0 +1,24 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define width (p0[0])
+#define height (p0[1])
+#define counter (p0[2])
+#define clock (p0[3])
+#define one_over_width (p1[0])
+#define one_over_height (p1[1])
+
+#define PI acos(-1)
+
+float4 main(float2 tex : TEXCOORD0) : COLOR
+{
+ float4 c0 = tex2D(s0, tex);
+
+ float2 h = float2(0, 1/height);
+ float4 c1 = tex2D(s0, tex-h);
+ float4 c2 = tex2D(s0, tex+h);
+ c0 = (c0*2+c1+c2)/4;
+
+ return c0;
+} \ No newline at end of file
diff --git a/src/apps/mplayerc/res/shaders/emboss.psh b/src/apps/mplayerc/res/shaders/emboss.psh
new file mode 100644
index 000000000..4dc2bba00
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/emboss.psh
@@ -0,0 +1,30 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define width (p0[0])
+#define height (p0[1])
+#define counter (p0[2])
+#define clock (p0[3])
+#define one_over_width (p1[0])
+#define one_over_height (p1[1])
+
+#define PI acos(-1)
+
+float4 main(float2 tex : TEXCOORD0) : COLOR
+{
+ float dx = 1/width;
+ float dy = 1/height;
+
+ float4 c1 = tex2D(s0, tex + float2(-dx,-dy));
+ float4 c2 = tex2D(s0, tex + float2(0,-dy));
+ float4 c4 = tex2D(s0, tex + float2(-dx,0));
+ float4 c6 = tex2D(s0, tex + float2(dx,0));
+ float4 c8 = tex2D(s0, tex + float2(0,dy));
+ float4 c9 = tex2D(s0, tex + float2(dx,dy));
+
+ float4 c0 = (-c1-c2-c4+c6+c8+c9);
+ c0 = (c0.r+c0.g+c0.b)/3 + 0.5;
+
+ return c0;
+}
diff --git a/src/apps/mplayerc/res/shaders/empty.psh b/src/apps/mplayerc/res/shaders/empty.psh
new file mode 100644
index 000000000..3d0ab987a
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/empty.psh
@@ -0,0 +1,19 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define width (p0[0])
+#define height (p0[1])
+#define counter (p0[2])
+#define clock (p0[3])
+#define one_over_width (p1[0])
+#define one_over_height (p1[1])
+
+#define PI acos(-1)
+
+float4 main(float2 tex : TEXCOORD0) : COLOR
+{
+ float4 c0 = tex2D(s0, tex);
+
+ return c0;
+}
diff --git a/src/apps/mplayerc/res/shaders/grayscale.psh b/src/apps/mplayerc/res/shaders/grayscale.psh
new file mode 100644
index 000000000..d57c94201
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/grayscale.psh
@@ -0,0 +1,19 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define width (p0[0])
+#define height (p0[1])
+#define counter (p0[2])
+#define clock (p0[3])
+#define one_over_width (p1[0])
+#define one_over_height (p1[1])
+
+#define PI acos(-1)
+
+float4 main(float2 tex : TEXCOORD0) : COLOR
+{
+ float c0 = dot(tex2D(s0, tex), float4(0.299, 0.587, 0.114, 0));
+
+ return c0;
+}
diff --git a/src/apps/mplayerc/res/shaders/invert.psh b/src/apps/mplayerc/res/shaders/invert.psh
new file mode 100644
index 000000000..4d61115c3
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/invert.psh
@@ -0,0 +1,19 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define width (p0[0])
+#define height (p0[1])
+#define counter (p0[2])
+#define clock (p0[3])
+#define one_over_width (p1[0])
+#define one_over_height (p1[1])
+
+#define PI acos(-1)
+
+float4 main(float2 tex : TEXCOORD0) : COLOR
+{
+ float4 c0 = float4(1, 1, 1, 1) - tex2D(s0, tex);
+
+ return c0;
+}
diff --git a/src/apps/mplayerc/res/shaders/letterbox.psh b/src/apps/mplayerc/res/shaders/letterbox.psh
new file mode 100644
index 000000000..c3a17297b
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/letterbox.psh
@@ -0,0 +1,25 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define width (p0[0])
+#define height (p0[1])
+#define counter (p0[2])
+#define clock (p0[3])
+#define one_over_width (p1[0])
+#define one_over_height (p1[1])
+
+#define PI acos(-1)
+
+float4 main(float2 tex : TEXCOORD0) : COLOR
+{
+ float4 c0 = 0;
+
+ float2 ar = float2(16, 9);
+ float h = (1 - width/height * ar.y/ar.x) / 2;
+
+ if(tex.y >= h && tex.y <= 1-h)
+ c0 = tex2D(s0, tex);
+
+ return c0;
+} \ No newline at end of file
diff --git a/src/apps/mplayerc/res/shaders/procamp.psh b/src/apps/mplayerc/res/shaders/procamp.psh
new file mode 100644
index 000000000..ec331d6bd
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/procamp.psh
@@ -0,0 +1,61 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define width (p0[0])
+#define height (p0[1])
+#define counter (p0[2])
+#define clock (p0[3])
+#define one_over_width (p1[0])
+#define one_over_height (p1[1])
+
+#define PI acos(-1)
+
+static float4x4 r2y =
+{
+ 0.299, 0.587, 0.114, 0,
+ -0.147, -0.289, 0.437, 0,
+ 0.615, -0.515, -0.100, 0,
+ 0, 0, 0, 0
+};
+
+static float4x4 y2r =
+{
+ 1.0, 0.0, 1.140, 0,
+ 1.0, -0.394, -0.581, 0,
+ 1.0, 2.028, 0.0, 0,
+ 0, 0, 0, 0
+};
+
+#define ymin (16.0/255)
+#define ymax (235.0/255)
+
+// Brightness: -1.0 to 1.0, default 0.0
+// Contrast: 0.0 to 10.0, default 1.0
+// Hue: -180.0 to +180.0, default 0.0
+// Saturation: 0.0 to 10.0, default 1.0
+
+#define Brightness 0.0
+#define Contrast 1.0
+#define Hue 0.0
+#define Saturation 1.0
+
+// tv -> pc scale
+// #define Brightness (-ymin)
+// #define Contrast (1.0/(ymax-ymin))
+
+static float2x2 HueMatrix =
+{
+ cos(Hue * PI / 180), sin(Hue * PI / 180),
+ -sin(Hue * PI / 180), cos(Hue * PI / 180)
+};
+
+float4 main(float2 tex : TEXCOORD0) : COLOR
+{
+ float4 c0 = tex2D(s0, tex);
+ c0 = mul(r2y, c0);
+ c0.r = Contrast * (c0.r - ymin) + ymin + Brightness;
+ c0.gb = mul(HueMatrix, c0.gb) * Saturation;
+ c0 = mul(y2r, c0);
+ return c0;
+}
diff --git a/src/apps/mplayerc/res/shaders/resizer.psh b/src/apps/mplayerc/res/shaders/resizer.psh
new file mode 100644
index 000000000..1c31f7653
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/resizer.psh
@@ -0,0 +1,105 @@
+
+sampler s0 : register(s0);
+sampler s1 : register(s1);
+sampler s2 : register(s2);
+sampler s3 : register(s3);
+sampler s4 : register(s4);
+
+float4 p0 : register(c0);
+float2 dxdy : register(c1);
+float2 dx : register(c2);
+float2 dy : register(c3);
+
+#define A _The_Value_Of_A_Is_Set_Here_
+
+// none of the resizers here can be used for 1:1 mapping!
+// tex * size won't be 0, 1, 2, 3, .. as you might expect, but something like 0, 0.999, 2.001, 2.999, ...
+// this means when the fractional part becomes 0.999 we will be interpolating with the wrong value!!!
+
+struct PS_INPUT
+{
+ float2 t0 : TEXCOORD0;
+ float2 t1 : TEXCOORD1;
+ float2 t2 : TEXCOORD2;
+ float2 t3 : TEXCOORD3;
+ float2 t4 : TEXCOORD4;
+};
+
+float4 main_bilinear(PS_INPUT input) : COLOR
+{
+ float2 dd = frac(input.t4);
+
+ float4 c = lerp(
+ lerp(tex2D(s0, input.t0), tex2D(s1, input.t1), dd.x),
+ lerp(tex2D(s2, input.t2), tex2D(s3, input.t3), dd.x),
+ dd.y);
+
+ return c;
+}
+
+static float4x4 tco =
+{
+ 0, A, -2*A, A,
+ 1, 0, -A-3, A+2,
+ 0, -A, 2*A+3, -A-2,
+ 0, 0, A, -A
+};
+
+float4 taps(float t)
+{
+ return mul(tco, float4(1, t, t*t, t*t*t));
+}
+
+float4 SampleX(float4 tx, float2 t0)
+{
+ return
+ mul(tx,
+ float4x4(
+ tex2D(s0, t0 - dx),
+ tex2D(s0, t0),
+ tex2D(s0, t0 + dx),
+ tex2D(s0, t0 + dx + dx)
+ )
+ );
+}
+
+float4 SampleY(float4 tx, float4 ty, float2 t0)
+{
+ return
+ mul(ty,
+ float4x4(
+ SampleX(tx, t0 - dy),
+ SampleX(tx, t0),
+ SampleX(tx, t0 + dy),
+ SampleX(tx, t0 + dy + dy)
+ )
+ );
+}
+
+float4 main_bicubic1pass(PS_INPUT input) : COLOR
+{
+ float2 dd = frac(input.t1);
+ return SampleY(taps(dd.x), taps(dd.y), input.t0);
+ // return SampleY(tex1D(s1, dd.x), tex1D(s1, dd.y), input.t0);
+}
+
+float4 Sample(float4 t, PS_INPUT input)
+{
+ return
+ mul(t,
+ float4x4(
+ tex2D(s0, input.t0),
+ tex2D(s1, input.t1),
+ tex2D(s2, input.t2),
+ tex2D(s3, input.t3)
+ )
+ );
+}
+
+float4 main_bicubic2pass(PS_INPUT input) : COLOR
+{
+ float2 dd = frac(input.t4);
+ return Sample(taps(dd.x), input);
+ // return Sample(tex1D(s4, dd.x), input);
+}
+
diff --git a/src/apps/mplayerc/res/shaders/sharpen.psh b/src/apps/mplayerc/res/shaders/sharpen.psh
new file mode 100644
index 000000000..e1001f476
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/sharpen.psh
@@ -0,0 +1,30 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define effect_width (1.6)
+#define val0 (2.0)
+#define val1 (-0.125)
+
+#define width (p0[0])
+#define height (p0[1])
+
+float4 main(float2 tex : TEXCOORD0) : COLOR
+{
+ float dx = effect_width/width;
+ float dy = effect_width/height;
+
+ float4 c1 = tex2D(s0, tex + float2(-dx,-dy)) * val1;
+ float4 c2 = tex2D(s0, tex + float2(0,-dy)) * val1;
+ float4 c3 = tex2D(s0, tex + float2(-dx,0)) * val1;
+ float4 c4 = tex2D(s0, tex + float2(dx,0)) * val1;
+ float4 c5 = tex2D(s0, tex + float2(0,dy)) * val1;
+ float4 c6 = tex2D(s0, tex + float2(dx,dy)) * val1;
+ float4 c7 = tex2D(s0, tex + float2(-dx,+dy)) * val1;
+ float4 c8 = tex2D(s0, tex + float2(+dx,-dy)) * val1;
+ float4 c9 = tex2D(s0, tex) * val0;
+
+ float4 c0 = (c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 +c9);
+
+ return c0;
+} \ No newline at end of file
diff --git a/src/apps/mplayerc/res/shaders/sphere.psh b/src/apps/mplayerc/res/shaders/sphere.psh
new file mode 100644
index 000000000..62dca5645
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/sphere.psh
@@ -0,0 +1,60 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define width (p0[0])
+#define height (p0[1])
+#define counter (p0[2])
+#define clock (p0[3])
+#define one_over_width (p1[0])
+#define one_over_height (p1[1])
+
+#define PI acos(-1)
+
+float4 main(float2 tex : TEXCOORD0) : COLOR
+{
+ // - this is a very simple raytracer, one sphere only
+ // - no reflection or refraction, yet (my ati 9800 has a 64 + 32 instruction limit...)
+
+ float3 pl = float3(3,-3,-4); // light pos
+ float4 cl = 0.4; // light color
+
+ float3 pc = float3(0,0,-1); // cam pos
+ float3 ps = float3(0,0,0.5); // sphere pos
+ float r = 0.65; // sphere radius
+
+ float3 pd = normalize(float3(tex.x-0.5, tex.y-0.5, 0) - pc);
+
+ float A = 1;
+ float B = 2*dot(pd, pc - ps);
+ float C = dot(pc - ps, pc - ps) - r*r;
+ float D = B*B - 4*A*C;
+
+ float4 c0 = 0;
+
+ if(D >= 0)
+ {
+ // t2 is the smaller, obviously...
+ // float t1 = (-B + sqrt(D)) / (2*A);
+ // float t2 = (-B - sqrt(D)) / (2*A);
+ // float t = min(t1, t2);
+
+ float t = (-B - sqrt(D)) / (2*A);
+
+ // intersection data
+ float3 p = pc + pd*t;
+ float3 n = normalize(p - ps);
+ float3 l = normalize(pl - p);
+
+ // mapping the image onto the sphere
+ tex = acos(-n)/PI;
+
+ // rotate it
+ tex.x = frac(tex.x + frac(clock/10));
+
+ // diffuse + specular
+ c0 = tex2D(s0, tex) * dot(n, l) + cl * pow(max(dot(l, reflect(pd, n)), 0), 50);
+ }
+
+ return c0;
+}
diff --git a/src/apps/mplayerc/res/shaders/spotlight.psh b/src/apps/mplayerc/res/shaders/spotlight.psh
new file mode 100644
index 000000000..1a185a8f4
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/spotlight.psh
@@ -0,0 +1,22 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define width (p0[0])
+#define height (p0[1])
+#define counter (p0[2])
+#define clock (p0[3])
+#define one_over_width (p1[0])
+#define one_over_height (p1[1])
+
+#define PI acos(-1)
+
+float4 main(float2 tex : TEXCOORD0) : COLOR
+{
+ float4 c0 = tex2D(s0, tex);
+ float3 lightsrc = float3(sin(clock*PI/1.5)/2+0.5,cos(clock*PI)/2+0.5,1);
+ float3 light = normalize(lightsrc - float3(tex.x,tex.y,0));
+ c0 *= pow(dot(light, float3(0,0,1)), 50);
+
+ return c0;
+}
diff --git a/src/apps/mplayerc/res/shaders/wave.psh b/src/apps/mplayerc/res/shaders/wave.psh
new file mode 100644
index 000000000..8cc42ed5c
--- /dev/null
+++ b/src/apps/mplayerc/res/shaders/wave.psh
@@ -0,0 +1,29 @@
+sampler s0 : register(s0);
+float4 p0 : register(c0);
+float4 p1 : register(c1);
+
+#define width (p0[0])
+#define height (p0[1])
+#define counter (p0[2])
+#define clock (p0[3])
+#define one_over_width (p1[0])
+#define one_over_height (p1[1])
+
+#define PI acos(-1)
+
+float4 main(float2 tex : TEXCOORD0) : COLOR
+{
+ // don't look at this for too long, you'll get dizzy :)
+
+ float4 c0 = 0;
+
+ tex.x += sin(tex.x+clock/0.3)/20;
+ tex.y += sin(tex.x+clock/0.3)/20;
+
+ if(tex.x >= 0 && tex.x <= 1 && tex.y >= 0 && tex.y <= 1)
+ {
+ c0 = tex2D(s0, tex);
+ }
+
+ return c0;
+}
diff --git a/src/apps/mplayerc/res/single.ico b/src/apps/mplayerc/res/single.ico
new file mode 100644
index 000000000..626da9bc2
--- /dev/null
+++ b/src/apps/mplayerc/res/single.ico
Binary files differ
diff --git a/src/apps/mplayerc/res/stereo.bmp b/src/apps/mplayerc/res/stereo.bmp
new file mode 100644
index 000000000..fec2e16ba
--- /dev/null
+++ b/src/apps/mplayerc/res/stereo.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/streamtypes.bmp b/src/apps/mplayerc/res/streamtypes.bmp
new file mode 100644
index 000000000..8aef07389
--- /dev/null
+++ b/src/apps/mplayerc/res/streamtypes.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/toolbar1.bmp b/src/apps/mplayerc/res/toolbar1.bmp
new file mode 100644
index 000000000..a0cd5087a
--- /dev/null
+++ b/src/apps/mplayerc/res/toolbar1.bmp
Binary files differ
diff --git a/src/apps/mplayerc/res/web/1pix.gif b/src/apps/mplayerc/res/web/1pix.gif
new file mode 100644
index 000000000..410a04b28
--- /dev/null
+++ b/src/apps/mplayerc/res/web/1pix.gif
Binary files differ
diff --git a/src/apps/mplayerc/res/web/404.html b/src/apps/mplayerc/res/web/404.html
new file mode 100644
index 000000000..eabeda830
--- /dev/null
+++ b/src/apps/mplayerc/res/web/404.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <title>MPC WebServer</title>
+ <link rel="stylesheet" type="text/css" href="/default.css">
+ </head>
+ <body>
+ <strong>404 - The requested URL was not found!</strong>
+ </body>
+</html>
+[debug]
diff --git a/src/apps/mplayerc/res/web/bottomside.png b/src/apps/mplayerc/res/web/bottomside.png
new file mode 100644
index 000000000..69d4e40d1
--- /dev/null
+++ b/src/apps/mplayerc/res/web/bottomside.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/browser.html b/src/apps/mplayerc/res/web/browser.html
new file mode 100644
index 000000000..6cae6c267
--- /dev/null
+++ b/src/apps/mplayerc/res/web/browser.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <title>MPC WebServer</title>
+ <meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=[charset]">
+ <link rel="stylesheet" type="text/css" href="/default.css">
+ </head>
+ <body>
+ <p>
+ <table border="1" cellpadding="2" cellspacing="1" width="100%">
+ <tr>
+ <td align="center"><strong>Location: </strong>[currentdir]</td>
+ </tr>
+ </table>
+ </p>
+ <p>
+ <table border="1" cellpadding="2" cellspacing="1" width="100%">
+ <tr>
+ <th width="100%"><nobr>Name</nobr></th>
+ <th><nobr>Type</nobr></th>
+ <th><nobr>Size</nobr></th>
+ <th><nobr>Date Modified</nobr></th>
+ </tr>
+ [currentfiles]
+ </table>
+ </p>
+ </body>
+</html>
+[debug]
diff --git a/src/apps/mplayerc/res/web/controlback.png b/src/apps/mplayerc/res/web/controlback.png
new file mode 100644
index 000000000..9dddb5e7e
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controlback.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/controlbuttondecrate.png b/src/apps/mplayerc/res/web/controlbuttondecrate.png
new file mode 100644
index 000000000..73e0c23e1
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controlbuttondecrate.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/controlbuttonincrate.png b/src/apps/mplayerc/res/web/controlbuttonincrate.png
new file mode 100644
index 000000000..aeb31385d
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controlbuttonincrate.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/controlbuttonpause.png b/src/apps/mplayerc/res/web/controlbuttonpause.png
new file mode 100644
index 000000000..f8837a310
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controlbuttonpause.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/controlbuttonplay.png b/src/apps/mplayerc/res/web/controlbuttonplay.png
new file mode 100644
index 000000000..2f97c6f02
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controlbuttonplay.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/controlbuttonskipback.png b/src/apps/mplayerc/res/web/controlbuttonskipback.png
new file mode 100644
index 000000000..aba644ee1
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controlbuttonskipback.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/controlbuttonskipforward.png b/src/apps/mplayerc/res/web/controlbuttonskipforward.png
new file mode 100644
index 000000000..db720c892
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controlbuttonskipforward.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/controlbuttonstep.png b/src/apps/mplayerc/res/web/controlbuttonstep.png
new file mode 100644
index 000000000..2eb1671cd
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controlbuttonstep.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/controlbuttonstop.png b/src/apps/mplayerc/res/web/controlbuttonstop.png
new file mode 100644
index 000000000..fcc80afa9
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controlbuttonstop.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/controls.html b/src/apps/mplayerc/res/web/controls.html
new file mode 100644
index 000000000..6a55fd506
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controls.html
@@ -0,0 +1,1735 @@
+<html>
+ <head>
+ <title>MPC WebServer</title>
+ <meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=[charset]">
+ <link rel="stylesheet" type="text/css" href="/default.css">
+ <script language="JavaScript" type="text/JavaScript">
+
+ // var filedir = "[filedirarg]";
+ var filepath = "[filepath]";
+ var curpos = [position];
+ var length = [duration];
+ var state = [state];
+ var pbr = [playbackrate];
+ var eta = [reloadtime];
+ var volume = [volumelevel];
+ var muted = [muted]; // -1 no sound
+
+ var starttime = (new Date()).getTime();
+ var slidersize = 500;
+ var sliderbuttonwidth = 15;
+ var vsb=10;
+ var vss=100;
+ var sc=0
+ var rdirt
+ var AP
+ var RL
+ var rpt
+ var etaup=false
+
+ if (eta==0) eta=(state<0 && filepath.length>0)?2:120;
+
+ function init()
+ {
+ if (eta>0) RL=setTimeout("etaup=true; if (re.checked==true) postform(0,'null',0);",1000*eta);
+ Live=(length<1);
+ starttime=starttime-curpos;
+ rdirt=length*pbr/slidersize;
+ rdirt=Math.floor(rdirt>1000?1000:(rdirt<300?300:rdirt))
+ cpf=document.getElementById("pos")
+ cp=document.getElementById("time")
+ sas=document.getElementById("SliderAutoScroll")
+ re=document.getElementById("reloadenabled")
+ s=document.getElementById("slider")
+ sb1=document.getElementById("c1")
+ sb2=document.getElementById("c2")
+ sb3=document.getElementById("c3")
+ vs=document.getElementById("v")
+ vs1=document.getElementById("v1")
+ vs2=document.getElementById("v2")
+ vs3=document.getElementById("v3")
+ document.getElementById("muted").innerHTML= muted == -1 ? "X" : muted == 1 ? "M" : "&nbsp;&nbsp;";
+
+ s.height=sb1.height=sb2.height=sb3.height=vs.height=vs1.height=vs2.height=vs3.height=20
+ s.width=slidersize+(sb2.width=sliderbuttonwidth);
+ vs.width=vss+(vs2.width=vsb);
+
+ sb1.onclick=sb2.onclick=sb3.onclick=sliderclick
+ vs1.onclick=vs2.onclick=vs3.onclick=vsliderclick
+
+ sas.checked=true;
+ // g=" "+secondsToTS(curpos,0,true)+" "+x<0?("Buffering %"+(-x-1).toString()):"";
+ cp.innerHTML = cpf.value=secondsToTS(curpos,5,false);
+ rpt=curpos;
+ if (state==2 && pbr!=0)
+ autoplay();
+ vupdate(volume,true);
+ return update(curpos,true);
+ }
+ function autoplay(a)
+ {
+ if (etaup && re.checked==true)
+ {
+ etaup=false;
+ RL=setTimeout("etaup=true; if (re.checked==true) postform(0,'null',0);",5000);
+ }
+ AP=setTimeout('autoplay()',rdirt);
+ var ct = (new Date()).getTime();
+ var cap=pbr*(ct-starttime);
+ if (cap>length && !Live) if (re.checked==true) RL=setTimeout('window.location=window.location',5000);
+ cap=((cap>length && !Live)?length:(cap<0?0:cap))
+ if (sas.checked==true || a==true)
+ {
+ update(cap,true)
+ cpf.value=secondsToTS(cap,5,false);
+ }
+ var gg = " "+secondsToTS(cap,5,true)+" ";
+ cp.innerHTML = gg;
+ rpt=cap;
+ return true;
+ }
+ function pad(number, length)
+ {
+ var str = '' + number;
+ while(str.length < length) str = '0' + str;
+ return str;
+ }
+ function secondsToTS(a,b,c)
+ {
+ var a1 = Math.floor(a/3600000);
+ var a2 = Math.floor(a/60000)%60;
+ var a3 = Math.floor(a/1000)%60;
+ var a4 = Math.floor(a)%1000;
+ var a1s = pad(a1.toString(),2);
+ var a2s = pad(a2.toString(),2);
+ var a3s = pad(a3.toString(),2);
+ var a4s = pad(a4.toString(),3);
+ switch(b){
+ case 1: return a1s;
+ case 2: return a2s;
+ case 3: return a3s;
+ case 4: return a4s;
+ case 5: //return a1s+":"+a2s+":"+a3s+"."+a4s;
+ case 6: //return ((a1>0?(a1s+":"):"")+a2s+":"+a3s+"."+a4s);
+ case 7: return a1s+":"+a2s+":"+a3s;
+ default: return ((a1>0?(a1s+":"):"")+a2s+":"+a3s);
+ }
+ return "bahh";
+ }
+ function parsetime(y)
+ {
+ ts=timesyntax(y)
+ t = 0
+ p1=ts.indexOf(".")
+ p2=ts.indexOf(":")
+ p3=ts.indexOf(":",p2+1)
+ p4=ts.indexOf(":",p3+1)
+ if (p4!=-1 || (p1!=-1 && p2!=-1 && p2>p1) || (p1!=-1 && p3!=-1 && p3>p1)) return -2000;
+ p1=(p1 == -1?ts.length+1:p1)
+ if (p2 == -1) t=parseFloat((ts+" ").substring(0,p1+4));
+ if (p2 != -1 && p3 == -1) t=parseInt(ts.substring(0,p2))*60 +
+ parseFloat("0"+(ts+" ").substring(p2+1,p1+4));
+ if (p2 != -1 && p3 != -1) t=parseInt(ts.substring(0,p2))*3600 +
+ parseInt(ts.substring(p2+1,p3))*60 +
+ parseFloat("0"+(ts+" ").substring(p3+1,p1+4));
+ return t;
+ }
+ function update(a,b)
+ {
+ if (a==-2000) return false;
+ if (b){ m=(curpos=((a>length && !Live)?length:(a<0?0:a)))*slidersize/length; }
+ else{ curpos=(m=(a>slidersize?slidersize:(a<0?0:a)))*length/slidersize; }
+ if (m>sb1.width)
+ {sb3.width=slidersize-Math.floor(m); sb1.width=m;}else
+ {sb1.width=m; sb3.width=slidersize-sb1.width;}
+ return true;
+ }
+ function sliderclick(e)
+ {
+ update( (window.event?window.event.clientX-3:e.clientX) + document.body.scrollLeft -
+ getoffsetx(s) - Math.floor(sliderbuttonwidth/2) + sc, false);
+ cpf.value=secondsToTS(curpos,5,false);
+ sas.checked=false;
+ return true;
+ }
+ function getoffsetx(m)
+ {
+ var x = m.offsetLeft;
+ while (m.offsetParent) {x += (m = m.offsetParent).offsetLeft; }
+ return x;
+ }
+ function posupdate()
+ {
+ if (event.keyCode < 46 || event.keyCode > 58 || event.keyCode==47)
+ return false;
+ self.setTimeout('update(parseFloat(parsetime(cpf.value)),true)',1);
+ return true;
+ }
+
+ function timesyntax(ts)
+ {
+ var b=""
+ for(a=0;a<ts.length;a++)
+ {
+ switch(ts.charAt(a)){
+ case "0": b+="0";break;
+ case "1": b+="1";break;
+ case "2": b+="2";break;
+ case "3": b+="3";break;
+ case "4": b+="4";break;
+ case "5": b+="5";break;
+ case "6": b+="6";break;
+ case "7": b+="7";break;
+ case "8": b+="8";break;
+ case "9": b+="9";break;
+ case ".": b+=".";break;
+ case ":": b+=":";break;
+ default: break;}
+ }
+ return b;
+ }
+
+ function vupdate(a,b)
+ {
+ if (b){ m=(volume=((a>100)?100:(a<0?0:a)))*vss/100; }
+ else{ volume=(m=(a>vss?vss:(a<0?0:a)))*100/vss; }
+ volume=Math.ceil(volume)
+ vs1.width=m;
+ vs3.width=vss-vs1.width;
+ return true;
+ }
+ function vsliderclick(e)
+ {
+ return vupdate( (window.event?window.event.clientX-3:e.clientX) + document.body.scrollLeft -
+ getoffsetx(vs) - Math.floor(vsb/2) + sc, false);
+ }
+ function postform(wmc,ext,extv)
+ {
+ document.getElementById("fwmc").value=wmc;
+ document.getElementById("fextra").value=extv;
+ document.getElementById("fextra").name=ext;
+ document.getElementById("ef").submit();
+ return true;
+ }
+
+ </script>
+ </head>
+ <body onload="init()">
+ <p>
+ <strong>
+ Feel free to redesign this page (nice image buttons, more "player-like" layout, etc.), but if you do
+ alter the page <a href="http://cvs.sourceforge.net/viewcvs.py/guliverkli/guliverkli/src/apps/mplayerc/res/web/">here</a>
+ and not the one you can save from the browser. Post your comments, remarks, ideas, progress into
+ <a href="https://sourceforge.net/forum/message.php?msg_id=2357783">this topic</a>.
+ </strong>
+ </p>
+ <p>
+ File Info
+ <noscript>: disabled (component requires javascript)</noscript>
+ <br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td colspan="4">
+ <nobr>
+ Loaded file: <a href="[browserpath]?path=[filepatharg]&redir=[path]">[filepath]</a>
+ <a href="[browserpath]?path=[filedirarg]">Browse...</a>
+ </nobr>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Status: [statestring]
+ </td>
+ <td align="center">
+ <table>
+ <tr>
+ <td id="time">[positionstring]</td>
+ <td>/</td>
+ <td>[durationstring]</td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <input type="checkbox" id="reloadenabled" checked>
+ </td>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ </noscript>
+ <input type="submit" value="Refresh" name="submit" onclick="window.location=window.location; return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </p>
+ <p>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="-1"> Goto control
+ <noscript>: (position slider disabled)</noscript>
+ <br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <table id="slider" border="0" cellspacing="0" cellpadding="0" width="1" height="1" style="background-image:url('sliderback.gif');">
+ <tr>
+ <td><img id="c1" width="1" height="1" src="/1pix.gif" ></td>
+ <td><img id="c2" width="1" height="1" src="/slidergrip.gif"></td>
+ <td><img id="c3" width="1" height="1" src="/1pix.gif"></td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <input type="checkbox" id="SliderAutoScroll" onclick="if (sas.checked==true) {update(rpt,true); cpf.value=secondsToTS(rpt,5,false)}; return true;">
+ </td>
+ <td>
+ <noscript>Goto...</noscript>
+ <input id="pos" name="position" size="12" onfocus="sas.checked=false;" onkeypress="return posupdate()"
+ value="[positionstring]">
+ </td>
+ <td>
+ <input type="submit" value="Go!" name="submit" onclick="postform([setposcommand],'position',timesyntax(cpf.value)); return false;">
+ </td>
+ </tr>
+ </table>
+ </form>
+ </p>
+ <p>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ Playback control<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="887">
+ </noscript>
+ <input type="submit" value=" &gt; " name="submit" onclick="postform(887,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="888">
+ </noscript>
+ <input type="submit" value=" I I " name="submit" onclick="postform(888,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="890">
+ </noscript>
+ <input type="submit" value=" # " name="submit" onclick="postform(890,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="920">
+ </noscript>
+ <input type="submit" value="I&lt;&lt;" name="submit" onclick="postform(920,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="894">
+ </noscript>
+ <input type="submit" value="&lt;&lt;" name="submit" onclick="postform(894,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="895">
+ </noscript>
+ <input type="submit" value="&gt;&gt;" name="submit" onclick="postform(895,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="921">
+ </noscript>
+ <input type="submit" value="&gt;&gt;I" name="submit" onclick="postform(921,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="892">
+ </noscript>
+ <input type="submit" value=" &lt;I " name="submit" onclick="postform(892,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="891">
+ </noscript>
+ <input type="submit" value=" I&gt; " name="submit" onclick="postform(891,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ <td width="20">
+ &nbsp;
+ </td>
+ <td>
+ Seek<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="897">
+ </noscript>
+ <input type="submit" value="&lt; k" name="submit" onclick="postform(897,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="903">
+ </noscript>
+ <input type="submit" value="&lt;&lt;&lt;" name="submit" onclick="postform(903,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="901">
+ </noscript>
+ <input type="submit" value=" &lt;&lt; " name="submit" onclick="postform(901,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="899">
+ </noscript>
+ <input type="submit" value=" &lt; " name="submit" onclick="postform(899,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="900">
+ </noscript>
+ <input type="submit" value=" &gt; " name="submit" onclick="postform(900,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="902">
+ </noscript>
+ <input type="submit" value=" &gt;&gt; " name="submit" onclick="postform(902,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="904">
+ </noscript>
+ <input type="submit" value="&gt;&gt;&gt;" name="submit" onclick="postform(904,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="898">
+ </noscript>
+ <input type="submit" value="k &gt;" name="submit" onclick="postform(898,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </p>
+ <p>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ Volume control
+ <noscript>: (integer between 0 & 100)</noscript><br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td id="muted" align="center" valign="center">
+ U
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="909">
+ </noscript>
+ <input type="submit" value="Mute" name="submit" onclick="postform(909,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ <table id="v" width="1" height="1" border="0" cellspacing="0" cellpadding="0" style="background-image:url('vbg.gif');">
+ <tr>
+ <td><img id="v1" src="/1pix.gif" width="1" height="1"></td>
+ <td><img id="v2" src="/vbs.gif" width="1" height="1"></td>
+ <td><img id="v3" src="/1pix.gif" width="1" height="1"></td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="[setvolumecommand]">
+ <input name="volume" value="[volumelevel]" size="5">
+ <!-- FIXME /form -->
+ </noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <input type="submit" value="Go!" name="submit" onclick="postform([setvolumecommand],'volume',volume); return true;">
+ <noscript></form><!-- FIXME --></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="908">
+ </noscript>
+ <input type="submit" value="Down" name="submit" onclick="postform(908,'null',0); return true;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="907">
+ </noscript>
+ <input type="submit" value=" Up " name="submit" onclick="postform(907,'null',0); return true;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td width="20">
+ &nbsp;
+ </td>
+ <td>
+ Playlist
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="918">
+ </noscript>
+ <input type="submit" value="&lt;&lt;" name="submit" onclick="postform(918,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="919">
+ </noscript>
+ <input type="submit" value="&gt;&gt;" name="submit" onclick="postform(919,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ <td width="20">
+ &nbsp;
+ </td>
+ <td>
+ Panic Button<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="943">
+ </noscript>
+ <input type="submit" value="Boss Key" name="submit" onclick="postform(943,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td width="20">
+ &nbsp;
+ </td>
+ <td>
+ Audio Delay<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="906">
+ </noscript>
+ <input type="submit" value="-10ms" name="submit" onclick="postform(906,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="905">
+ </noscript>
+ <input type="submit" value="+10ms" name="submit" onclick="postform(905,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </p>
+ <!-- sorry chobits, I was thinking of doing this differently :) p>
+ <form action="[commandpath]" method="POST">
+ Playlist Editor<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr align="center">
+ <td colspan="4">
+ <input type="hidden" name="[wmcname]" value="-3">
+ <textarea name="playlist" multiple cols="60" rows="10" wrap="off">[playlist]</textarea>
+ </td>
+ </tr>
+ <tr>
+ <td align="center">
+ Play changes on update&nbsp;
+ <input type="checkbox" name="playupdate" checked>
+ </td>
+ <td align="center">
+ Playlist playing position&nbsp;
+ <input type="text" name="playlistposition" size=4 value="[currentplaylistposition]">
+ </td>
+ <td align="center">
+ <input type="submit" value="Update" name="submit">
+ </td>
+ </tr>
+ </table>
+ </form>
+ </p -->
+ <p>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ Pan&amp;Scan Move<br>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="872">
+ </noscript>
+ <input type="submit" value="Up/Left" name="submit" onclick="postform(872,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="870">
+ </noscript>
+ <input type="submit" value="Up" name="submit" onclick="postform(870,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="873">
+ </noscript>
+ <input type="submit" value="Up/Right" name="submit" onclick="postform(873,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="868">
+ </noscript>
+ <input type="submit" value="Left" name="submit" onclick="postform(868,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="876">
+ </noscript>
+ <input type="submit" value="Center" name="submit" onclick="postform(876,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="869">
+ </noscript>
+ <input type="submit" value="Right" name="submit" onclick="postform(869,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="874">
+ </noscript>
+ <input type="submit" value="Down/Left" name="submit" onclick="postform(874,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="871">
+ </noscript>
+ <input type="submit" value="Down" name="submit" onclick="postform(871,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="875">
+ </noscript>
+ <input type="submit" value="Down/Right" name="submit" onclick="postform(875,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ <td width="30">
+ &nbsp;
+ </td>
+ <td>
+ Pan&amp;Scan Size<br>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="866">
+ </noscript>
+ <input type="submit" value="Inc Height" name="submit" onclick="postform(866,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="862">
+ </noscript>
+ <input type="submit" value="Inc Size" name="submit" onclick="postform(862,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="865">
+ </noscript>
+ <input type="submit" value="Dec Width" name="submit" onclick="postform(865,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="861">
+ </noscript>
+ <input type="submit" value="Reset" name="submit" onclick="postform(861,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="864">
+ </noscript>
+ <input type="submit" value="Inc Width" name="submit" onclick="postform(864,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ <tr>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="863">
+ </noscript>
+ <input type="submit" value="Dec Size" name="submit" onclick="postform(863,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="867">
+ </noscript>
+ <input type="submit" value="Dec Height" name="submit" onclick="postform(867,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </td> </tr> </table>
+ </p>
+ <p>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ Video Frame<br>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="835">
+ </noscript>
+ <input type="submit" value="Half" name="submit" onclick="postform(835,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="837">
+ </noscript>
+ <input type="submit" value="Double" name="submit" onclick="postform(837,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="836">
+ </noscript>
+ <input type="submit" value="Normal" name="submit" onclick="postform(836,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="838">
+ </noscript>
+ <input type="submit" value="Stretch" name="submit" onclick="postform(838,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="839">
+ </noscript>
+ <input type="submit" value="Inside" name="submit" onclick="postform(839,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="840">
+ </noscript>
+ <input type="submit" value="Outside" name="submit" onclick="postform(840,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ <td width="30">
+ </td>
+ <td>
+ DVD Menu Controler<br>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="930">
+ </noscript>
+ <input type="submit" value="Up" name="submit" onclick="postform(930,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="928">
+ </noscript>
+ <input type="submit" value="Left" name="submit" onclick="postform(928,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="932">
+ </noscript>
+ <input type="submit" value="Activate" name="submit" onclick="postform(932,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="929">
+ </noscript>
+ <input type="submit" value="Right" name="submit" onclick="postform(929,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="933">
+ </noscript>
+ <input type="submit" value="Back" name="submit" onclick="postform(933,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="931">
+ </noscript>
+ <input type="submit" value="Down" name="submit" onclick="postform(931,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="934">
+ </noscript>
+ <input type="submit" value="Leave" name="submit" onclick="postform(934,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </table>
+ <td width="30">
+ &nbsp;
+ </td>
+ <td>
+ Misc<br>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="800">
+ </noscript>
+ <input type="submit" value="Open File" name="submit" onclick="postform(800,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="801">
+ </noscript>
+ <input type="submit" value="Open DVD" name="submit" onclick="postform(801,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="802">
+ </noscript>
+ <input type="submit" value="Open Device" name="submit" onclick="postform(802,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="805">
+ </noscript>
+ <input type="submit" value="Save As" name="submit" onclick="postform(805,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="804">
+ </noscript>
+ <input type="submit" value="Close" name="submit" onclick="postform(804,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="816">
+ </noscript>
+ <input type="submit" value="Exit" name="submit" onclick="postform(816,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="893">
+ </noscript>
+ <input type="submit" value="Go To" name="submit" onclick="postform(893,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="886">
+ </noscript>
+ <input type="submit" value="Options" name="submit" onclick="postform(886,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border="2" cellspacing="1" cellpadding="4" width="100%">
+ <tr>
+ <td align="center">
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="814">
+ </noscript>
+ <input type="submit" value="Properties" name="submit" onclick="postform(814,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </p>
+ <p>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ Zoom control<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="832">
+ </noscript>
+ <input type="submit" value="Zoom 50%" name="submit" onclick="postform(832,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="833">
+ </noscript>
+ <input type="submit" value="Zoom 100%" name="submit" onclick="postform(833,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="834">
+ </noscript>
+ <input type="submit" value="Zoom 200%" name="submit" onclick="postform(834,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td width="20">
+ &nbsp;
+ </td>
+ <td>
+ Fullscreen control<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="830">
+ </noscript>
+ <input type="submit" value="Normal" name="submit" onclick="postform(830,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="831">
+ </noscript>
+ <input type="submit" value="w/o res.change" name="submit" onclick="postform(831,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </p>
+ <p>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ Player views<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="827">
+ </noscript>
+ <input type="submit" value="Minimal" name="submit" onclick="postform(827,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="828">
+ </noscript>
+ <input type="submit" value="Compact" name="submit" onclick="postform(828,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="829">
+ </noscript>
+ <input type="submit" value="Normal" name="submit" onclick="postform(829,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td width="20">
+ </td>
+ <td>
+ Detachable Controlls<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="824">
+ </noscript>
+ <input type="submit" value="Playlist" name="submit" onclick="postform(824,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="823">
+ </noscript>
+ <input type="submit" value="Subresync" name="submit" onclick="postform(823,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="825">
+ </noscript>
+ <input type="submit" value="Capture" name="submit" onclick="postform(825,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="817">
+ </noscript>
+ <input type="submit" value="Caption&Menu" name="submit" onclick="postform(817,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="818">
+ </noscript>
+ <input type="submit" value="Seeker" name="submit" onclick="postform(818,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="819">
+ </noscript>
+ <input type="submit" value="Controls" name="submit" onclick="postform(819,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="820">
+ </noscript>
+ <input type="submit" value="Information" name="submit" onclick="postform(820,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="821">
+ </noscript>
+ <input type="submit" value="Statistics" name="submit" onclick="postform(821,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="822">
+ </noscript>
+ <input type="submit" value="Status" name="submit" onclick="postform(822,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </p>
+ <p>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ Generic Audio/Subtitles<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="952">
+ </noscript>
+ <input type="submit" value="&lt; Audio" name="submit" onclick="postform(952,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="951">
+ </noscript>
+ <input type="submit" value="Audio &gt;" name="submit" onclick="postform(951,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="954">
+ </noscript>
+ <input type="submit" value="&lt; Subtitle" name="submit" onclick="postform(954,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="953">
+ </noscript>
+ <input type="submit" value="Subtitle &gt;" name="submit" onclick="postform(953,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td width="20">
+ &nbsp;
+ </td>
+ <td>
+ <!-- p TODO -->
+ OGM Audio/Subtitles<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="957">
+ </noscript>
+ <input type="submit" value="&lt; Audio" name="submit" onclick="postform(957,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="956">
+ </noscript>
+ <input type="submit" value="Audio &gt;" name="submit" onclick="postform(956,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="959">
+ </noscript>
+ <input type="submit" value="&lt; Subtitle" name="submit" onclick="postform(959,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="958">
+ </noscript>
+ <input type="submit" value="Subtitle &gt;" name="submit" onclick="postform(958,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </p>
+ <p>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ Subtitles<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="809">
+ </noscript>
+ <input type="submit" value="Load" name="submit" onclick="postform(809,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="810">
+ </noscript>
+ <input type="submit" value="Save" name="submit" onclick="postform(810,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td width="20">
+ &nbsp;
+ </td>
+ <td>
+ DVD Angles/Audio/Subtitles<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="961">
+ </noscript>
+ <input type="submit" value="&lt; Angle" name="submit" onclick="postform(961,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="960">
+ </noscript>
+ <input type="submit" value="Angle &gt;" name="submit" onclick="postform(960,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="963">
+ </noscript>
+ <input type="submit" value="&lt; Audio" name="submit" onclick="postform(963,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="962">
+ </noscript>
+ <input type="submit" value="Audio &gt;" name="submit" onclick="postform(962,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="965">
+ </noscript>
+ <input type="submit" value="&lt; Subtitle" name="submit" onclick="postform(965,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="964">
+ </noscript>
+ <input type="submit" value="Subtitle &gt;" name="submit" onclick="postform(964,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </p>
+ <p>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ DVD Menus<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="922">
+ </noscript>
+ <input type="submit" value="Title" name="submit" onclick="postform(922,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="923">
+ </noscript>
+ <input type="submit" value="Root" name="submit" onclick="postform(923,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="924">
+ </noscript>
+ <input type="submit" value="Subtitle" name="submit" onclick="postform(924,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="925">
+ </noscript>
+ <input type="submit" value="Audio" name="submit" onclick="postform(925,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="926">
+ </noscript>
+ <input type="submit" value="Angle" name="submit" onclick="postform(926,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="927">
+ </noscript>
+ <input type="submit" value="Chapter" name="submit" onclick="postform(927,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td width="20">
+ &nbsp;
+ </td>
+ <td>
+ Media Player Classic Menu's
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="950">
+ </noscript>
+ <input type="submit" value="Filters" name="submit" onclick="postform(950,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="948">
+ </noscript>
+ <input type="submit" value="Player (short)" name="submit" onclick="postform(948,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="949">
+ </noscript>
+ <input type="submit" value="Player (long)" name="submit" onclick="postform(949,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </p>
+ <p>
+ Always On Top<br>
+ <table border="2" cellspacing="1" cellpadding="4">
+ <tr>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="884">
+ </noscript>
+ <input type="submit" value="Always" name="submit" onclick="postform(884,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="885">
+ </noscript>
+ <input type="submit" value="While Playing" name="submit" onclick="postform(885,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ <td>
+ <noscript>
+ <form action="[commandpath]" method="POST">
+ <input type="hidden" name="[wmcname]" value="883">
+ </noscript>
+ <input type="submit" value="Never" name="submit" onclick="postform(883,'null',0); return false;">
+ <noscript></form></noscript>
+ </td>
+ </tr>
+ </table>
+ <form id="ef" action="[commandpath]" method="POST"> <!-- FIXME: POSTing does not want to work with mozilla -->
+ <input id="fwmc" type="hidden" name="[wmcname]" value="-2">
+ <input id="fextra" type="hidden" name="extra" value="">
+ </form>
+ </p>
+ </body>
+</html>
+[debug]
diff --git a/src/apps/mplayerc/res/web/controlvolumebar.png b/src/apps/mplayerc/res/web/controlvolumebar.png
new file mode 100644
index 000000000..ab51a5d01
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controlvolumebar.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/controlvolumegrip.png b/src/apps/mplayerc/res/web/controlvolumegrip.png
new file mode 100644
index 000000000..f9f68ce03
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controlvolumegrip.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/controlvolumeoff.png b/src/apps/mplayerc/res/web/controlvolumeoff.png
new file mode 100644
index 000000000..a78d48389
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controlvolumeoff.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/controlvolumeon.png b/src/apps/mplayerc/res/web/controlvolumeon.png
new file mode 100644
index 000000000..979b82998
--- /dev/null
+++ b/src/apps/mplayerc/res/web/controlvolumeon.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/default.css b/src/apps/mplayerc/res/web/default.css
new file mode 100644
index 000000000..89191a529
--- /dev/null
+++ b/src/apps/mplayerc/res/web/default.css
@@ -0,0 +1,5 @@
+body, th, td
+{
+ font-size: 0.8em;
+ font-family: Verdana, Arial, Helvetica, Sans-Serif;
+} \ No newline at end of file
diff --git a/src/apps/mplayerc/res/web/headerback.png b/src/apps/mplayerc/res/web/headerback.png
new file mode 100644
index 000000000..ac14c9653
--- /dev/null
+++ b/src/apps/mplayerc/res/web/headerback.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/headerclose.png b/src/apps/mplayerc/res/web/headerclose.png
new file mode 100644
index 000000000..72fd81c98
--- /dev/null
+++ b/src/apps/mplayerc/res/web/headerclose.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/headericon.png b/src/apps/mplayerc/res/web/headericon.png
new file mode 100644
index 000000000..f8e9dc705
--- /dev/null
+++ b/src/apps/mplayerc/res/web/headericon.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/index.html b/src/apps/mplayerc/res/web/index.html
new file mode 100644
index 000000000..e050e98be
--- /dev/null
+++ b/src/apps/mplayerc/res/web/index.html
@@ -0,0 +1,35 @@
+<html>
+ <head>
+ <title>MPC WebServer</title>
+ <link rel="stylesheet" type="text/css" href="/default.css">
+ </head>
+ <body>
+ <p>
+ Sorry, this is just a little demo page for now, I'm still awaiting ideas what
+ to put here ... and mostly why (hehe) Anyway, I'm sure there will be some use
+ of this web server in the future. You users can always come up with something.
+ </p>
+ <p>
+ And if you are already here, why don't you try sending a few commands to MPC,
+ just to see if it works :)
+ </p>
+ <p>
+ <form action="[commandpath]" method="post">
+ <select name="[wmcname]">
+ [wmcoptions]
+ </select>
+ <input type="submit" value="Go!" name="submit">
+ </form>
+ </p>
+ <p>
+ <a href="/browser.html">File browser</a>
+ </p>
+ <p>
+ <a href="/controls.html">The media player interface made by chobits</a>
+ </p>
+ <p>
+ New in this release: <a href="/player.html">MPC in the browser!</a>
+ </p>
+ [debug]
+ </body>
+</html>
diff --git a/src/apps/mplayerc/res/web/leftbottomside.png b/src/apps/mplayerc/res/web/leftbottomside.png
new file mode 100644
index 000000000..93c696046
--- /dev/null
+++ b/src/apps/mplayerc/res/web/leftbottomside.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/leftside.png b/src/apps/mplayerc/res/web/leftside.png
new file mode 100644
index 000000000..f8fdfa97c
--- /dev/null
+++ b/src/apps/mplayerc/res/web/leftside.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/logo.png b/src/apps/mplayerc/res/web/logo.png
new file mode 100644
index 000000000..9ee6a389b
--- /dev/null
+++ b/src/apps/mplayerc/res/web/logo.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/player.html b/src/apps/mplayerc/res/web/player.html
new file mode 100644
index 000000000..778cf879a
--- /dev/null
+++ b/src/apps/mplayerc/res/web/player.html
@@ -0,0 +1,303 @@
+<html>
+
+<head>
+
+<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8">
+
+<title>Media Player Classic</title>
+
+<script language="JavaScript" type="text/JavaScript">
+
+function getXMLHTTP()
+{
+ try {return new ActiveXObject("Msxml2.XMLHTTP");}
+ catch(e) {try {return new ActiveXObject("Microsoft.XMLHTTP");}
+ catch(e) {}}
+ if(typeof XMLHttpRequest != "undefined") {return new XMLHttpRequest();}
+ return null;
+}
+
+function MakeRequest(req)
+{
+ var httpRequest = getXMLHTTP();
+
+ try
+ {
+ httpRequest.open("GET", req, true);
+ httpRequest.send(null);
+ }
+ catch(e)
+ {
+ }
+}
+
+function urlencode(s)
+{
+ if(encodeURIComponent) return encodeURIComponent(s);
+ if(escape) return escape(s);
+ return s; // whatever
+}
+
+function getOffsetX(m)
+{
+ var x = m.offsetLeft;
+ while (m.offsetParent) {x += (m = m.offsetParent).offsetLeft; }
+ return x;
+}
+
+OnStatus = function(title, status, pos, posstr, dur, durstr, muted, volume)
+{
+ var maxtitle = 70;
+ if(title.length > maxtitle) title = title.substr(0, maxtitle-3) + '...';
+ var timestr = dur > 0 && posstr && durstr ? posstr + '&nbsp;/&nbsp;' + durstr : '&nbsp;';
+ if(!dur || dur == 0) dur = 1;
+ var sbpercent = Math.floor(100*pos/dur);
+
+ if(e = document.getElementById('title')) e.innerHTML = title;
+ if(e = document.getElementById('seekbarchleft')) e.width = sbpercent > 0 ? sbpercent + '%' : '1px';
+ if(e = document.getElementById('seekbarchright')) e.width = sbpercent < 100 ? (100 - sbpercent) + '%' : '1px';
+ if((e = document.getElementById('status')) && e.innerHTML != status) e.innerHTML = status;
+ if((e = document.getElementById('timer')) && e.innerHTML != timestr) e.innerHTML = timestr;
+ if(e = document.getElementById('controlvolumemute')) {url = 'url(controlvolume' + (muted?'off':'on') + '.png)'; if(e.style.backgroundImage != url) e.style.backgroundImage = url;}
+ if(e = document.getElementById('controlvolumegrip'))
+ {
+ volume = (document.getElementById('controlvolumebar').offsetWidth - e.offsetWidth) * volume / 100;
+ e.style.position = 'relative';
+ e.style.top = '2px';
+ e.style.left = Math.floor(volume) + 'px';
+ }
+}
+
+var httpRequestStatus;
+
+function OnReadyStateChange()
+{
+ if(httpRequestStatus && httpRequestStatus.readyState == 4 && httpRequestStatus.responseText)
+ {
+ if(httpRequestStatus.responseText.charAt(0) != "<") eval(httpRequestStatus.responseText);
+ else {alert(httpRequestStatus.responseText);}
+ httpRequestStatus = null;
+ }
+}
+
+function StatusLoop()
+{
+ if(!httpRequestStatus || httpRequestStatus.readyState == 0)
+ {
+ httpRequestStatus = getXMLHTTP();
+
+ try
+ {
+ httpRequestStatus.open("GET", 'status.html', true);
+ httpRequestStatus.onreadystatechange = OnReadyStateChange;
+ httpRequestStatus.send(null);
+ }
+ catch(e)
+ {
+ }
+ }
+
+ setTimeout("StatusLoop()", 500);
+}
+
+var snapshotcounter = 0;
+
+function LoadSnapShot()
+{
+ if(img = document.getElementById('snapshot'))
+ {
+ img.src = 'snapshot.jpg' + '?' + snapshotcounter++;
+ }
+}
+
+function OnLoadSnapShot()
+{
+ setTimeout("LoadSnapShot()", 5000);
+}
+
+function OnAbortErrorSnapShot(e)
+{
+ setTimeout("LoadSnapShot()", 10000);
+}
+
+function OnSeek(e)
+{
+ left = right = 0;
+ if(sb = document.getElementById('seekbarchleft')) left = getOffsetX(sb);
+ if(sb = document.getElementById('seekbarchright')) {right = getOffsetX(sb) + sb.offsetWidth;}
+ if(sb = document.getElementById('seekbargrip')) {left += sb.offsetWidth / 2; right -= sb.offsetWidth / 2;}
+ if(left > 0 && left < right)
+ {
+ percent = 100 * ((window.event ? window.event.clientX : e.clientX) - left) / (right - left);
+ if(percent < 0) percent = 0;
+ else if(percent > 100) percent = 100;
+
+ MakeRequest('command.html?wm_command=[setposcommand]&percent='+percent);
+ }
+}
+
+function OnVolume(e)
+{
+ left = right = 0;
+ if(cv = document.getElementById('controlvolumebar')) {left = getOffsetX(cv)+3; right = getOffsetX(cv) + cv.offsetWidth-3;}
+ if(left > 0 && left < right)
+ {
+ percent = 100 * ((window.event ? window.event.clientX : e.clientX) - left) / (right - left);
+ if(percent < 0) percent = 0;
+ else if(percent > 100) percent = 100;
+
+ MakeRequest('command.html?wm_command=[setvolumecommand]&volume='+percent);
+ }
+}
+
+function OnCommand(id)
+{
+ MakeRequest('command.html?wm_command='+id);
+}
+
+function Init()
+{
+ StatusLoop();
+ LoadSnapShot();
+
+ if(e = document.getElementById('seekbar'))
+ e.onclick = OnSeek;
+
+ if(e = document.getElementById('controlvolumebar'))
+ e.onclick = OnVolume;
+}
+
+</script>
+
+<style>
+img {padding: 0; margin: 0; border: 0;}
+#player {margin-left: auto; margin-right: auto;}
+#player td {font-family: Sans-Serif; font-size: 13px;}
+#header {width: 100%;}
+#header td {height: 30px;}
+#headericon {background-image: url(headericon.png); background-repeat: no-repeat; width: 22px;}
+#headerback {background-image: url(headerback.png); background-repeat: repeat-x; color: white; font-weight: bold; padding-top: 5px}
+#headerclose {background-image: url(headerclose.png); background-repeat: no-repeat; width: 28px;}
+#title, #status, #posstr, #durstr {display: inline;}
+#menu td {font-family: Sans-Serif; font-size: 12px; padding: 1px 5px;}
+#menu, #controlbar {background-color: #ece6d4;}
+#statusbar td {font-family: Sans-Serif; font-size: 12px;}
+#video, #statusbar {background-color: black; color: white;}
+#video {padding: 1px; cursor: pointer;}
+#controlbar {background-image: url(controlback.png); background-repeat: repeat-x; height: 28px;}
+#controlbuttonplay {background-image: url(controlbuttonplay.png); background-repeat: no-repeat; width: 25px; height: 28px;}
+#controlbuttonpause {background-image: url(controlbuttonpause.png); background-repeat: no-repeat; width: 23px; height: 28px;}
+#controlbuttonstop {background-image: url(controlbuttonstop.png); background-repeat: no-repeat; width: 25px; height: 28px;}
+#controlbuttonskipback {background-image: url(controlbuttonskipback.png); background-repeat: no-repeat; width: 24px; height: 28px;}
+#controlbuttondecrate {background-image: url(controlbuttondecrate.png); background-repeat: no-repeat; width: 22px; height: 28px;}
+#controlbuttonincrate {background-image: url(controlbuttonincrate.png); background-repeat: no-repeat; width: 23px; height: 28px;}
+#controlbuttonskipforward {background-image: url(controlbuttonskipforward.png); background-repeat: no-repeat; width: 28px; height: 28px;}
+#controlbuttonstep {background-image: url(controlbuttonstep.png); background-repeat: no-repeat; width: 31px; height: 28px;}
+#controlvolumemute {background-image: url(controlvolumeon.png); background-repeat: no-repeat; width: 28px; height: 28px;}
+#controlvolumebar {background-image: url(controlvolumebar.png); background-repeat: no-repeat; width: 55px; height: 28px;}
+#seekbar {background-image: url(seekbarmid.png); background-repeat: repeat-x;}
+#seekbar td {height: 15px;}
+#center {width: 100%;}
+#leftside {background-image: url(leftside.png); background-repeat: repeat-y; width: 4px;}
+#rightside {background-image: url(rightside.png); background-repeat: repeat-y; width: 4px;}
+#leftbottomside {background-image: url(leftbottomside.png); background-repeat: repeat-x; width: 4px; height: 4px;}
+#bottomside {background-image: url(bottomside.png); background-repeat: repeat-x; height: 4px;}
+#rightbottomside {background-image: url(rightbottomside.png); background-repeat: repeat-x; width: 4px; height: 4px;}
+</style>
+
+</head>
+
+<body onload="Init()">
+
+ <div align="center">
+ <table id="player" cellpadding="0" cellspacing="0">
+ <tr>
+ <td colspan="3">
+ <table id="header" cellpadding="0" cellspacing="0">
+ <tr>
+ <td id="headericon"></td>
+ <td id="headerback"><nobr>&nbsp;<div id="title"></div>&nbsp;</nobr></td>
+ <td id="headerclose" onclick="OnCommand(816)"></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td id="leftside"></td>
+ <td>
+ <table cellpadding="0" cellspacing="0" id="center">
+ <tr>
+ <td>
+ <table id="menu" width="100%">
+ <tr>
+ <td>File</td>
+ <td>View</td>
+ <td>Play</td>
+ <td>Navigate</td>
+ <td>Favorites</td>
+ <td width="100%" align="right">Help</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td id="video" align="center" onclick="OnCommand(889)">
+ <img src="snapshot.png" alt="snapshot" id="snapshot" onload="OnLoadSnapShot()" onabort="OnAbortErrorSnapShot()" onerror="OnAbortErrorSnapShot()" />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table width="100%" id="seekbar" cellpadding="0" cellspacing="0">
+ <tr>
+ <td id="seekbarleft"><img src="seekbarleft.png"></td>
+ <td id="seekbarchleft" width="0%"></td>
+ <td id="seekbargrip"><img src="seekbargrip.png"></td>
+ <td id="seekbarchright" width="100%"></td>
+ <td id="seekbarright"><img src="seekbarright.png"></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table width="100%" cellpadding="0" cellspacing="0" id="controlbar">
+ <tr>
+ <td id="controlbuttonplay" onclick="OnCommand(887)"></td>
+ <td id="controlbuttonpause" onclick="OnCommand(888)"></td>
+ <td id="controlbuttonstop" onclick="OnCommand(890)"></td>
+ <td id="controlbuttonskipback" onclick="OnCommand(920)"></td>
+ <td id="controlbuttondecrate" onclick="OnCommand(894)"></td>
+ <td id="controlbuttonincrate" onclick="OnCommand(895)"></td>
+ <td id="controlbuttonskipforward" onclick="OnCommand(921)"></td>
+ <td id="controlbuttonstep" onclick="OnCommand(891)"></td>
+ <td>&nbsp;</td>
+ <td id="controlvolumemute" onclick="OnCommand(909)"></td>
+ <td id="controlvolumebar" valign="top"><img src="controlvolumegrip.png" id="controlvolumegrip"></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table width="100%" id="statusbar">
+ <tr>
+ <td><div id="status"></div></td>
+ <td align="right"><div id="timer">&nbsp;</div></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td id="rightside"></td>
+ </tr>
+ <tr>
+ <td id="leftbottomside"></td>
+ <td id="bottomside"></td>
+ <td id="rightbottomside"></td>
+ </tr>
+ </table>
+ </div>
+</body>
+
+</html> \ No newline at end of file
diff --git a/src/apps/mplayerc/res/web/rightbottomside.png b/src/apps/mplayerc/res/web/rightbottomside.png
new file mode 100644
index 000000000..ee3241c5f
--- /dev/null
+++ b/src/apps/mplayerc/res/web/rightbottomside.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/rightside.png b/src/apps/mplayerc/res/web/rightside.png
new file mode 100644
index 000000000..a38d53978
--- /dev/null
+++ b/src/apps/mplayerc/res/web/rightside.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/seekbargrip.png b/src/apps/mplayerc/res/web/seekbargrip.png
new file mode 100644
index 000000000..afb032748
--- /dev/null
+++ b/src/apps/mplayerc/res/web/seekbargrip.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/seekbarleft.png b/src/apps/mplayerc/res/web/seekbarleft.png
new file mode 100644
index 000000000..880e254a3
--- /dev/null
+++ b/src/apps/mplayerc/res/web/seekbarleft.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/seekbarmid.png b/src/apps/mplayerc/res/web/seekbarmid.png
new file mode 100644
index 000000000..f93e037f0
--- /dev/null
+++ b/src/apps/mplayerc/res/web/seekbarmid.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/seekbarright.png b/src/apps/mplayerc/res/web/seekbarright.png
new file mode 100644
index 000000000..f411c42d2
--- /dev/null
+++ b/src/apps/mplayerc/res/web/seekbarright.png
Binary files differ
diff --git a/src/apps/mplayerc/res/web/sliderback.gif b/src/apps/mplayerc/res/web/sliderback.gif
new file mode 100644
index 000000000..d4e5cd6f9
--- /dev/null
+++ b/src/apps/mplayerc/res/web/sliderback.gif
Binary files differ
diff --git a/src/apps/mplayerc/res/web/sliderbar.gif b/src/apps/mplayerc/res/web/sliderbar.gif
new file mode 100644
index 000000000..0d05c58c2
--- /dev/null
+++ b/src/apps/mplayerc/res/web/sliderbar.gif
Binary files differ
diff --git a/src/apps/mplayerc/res/web/slidergrip.gif b/src/apps/mplayerc/res/web/slidergrip.gif
new file mode 100644
index 000000000..15002f09b
--- /dev/null
+++ b/src/apps/mplayerc/res/web/slidergrip.gif
Binary files differ
diff --git a/src/apps/mplayerc/res/web/vbg.GIF b/src/apps/mplayerc/res/web/vbg.GIF
new file mode 100644
index 000000000..5247809ca
--- /dev/null
+++ b/src/apps/mplayerc/res/web/vbg.GIF
Binary files differ
diff --git a/src/apps/mplayerc/res/web/vbs.GIF b/src/apps/mplayerc/res/web/vbs.GIF
new file mode 100644
index 000000000..fac72a07d
--- /dev/null
+++ b/src/apps/mplayerc/res/web/vbs.GIF
Binary files differ
diff --git a/src/apps/mplayerc/resource.h b/src/apps/mplayerc/resource.h
new file mode 100644
index 000000000..b14fa16ce
--- /dev/null
+++ b/src/apps/mplayerc/resource.h
@@ -0,0 +1,758 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by mplayerc.rc
+//
+#define IDR_MAINFRAME 128
+#define IDR_POPUP 129
+#define IDS_STRING129 129
+#define IDS_RS_DVDPOS 129
+#define IDR_POPUPMAIN 130
+#define IDS_RS_FILEPOS 130
+#define IDS_RS_LASTFULLSCREEN 131
+#define IDB_PLAYERTOOLBAR 201
+#define IDB_NOAUDIO 202
+#define IDB_MONO 203
+#define IDB_STEREO 204
+#define IDB_ONOFF 205
+#define IDB_LOGO0 206
+#define IDB_LOGO1 207
+#define IDB_LOGO2 208
+#define IDB_LOGO3 209
+#define IDB_LOGO4 210
+#define IDB_LOGO5 211
+#define IDB_LOGO6 212
+#define IDB_LOGO7 213
+#define IDB_AUTHHDRPIC 214
+#define IDB_STREAMTYPES 215
+#define IDI_SINGLE 300
+#define IDI_MULTI 301
+#define IDI_DVD 302
+#define IDI_AUDIOCD 303
+#define IDI_UNKNOWN 304
+#define IDR_AVI_FILECOPY 400
+#define IDR_HTML_INDEX 500
+#define IDR_HTML_404 501
+#define IDR_HTML_BROWSER 502
+#define IDR_HTML_CONTROLS 503
+#define IDR_HTML_PLAYER 504
+#define IDF_DEFAULT_CSS 505
+#define IDF_SLIDERBAR_GIF 506
+#define IDF_VBR_GIF 507
+#define IDF_VBS_GIF 508
+#define IDF_SLIDERGRIP_GIF 509
+#define IDF_1PIX_GIF 510
+#define IDF_SLIDERBACK_GIF 511
+#define IDF_HEADERICON_PNG 512
+#define IDF_HEADERBACK_PNG 513
+#define IDF_HEADERCLOSE_PNG 514
+#define IDF_LEFTSIDE_PNG 515
+#define IDF_RIGHTSIDE_PNG 516
+#define IDF_BOTTOMSIDE_PNG 517
+#define IDF_LEFTBOTTOMSIDE_PNG 518
+#define IDF_RIGHTBOTTOMSIDE_PNG 519
+#define IDF_SEEKBARLEFT_PNG 520
+#define IDF_SEEKBARMID_PNG 521
+#define IDF_SEEKBARRIGHT_PNG 522
+#define IDF_SEEKBARGRIP_PNG 523
+#define IDF_LOGO_PNG 524
+#define IDF_CONTROLBACK_PNG 525
+#define IDF_CONTROLBUTTONPLAY_PNG 526
+#define IDF_CONTROLBUTTONPAUSE_PNG 527
+#define IDF_CONTROLBUTTONSTOP_PNG 528
+#define IDF_CONTROLBUTTONSKIPBACK_PNG 529
+#define IDF_CONTROLBUTTONDECRATE_PNG 530
+#define IDF_CONTROLBUTTONINCRATE_PNG 531
+#define IDF_CONTROLBUTTONSKIPFORWARD_PNG 532
+#define IDF_CONTROLBUTTONSTEP_PNG 533
+#define IDF_CONTROLVOLUMEON_PNG 534
+#define IDF_CONTROLVOLUMEOFF_PNG 535
+#define IDF_CONTROLVOLUMEBAR_PNG 536
+#define IDF_CONTROLVOLUMEGRIP_PNG 537
+#define IDF_SHADER_RESIZER 700
+#define IDF_SHADER_EMPTY 701
+#define IDF_SHADER_CONTOUR 702
+#define IDF_SHADER_DEINTERLACE 703
+#define IDF_SHADER_EMBOSS 704
+#define IDF_SHADER_GRAYSCALE 705
+#define IDF_SHADER_INVERT 706
+#define IDF_SHADER_LETTERBOX 707
+#define IDF_SHADER_SHARPEN 708
+#define IDF_SHADER_SPHERE 709
+#define IDF_SHADER_SPOTLIGHT 710
+#define IDF_SHADER_WAVE 711
+#define IDF_SHADER_PROCAMP 712
+#define ID_FILE_OPENMEDIA 800
+#define ID_FILE_OPENDVD 801
+#define ID_FILE_OPENDEVICE 802
+#define ID_FILE_CLOSEMEDIA 803
+#define ID_FILE_CLOSEPLAYLIST 804
+#define ID_FILE_SAVE_COPY 805
+#define ID_FILE_SAVE_IMAGE 806
+#define ID_FILE_SAVE_IMAGE_AUTO 807
+#define ID_FILE_SAVE_THUMBNAILS 808
+#define ID_FILE_LOAD_SUBTITLE 809
+#define ID_FILE_SAVE_SUBTITLE 810
+#define ID_FILE_ISDB_UPLOAD 811
+#define ID_FILE_ISDB_DOWNLOAD 812
+#define ID_FILE_ISDB_SEARCH 813
+#define ID_FILE_PROPERTIES 814
+#define ID_FILE_CONVERT 815
+#define ID_FILE_EXIT 816
+#define ID_VIEW_CAPTIONMENU 817
+#define ID_VIEW_SEEKER 818
+#define ID_VIEW_CONTROLS 819
+#define ID_VIEW_INFORMATION 820
+#define ID_VIEW_STATISTICS 821
+#define ID_VIEW_STATUS 822
+#define ID_VIEW_SUBRESYNC 823
+#define ID_VIEW_PLAYLIST 824
+#define ID_VIEW_CAPTURE 825
+#define ID_VIEW_SHADEREDITOR 826
+#define ID_VIEW_PRESETS_MINIMAL 827
+#define ID_VIEW_PRESETS_COMPACT 828
+#define ID_VIEW_PRESETS_NORMAL 829
+#define ID_VIEW_FULLSCREEN 830
+#define ID_VIEW_FULLSCREEN_SECONDARY 831
+#define ID_VIEW_ZOOM_50 832
+#define ID_VIEW_ZOOM_100 833
+#define ID_VIEW_ZOOM_200 834
+#define ID_VIEW_VF_HALF 835
+#define ID_VIEW_VF_NORMAL 836
+#define ID_VIEW_VF_DOUBLE 837
+#define ID_VIEW_VF_STRETCH 838
+#define ID_VIEW_VF_FROMINSIDE 839
+#define ID_VIEW_VF_FROMOUTSIDE 840
+#define ID_VIEW_VF_KEEPASPECTRATIO 841
+#define ID_VIEW_VF_COMPMONDESKARDIFF 842
+#define ID_ASPECTRATIO_START 850
+#define ID_ASPECTRATIO_SOURCE 850
+#define ID_ASPECTRATIO_4_3 851
+#define ID_ASPECTRATIO_5_4 852
+#define ID_ASPECTRATIO_16_9 853
+#define ID_ASPECTRATIO_END 859
+#define ID_ASPECTRATIO_NEXT 860
+#define ID_VIEW_RESET 861
+#define ID_VIEW_INCSIZE 862
+#define ID_VIEW_DECSIZE 863
+#define ID_VIEW_INCWIDTH 864
+#define ID_VIEW_DECWIDTH 865
+#define ID_VIEW_INCHEIGHT 866
+#define ID_VIEW_DECHEIGHT 867
+#define ID_PANSCAN_MOVELEFT 868
+#define ID_PANSCAN_MOVERIGHT 869
+#define ID_PANSCAN_MOVEUP 870
+#define ID_PANSCAN_MOVEDOWN 871
+#define ID_PANSCAN_MOVEUPLEFT 872
+#define ID_PANSCAN_MOVEUPRIGHT 873
+#define ID_PANSCAN_MOVEDOWNLEFT 874
+#define ID_PANSCAN_MOVEDOWNRIGHT 875
+#define ID_PANSCAN_CENTER 876
+#define ID_PANSCAN_ROTATEXP 877
+#define ID_PANSCAN_ROTATEXM 878
+#define ID_PANSCAN_ROTATEYP 879
+#define ID_PANSCAN_ROTATEYM 880
+#define ID_PANSCAN_ROTATEZP 881
+#define ID_PANSCAN_ROTATEZM 882
+#define ID_ONTOP_NEVER 883
+#define ID_ONTOP_ALWAYS 884
+#define ID_ONTOP_WHILEPLAYING 885
+#define ID_VIEW_OPTIONS 886
+#define ID_PLAY_PLAY 887
+#define ID_PLAY_PAUSE 888
+#define ID_PLAY_PLAYPAUSE 889
+#define ID_PLAY_STOP 890
+#define ID_PLAY_FRAMESTEP 891
+#define ID_PLAY_FRAMESTEPCANCEL 892
+#define ID_PLAY_GOTO 893
+#define ID_PLAY_DECRATE 894
+#define ID_PLAY_INCRATE 895
+#define ID_PLAY_RESETRATE 896
+#define ID_PLAY_SEEKKEYBACKWARD 897
+#define ID_PLAY_SEEKKEYFORWARD 898
+#define ID_PLAY_SEEKBACKWARDSMALL 899
+#define ID_PLAY_SEEKFORWARDSMALL 900
+#define ID_PLAY_SEEKBACKWARDMED 901
+#define ID_PLAY_SEEKFORWARDMED 902
+#define ID_PLAY_SEEKBACKWARDLARGE 903
+#define ID_PLAY_SEEKFORWARDLARGE 904
+#define ID_PLAY_INCAUDDELAY 905
+#define ID_PLAY_DECAUDDELAY 906
+#define ID_VOLUME_UP 907
+#define ID_VOLUME_DOWN 908
+#define ID_VOLUME_MUTE 909
+#define ID_VOLUME_MUTE_ON 910
+#define ID_VOLUME_MUTE_DISABLED 911
+#define ID_AFTERPLAYBACK_CLOSE 912
+#define ID_AFTERPLAYBACK_STANDBY 913
+#define ID_AFTERPLAYBACK_HIBERNATE 914
+#define ID_AFTERPLAYBACK_SHUTDOWN 915
+#define ID_AFTERPLAYBACK_LOGOFF 916
+#define ID_AFTERPLAYBACK_DONOTHING 917
+#define ID_NAVIGATE_SKIPBACKPLITEM 918
+#define ID_NAVIGATE_SKIPFORWARDPLITEM 919
+#define ID_NAVIGATE_SKIPBACK 920
+#define ID_NAVIGATE_SKIPFORWARD 921
+#define ID_NAVIGATE_TITLEMENU 922
+#define ID_NAVIGATE_ROOTMENU 923
+#define ID_NAVIGATE_SUBPICTUREMENU 924
+#define ID_NAVIGATE_AUDIOMENU 925
+#define ID_NAVIGATE_ANGLEMENU 926
+#define ID_NAVIGATE_CHAPTERMENU 927
+#define ID_NAVIGATE_MENU_LEFT 928
+#define ID_NAVIGATE_MENU_RIGHT 929
+#define ID_NAVIGATE_MENU_UP 930
+#define ID_NAVIGATE_MENU_DOWN 931
+#define ID_NAVIGATE_MENU_ACTIVATE 932
+#define ID_NAVIGATE_MENU_BACK 933
+#define ID_NAVIGATE_MENU_LEAVE 934
+#define ID_FAVORITES 935
+#define ID_FAVORITES_ORGANIZE 936
+#define ID_FAVORITES_ADD 937
+#define ID_HELP_HOMEPAGE 938
+#define ID_HELP_DOCUMENTATION 939
+#define ID_HELP_SHOWCOMMANDLINESWITCHES 940
+#define ID_HELP_DONATE 941
+#define ID_HELP_ABOUT 942
+#define ID_BOSS 943
+#define ID_DUMMYSEPARATOR 944
+#define ID_BUTTONSEP 945
+#define ID_FILE_POST_OPENMEDIA 946
+#define ID_FILE_POST_CLOSEMEDIA 947
+#define ID_MENU_PLAYER_SHORT 948
+#define ID_MENU_PLAYER_LONG 949
+#define ID_MENU_FILTERS 950
+#define ID_STREAM_AUDIO_NEXT 951
+#define ID_STREAM_AUDIO_PREV 952
+#define ID_STREAM_SUB_NEXT 953
+#define ID_STREAM_SUB_PREV 954
+#define ID_STREAM_SUB_ONOFF 955
+#define ID_OGM_AUDIO_NEXT 956
+#define ID_OGM_AUDIO_PREV 957
+#define ID_OGM_SUB_NEXT 958
+#define ID_OGM_SUB_PREV 959
+#define ID_DVD_ANGLE_NEXT 960
+#define ID_DVD_ANGLE_PREV 961
+#define ID_DVD_AUDIO_NEXT 962
+#define ID_DVD_AUDIO_PREV 963
+#define ID_DVD_SUB_NEXT 964
+#define ID_DVD_SUB_PREV 965
+#define ID_DVD_SUB_ONOFF 966
+#define ID_VIEW_ZOOM_AUTOFIT 967
+#define ID_FILE_OPENQUICK 968
+#define ID_VOLUME_BOOST_INC 969
+#define ID_VOLUME_BOOST_DEC 970
+#define ID_VOLUME_BOOST_MIN 971
+#define ID_VOLUME_BOOST_MAX 972
+#define ID_FILTERS_SUBITEM_START 2000
+#define ID_FILTERS_SUBITEM_END 2099
+#define ID_FILTERSTREAMS_SUBITEM_START 2100
+#define ID_FILTERSTREAMS_SUBITEM_END 2199
+#define ID_AUDIO_SUBITEM_START 2200
+#define ID_AUDIO_SUBITEM_END 2299
+#define ID_SUBTITLES_SUBITEM_START 2300
+#define ID_SUBTITLES_SUBITEM_END 2399
+#define ID_NAVIGATE_CHAP_SUBITEM_START 2400
+#define ID_NAVIGATE_CHAP_SUBITEM_END 2499
+#define ID_NAVIGATE_AUDIO_SUBITEM_START 2500
+#define ID_NAVIGATE_AUDIO_SUBITEM_END 2599
+#define ID_NAVIGATE_SUBP_SUBITEM_START 2600
+#define ID_NAVIGATE_SUBP_SUBITEM_END 2699
+#define ID_NAVIGATE_ANGLE_SUBITEM_START 2700
+#define ID_NAVIGATE_ANGLE_SUBITEM_END 2799
+#define ID_FAVORITES_FILE_START 2800
+#define ID_FAVORITES_FILE_END 3799
+#define ID_FAVORITES_DVD_START 3800
+#define ID_FAVORITES_DVD_END 3899
+#define ID_FAVORITES_DEVICE_START 3900
+#define ID_FAVORITES_DEVICE_END 3999
+#define ID_FILE_OPEN_CD_START 4000
+#define ID_FILE_OPEN_CD_END 4099
+#define ID_PANNSCAN_PRESETS_START 4100
+#define ID_PANNSCAN_PRESETS_END 4199
+#define ID_SHADERS_START 4200
+#define ID_SHADERS_END 4299
+#define IDD_OPEN_DLG 10000
+#define IDD_OPENCAPDEVICE_DLG 10001
+#define IDD_MEDIATYPES_DLG 10002
+#define IDD_AUTH_DLG 10003
+#define IDD_SAVE_DLG 10004
+#define IDD_SUBTITLEDL_DLG 10005
+#define IDD_CONVERT_DLG 10006
+#define IDD_CONVERTPROPS_DLG 10007
+#define IDD_CONVERTRES_DLG 10008
+#define IDD_CONVERTCHAP_DLG 10009
+#define IDD_FILEPROPDETAILS 10010
+#define IDD_FILEPROPCLIP 10011
+#define IDD_SHADEREDITOR_DLG 10012
+#define IDD_SHADERAUTOCOMPLETE_DLG 10013
+#define IDD_SHADERCOMBINE_DLG 10014
+#define IDD_PNSPRESET_DLG 10015
+#define IDD_GOTO_DLG 10016
+#define IDD_FAVADD 10017
+#define IDD_FAVORGANIZE 10018
+#define IDD_ABOUTBOX 10019
+#define IDD_PLAYERINFOBAR 10020
+#define IDD_PLAYERSTATUSBAR 10021
+#define IDD_PLAYERSEEKBAR 10022
+#define IDD_PPAGEPLAYBACK 10023
+#define IDD_PPAGEPLAYER 10024
+#define IDD_PPAGEDVD 10025
+#define IDD_PPAGESUBTITLES 10026
+#define IDD_PPAGEFORMATS 10027
+#define IDD_PPAGETWEAKS 10028
+#define IDD_PPAGEAUDIOSWITCHER 10029
+#define IDD_PPAGEEXTERNALFILTERS 10030
+#define IDD_PPAGEACCELTBL 10032
+#define IDD_PPAGESUBSTYLE 10033
+#define IDD_PPAGEMOUSE 10034
+#define IDD_PPAGEINTERNALFILTERS 10036
+#define IDD_PPAGELOGO 10037
+#define IDD_PPAGEVIDREND 10038
+#define IDD_PPAGEOUTPUT 10039
+#define IDD_PPAGEWEBSERVER 10040
+#define IDD_PPAGEAUDIODEC 10041
+#define IDD_PPAGESUBDB 10042
+#define IDD_SAVETEXTFILEDIALOGTEMPL 10043
+#define IDD_SAVETEXTFILEDIALOGTEMPL_400 10044
+#define IDD_CAPTURE_DLG 10045
+#define IDD_ADDREGFILTER 10046
+#define IDD_SELECTMEDIATYPE 10047
+#define IDD_COMPROPERTYPAGE 10048
+#define IDD_FILEPROPRES 10049
+#define IDD_SAVETHUMBSDIALOGTEMPL 10050
+#define IDD_SAVETHUMBSDIALOGTEMPL_400 10051
+#define IDD_PPAGECASIMIR 10052
+#define IDC_COMBO1 11000
+#define IDC_COMBO2 11001
+#define IDC_COMBO3 11002
+#define IDC_COMBO4 11003
+#define IDC_COMBO5 11004
+#define IDC_COMBO6 11005
+#define IDC_COMBO7 11006
+#define IDC_COMBO8 11007
+#define IDC_COMBO9 11008
+#define IDC_COMBO10 11009
+#define IDC_COMBO11 11010
+#define IDC_COMBO12 11011
+#define IDC_COMBO13 11012
+#define IDC_COMBO14 11013
+#define IDC_SLIDER1 11020
+#define IDC_SLIDER2 11021
+#define IDC_SLIDER3 11022
+#define IDC_SLIDER4 11023
+#define IDC_SLI_BRIGHTNESS 11025
+#define IDC_SLI_HUE 11026
+#define IDC_SLI_SATURATION 11027
+#define IDC_RADIO1 11040
+#define IDC_RADIO2 11041
+#define IDC_RADIO3 11042
+#define IDC_RADIO4 11043
+#define IDC_RADIO5 11044
+#define IDC_RADIO6 11045
+#define IDC_RADIO7 11046
+#define IDC_RADIO8 11047
+#define IDC_RADIO9 11048
+#define IDC_RADIO10 11049
+#define IDC_RADIO11 11050
+#define IDC_EDIT1 11060
+#define IDC_EDIT3 11061
+#define IDC_EDIT2 11062
+#define IDC_EDIT4 11063
+#define IDC_EDIT5 11064
+#define IDC_EDIT6 11065
+#define IDC_EDIT7 11066
+#define IDC_EDIT8 11067
+#define IDC_EDIT9 11068
+#define IDC_EDIT10 11069
+#define IDC_CHECK1 11080
+#define IDC_CHECK2 11081
+#define IDC_CHECK3 11082
+#define IDC_CHECK4 11083
+#define IDC_CHECK5 11084
+#define IDC_CHECK6 11085
+#define IDC_CHECK7 11086
+#define IDC_CHECK8 11087
+#define IDC_CHECK9 11088
+#define IDC_CHECK10 11089
+#define IDC_CHECK11 11090
+#define IDC_CHECK12 11091
+#define IDC_CHECK13 11092
+#define IDC_SPIN1 11100
+#define IDC_SPIN2 11101
+#define IDC_SPIN3 11102
+#define IDC_SPIN4 11103
+#define IDC_SPIN5 11104
+#define IDC_SPIN6 11105
+#define IDC_SPIN7 11106
+#define IDC_SPIN8 11107
+#define IDC_SPIN9 11108
+#define IDC_SPIN10 11109
+#define IDC_BUTTON1 11120
+#define IDC_BUTTON2 11121
+#define IDC_BUTTON3 11122
+#define IDC_BUTTON4 11123
+#define IDC_BUTTON5 11124
+#define IDC_BUTTON6 11125
+#define IDC_BUTTON7 11126
+#define IDC_BUTTON8 11127
+#define IDC_TREE1 11140
+#define IDC_TREE2 11141
+#define IDC_LIST1 11160
+#define IDC_LIST2 11180
+#define IDC_TAB1 11200
+#define IDC_ANIMATE1 11220
+#define IDC_PROGRESS1 11240
+#define IDC_STATIC1 11260
+#define IDC_STATIC2 11261
+#define IDC_STATIC3 11262
+#define IDC_STATIC4 11263
+#define IDC_DVDPATH 12000
+#define IDC_SUBRESYNCLIST 12001
+#define IDC_PLAYLIST 12002
+#define IDC_COLORPRI 12003
+#define IDC_COLORSEC 12004
+#define IDC_COLOROUTL 12005
+#define IDC_COLORSHAD 12006
+#define IDC_STATICLINK 12007
+#define IDC_STATICLINK2 12008
+#define IDC_DEFAULTICON 12009
+#define IDC_PLACEHOLDER 12010
+#define IDC_REPORT 12011
+#define IDC_FROMTO 12012
+#define IDC_TYPE 12013
+#define IDC_LOGOPREVIEW 12014
+#define IDC_LOGONAME 12015
+#define IDC_LOGOFILENAME 12016
+#define IDC_DESC 12017
+#define IDC_AUTHOR 12018
+#define IDC_CHECK_RELATIVETO 12019
+#define IDC_CHECK_SPCPOW2TEX 12020
+#define IDC_HLINE 12021
+#define IDC_STATICLINKGTS 12022
+#define IDC_BUTTON_EXT_SET 12023
+#define IDC_OK1 12024
+#define IDC_OK2 12025
+#define IDC_PLAYERSTATUS 12026
+#define IDC_PLAYERTIME 12027
+#define IDC_DSSYSDEF 12100
+#define IDC_DSOLD 12101
+#define IDC_DSOVERLAYMIXER 12102
+#define IDC_DSVMR7WIN 12103
+#define IDC_DSVMR9WIN 12104
+#define IDC_DSVMR7REN 12105
+#define IDC_DSVMR9REN 12106
+#define IDC_DSDXR 12107
+#define IDC_DSNULL_COMP 12108
+#define IDC_DSNULL_UNCOMP 12109
+#define IDC_RMSYSDEF 12120
+#define IDC_RMDX7 12121
+#define IDC_RMDX9 12122
+#define IDC_QTSYSDEF 12123
+#define IDC_QTDX7 12124
+#define IDC_QTDX9 12125
+#define IDC_REULARSURF 12126
+#define IDC_REGULARSURF 12127
+#define IDC_TEXTURESURF2D 12128
+#define IDC_TEXTURESURF3D 12129
+#define IDC_DX9RESIZER_COMBO 12130
+#define IDC_DSVMR9LOADMIXER 12131
+#define IDC_CHECK_MPEGINTERLACED 12132
+#define IDC_DSVMR9YUVMIXER 12132
+#define IDS_R_SETTINGS 13000
+#define IDS_RS_TITLEBARTEXTSTYLE 13001
+#define IDS_RS_USEWMASFREADER 13002
+#define IDS_RS_CONTROLSTATE 13003
+#define IDS_RS_VOLUME 13004
+#define IDS_RS_MUTE 13005
+#define IDS_RS_BALANCE 13006
+#define IDS_RS_LOOP 13007
+#define IDS_RS_LOOPNUM 13008
+#define IDS_RS_REWIND 13009
+#define IDS_RS_ZOOM 13010
+#define IDS_RS_HWACCEL 13011
+#define IDS_RS_MULTIINST 13012
+#define IDS_RS_ALWAYSONTOP 13013
+#define IDS_RS_AUTOZOOM 13014
+#define IDS_RS_FULLSCREENCTRLS 13015
+#define IDS_RS_FULLSCREENCTRLSTIMEOUT 13016
+#define IDS_RS_VMRFLIP 13017
+#define IDS_RS_DVDPATH 13018
+#define IDS_RS_USEDVDPATH 13019
+#define IDS_RS_MENULANG 13020
+#define IDS_RS_AUDIOLANG 13021
+#define IDS_RS_SUBTITLESLANG 13022
+#define IDS_RS_SPLOGFONT 13023
+#define IDS_RS_SPOUTLINE 13024
+#define IDS_RS_SPSHADOW 13025
+#define IDS_RS_SPSFGCOLOR 13026
+#define IDS_RS_SPOVERRIDEPLACEMENT 13027
+#define IDS_RS_SPHORPOS 13028
+#define IDS_RS_SPVERPOS 13029
+#define IDS_RS_SPCSIZE 13030
+#define IDS_RS_SPC16BPP 13031
+#define IDS_RS_SPCMAXRES 13032
+#define IDS_RS_SPCCOMPRESS 13033
+#define IDS_RS_INTREALMEDIA 13034
+#define IDS_RS_FAVORWAVEOUT 13035
+#define IDS_RS_DISABLEXPTOOLBARS 13036
+#define IDS_RS_USEDEDYNAMIC 13037
+#define IDS_RS_DBLCLICKFULLSCREEN 13038
+#define IDS_RS_EXITFULLSCREENATTHEEND 13039
+#define IDS_RS_AUTOSPEAKERCONF 13040
+#define IDS_RS_REMEMBERWINDOWPOS 13041
+#define IDS_RS_LASTWINDOWRECT 13042
+#define IDS_RS_AUDIORENDERERTYPE 13043
+#define IDS_RS_SPEAKERTOCHANNELMAPPING 13044
+#define IDS_RS_CUSTOMCHANNELMAPPING 13045
+#define IDS_RS_DOWNSAMPLETO441 13046
+#define IDS_RS_ENABLEAUDIOSWITCHER 13047
+#define IDS_RS_HIDECAPTIONMENU 13048
+#define IDS_R_FILTERS 13049
+#define IDS_RS_DEFAULTVIDEOFRAME 13050
+#define IDS_RS_REMEMBERWINDOWSIZE 13051
+#define IDS_RS_REALMEDIARENDERLESS 13052
+#define IDS_RS_QUICKTIMERENDERER 13053
+#define IDS_RS_REALMEDIAFPS 13054
+#define IDS_RS_AUDIOTIMESHIFT 13055
+#define IDS_RS_ENABLEAUDIOTIMESHIFT 13056
+#define IDS_R_FAVFILES 13057
+#define IDS_R_FAVDVDS 13058
+#define IDS_R_FAVDEVICES 13059
+#define IDS_RS_LOGOFILE 13060
+#define IDS_RS_ENABLEWORKERTHREADFOROPENING 13061
+#define IDS_RS_PNSPRESETS 13062
+#define IDS_RS_AUTOLOADAUDIO 13063
+#define IDS_RS_AUTOLOADSUBTITLES 13064
+#define IDS_RS_SEARCHKEYFRAMES 13065
+#define IDS_RS_ACCELTBL 13066
+#define IDS_RS_SETFULLSCREENRES 13067
+#define IDS_RS_FULLSCREENRES 13068
+#define IDS_RS_WINLIRCADDR 13069
+#define IDS_R_COMMANDS 13070
+#define IDS_RS_WINLIRC 13071
+#define IDS_RS_TRAYICON 13072
+#define IDS_RS_KEEPASPECTRATIO 13073
+#define IDS_RS_UICEADDR 13074
+#define IDS_RS_UICE 13075
+#define IDS_RS_JUMPDISTS 13076
+#define IDS_RS_JUMPDISTM 13077
+#define IDS_RS_JUMPDISTL 13078
+#define IDS_RS_REPORTFAILEDPINS 13079
+#define IDS_RS_SRCFILTERS 13080
+#define IDS_RS_KEEPHISTORY 13081
+#define IDS_RS_LOGOID 13082
+#define IDS_RS_LOGOEXT 13083
+#define IDS_RS_TRAFILTERS 13084
+#define IDS_RS_MPEGDI 13085
+#define IDS_RS_MPEGBRIGHT 13086
+#define IDS_RS_MPEGCONT 13087
+#define IDS_RS_MPEGHUE 13088
+#define IDS_RS_MPEGSAT 13089
+#define IDS_RS_MPEGFORCEDSUBS 13090
+#define IDS_RS_MPEGPLANARYUV 13091
+#define IDS_RS_COMPMONDESKARDIFF 13092
+#define IDS_RS_HIDECDROMSSUBMENU 13093
+#define IDS_RS_VMRTEXTURE 13094
+#define IDS_RS_VMR3D 13095
+#define IDS_RS_DSVIDEORENDERERTYPE 13096
+#define IDS_RS_RMVIDEORENDERERTYPE 13097
+#define IDS_RS_QTVIDEORENDERERTYPE 13098
+#define IDS_RS_APSURACEFUSAGE 13099
+#define IDS_R_LOGINS 13100
+#define IDS_RS_ENABLEWEBSERVER 13101
+#define IDS_RS_WEBSERVERPORT 13102
+#define IDS_RS_LASTWINDOWTYPE 13103
+#define IDS_RS_ONTOP 13104
+#define IDS_RS_MPASF 13105
+#define IDS_RS_AC3SC 13106
+#define IDS_RS_AC3DRC 13107
+#define IDS_RS_WEBSERVERPRINTDEBUGINFO 13108
+#define IDS_RS_WEBSERVERUSECOMPRESSION 13109
+#define IDS_RS_MPANORMALIZE 13110
+#define IDS_RS_DTSSC 13111
+#define IDS_RS_DTSDRC 13112
+#define IDS_RS_SNAPSHOTPATH 13113
+#define IDS_RS_PRIORITY 13114
+#define IDS_RS_SNAPSHOTEXT 13115
+#define IDS_RS_LAUNCHFULLSCREEN 13116
+#define IDS_RS_MPABOOST 13117
+#define IDS_RS_AACSC 13118
+#define IDS_RS_VMRSYNCFIX 13119
+#define IDS_RS_ISDB 13120
+#define IDS_RS_POW2TEX 13121
+#define IDS_R_INTERNAL_FILTERS 13122
+#define IDS_RS_WEBROOT 13123
+#define IDS_RS_WEBSERVERLOCALHOSTONLY 13124
+#define IDS_RS_ASPECTRATIO_X 13125
+#define IDS_RS_ASPECTRATIO_Y 13126
+#define IDS_RS_DX9_RESIZER 13127
+#define IDS_RS_WEBSERVERCGI 13128
+#define IDS_RS_WEBDEFINDEX 13129
+#define IDS_RS_FREEWINDOWRESIZING 13130
+#define IDS_RS_NOTIFYMSN 13131
+#define IDS_RS_NOTIFYGTSDLL 13132
+#define IDS_RS_VMR9MIXERMODE 13133
+#define IDS_RS_THUMBROWS 13134
+#define IDS_RS_THUMBCOLS 13135
+#define IDS_RS_SNAPTODESKTOPEDGES 13136
+#define IDS_RS_ENABLESUBTITLES 13137
+#define IDS_RS_MPEGINTERLACED 13138
+#define IDS_RS_THUMBWIDTH 13139
+#define IDS_RS_AUDIONORMALIZE 13140
+#define IDS_RS_AUDIOBOOST 13141
+#define IDS_RS_D3DFULLSCREEN 13142
+#define IDS_RS_MONITOR_AUTOREFRESHRATE 13143
+#define IDS_RS_COLOR_BRIGHTNESS 13144
+#define IDS_RS_COLOR_CONTRAST 13145
+#define IDS_RS_COLOR_HUE 13146
+#define IDS_RS_COLOR_SATURATION 13147
+#define IDS_RS_SHADERLIST 13148
+#define IDS_RS_TITLEBARTEXTTITLE 13149
+#define IDS_RS_VMR9MIXERYUV 13150
+#define IDS_RS_AUDIONORMALIZERECOVER 13151
+#define IDS_SRC_RADGT 14000
+#define IDS_SRC_CDDA 14001
+#define IDS_SRC_AVI 14002
+#define IDS_SRC_CDXA 14003
+#define IDS_SRC_VTS 14004
+#define IDS_SRC_FLIC 14005
+#define IDS_SRC_D2V 14006
+#define IDS_SRC_DTSAC3 14007
+#define IDS_SRC_SHOUTCAST 14008
+#define IDS_SRC_REALMEDIA 14009
+#define IDS_SRC_MATROSKA 14010
+#define IDS_SRC_ROQ 14011
+#define IDS_SRC_OGG 14012
+#define IDS_SRC_NUT 14013
+#define IDS_SRC_DIRAC 14014
+#define IDS_SRC_DSM 14015
+#define IDS_SRC_MPA 14016
+#define IDS_SRC_MP4 14017
+#define IDS_TRA_RV 14018
+#define IDS_TRA_RA 14019
+#define IDS_TRA_MPEG1 14020
+#define IDS_TRA_MPEG2 14021
+#define IDS_TRA_MPA 14022
+#define IDS_TRA_LPCM 14023
+#define IDS_TRA_AC3 14024
+#define IDS_TRA_DTS 14025
+#define IDS_TRA_AAC 14026
+#define IDS_TRA_DIRAC 14027
+#define IDS_TRA_PS2AUD 14028
+#define IDS_VIDRENDDESC 14100
+#define IDS_CONVERT_ADDFILE 14101
+#define IDS_CONVERT_PROPERTIES 14102
+#define IDS_CONVERT_REMOVE 14103
+#define IDS_CONVERT_ENABLESTREAM 14104
+#define IDS_CONVERT_DISABLESTREAM 14105
+#define IDS_CONVERT_PINPROPERTIES 14106
+#define IDS_CONVERT_ADDRESOURCE 14107
+#define IDS_CONVERT_REMOVEALL 14108
+#define IDS_CONVERT_SAVEAS 14109
+#define IDS_CONVERT_RESOURCEPROPERTIES 14110
+#define IDS_CONVERT_LAUNCHINBROWSER 14111
+#define IDS_CONVERT_ADDCHAPTER 14112
+#define IDS_CONVERT_CHAPTERPROPERTIES 14113
+#define IDS_CONVERT_DEMUXSTREAM 14114
+#define IDS_PLAYLIST_OPEN 14115
+#define IDS_PLAYLIST_ADD 14116
+#define IDS_PLAYLIST_REMOVE 14117
+#define IDS_PLAYLIST_COPYTOCLIPBOARD 14118
+#define IDS_PLAYLIST_SAVEAS 14119
+#define IDS_PLAYLIST_SORTBYLABEL 14120
+#define IDS_PLAYLIST_SORTBYPATH 14121
+#define IDS_PLAYLIST_RANDOMIZE 14122
+#define IDS_PLAYLIST_RESTORE 14123
+#define IDS_SUBRESYNC_SEPARATOR 14124
+#define IDS_SUBRESYNC_DELETE 14125
+#define IDS_SUBRESYNC_DUPLICATE 14126
+#define IDS_SUBRESYNC_RESET 14127
+#define IDS_SUBRESYNC_ORIGINAL 14128
+#define IDS_SUBRESYNC_CURRENT 14129
+#define IDS_SUBRESYNC_EDIT 14130
+#define IDS_SUBRESYNC_YES 14131
+#define IDS_SUBRESYNC_NO 14132
+#define IDS_SUBRESYNC_DECREASE 14133
+#define IDS_SUBRESYNC_INCREASE 14134
+#define IDS_OPTIONS_CAPTION 14135
+#define IDS_SHADER_COMBINE 14136
+#define IDS_SHADER_OFF 14137
+#define IDS_SHADER_POPUP 14138
+#define IDS_FAVORITES_POPUP 14139
+#define IDS_JUMPTO_POPUP 14140
+#define IDS_VIDEOANGLE_POPUP 14141
+#define IDS_SUBTITLELANGUAGE_POPUP 14142
+#define IDS_AUDIOLANGUAGE_POPUP 14143
+#define IDS_SUBTITLES_POPUP 14144
+#define IDS_AUDIO_POPUP 14145
+#define IDS_FILTERS_POPUP 14146
+#define IDS_OPENCDROM_POPUP 14147
+#define IDS_NAVIGATE_POPUP 14148
+#define IDS_VIDEOFRAME_POPUP 14149
+#define IDS_PANSCAN_POPUP 14150
+#define IDS_ASPECTRATIO_POPUP 14151
+#define IDS_ZOOM_POPUP 14152
+#define IDS_FAVORITES_ADD 14153
+#define IDS_FAVORITES_ORGANIZE 14154
+#define IDS_PLAYLIST_SHUFFLE 14155
+#define IDS_PLAYLIST_REMEBERITEMS 14156
+#define IDS_CONTROLS_CLOSING 14157
+#define IDS_CONTROLS_PLAYING 14158
+#define IDS_CONTROLS_PAUSED 14159
+#define IDS_CONTROLS_STOPPED 14160
+#define IDS_CONTROLS_BUFFERING 14161
+#define IDS_CONTROLS_CAPTURING 14162
+#define IDS_CONTROLS_OPENING 14163
+#define IDS_CONTROLS_CLOSED 14164
+#define IDS_SUBTITLES_OPTIONS 14165
+#define IDS_SUBTITLES_STYLES 14166
+#define IDS_SUBTITLES_RELOAD 14167
+#define IDS_SUBTITLES_ENABLE 14168
+#define IDS_PANSCAN_EDIT 14169
+#define IDS_INFOBAR_TITLE 14170
+#define IDS_INFOBAR_AUTHOR 14171
+#define IDS_INFOBAR_COPYRIGHT 14172
+#define IDS_INFOBAR_RATING 14173
+#define IDS_INFOBAR_DESCRIPTION 14174
+#define IDS_INFOBAR_DOMAIN 14175
+#define IDS_INFOBAR_LOCATION 14176
+#define IDS_INFOBAR_VIDEO 14177
+#define IDS_INFOBAR_AUDIO 14178
+#define IDS_INFOBAR_SUBTITLES 14179
+#define IDS_CONTROLS_COMPLETING 14180
+#define IDS_AUTOPLAY_PLAYVIDEO 14181
+#define IDS_AUTOPLAY_PLAYMUSIC 14182
+#define IDS_AUTOPLAY_PLAYAUDIOCD 14183
+#define IDS_AUTOPLAY_PLAYDVDMOVIE 14184
+#define IDS_PROPSHEET_PROPERTIES 14185
+#define IDS_GRAPHBUILDER_AUDIOSWITCHER 14186
+#define IDS_SHADER_EDIT 14187
+#define IDF_SHADER_EDGE_SHARPEN 20000
+#define IDF_SHADER_SHARPEN_COMPLEX 20001
+#define IDC_FULLSCR_COMBO 22000
+#define IDC_AUTO_REFRESHRATE_CHECK 22001
+#define IDC_FULLSCREEN_MONITOR_CHECK 22002
+#define IDC_SLI_CONTRAST 22003
+#define IDC_RESET 22004
+#define IDC_DVD_POS 22005
+#define IDC_FILE_POS 22006
+#define ID_VIEW_TEARING_TEST 32769
+#define ID_SHADER_TOGGLE 32770
+#define IDS_SHADER_TOGGLE 32771
+#define ID_FILE_OPENDISC 32772
+#define ID_FILE_EJECTCLIP 32773
+#define ID_FILE_OPENDISC32774 32774
+#define ID__SHADERS 32775
+#define ID_Menu 32776
+#define ID_VIEW_REMAINING_TIME 32778
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 20002
+#define _APS_NEXT_COMMAND_VALUE 32779
+#define _APS_NEXT_CONTROL_VALUE 22006
+#define _APS_NEXT_SYMED_VALUE 24000
+#endif
+#endif
diff --git a/src/apps/subresync/res/bitmap1.bmp b/src/apps/subresync/res/bitmap1.bmp
new file mode 100644
index 000000000..002ab8074
--- /dev/null
+++ b/src/apps/subresync/res/bitmap1.bmp
Binary files differ
diff --git a/src/apps/subresync/res/bitmap2.bmp b/src/apps/subresync/res/bitmap2.bmp
new file mode 100644
index 000000000..9ce5fecda
--- /dev/null
+++ b/src/apps/subresync/res/bitmap2.bmp
Binary files differ
diff --git a/src/apps/subresync/res/subresync.ico b/src/apps/subresync/res/subresync.ico
new file mode 100644
index 000000000..8a84ca3d3
--- /dev/null
+++ b/src/apps/subresync/res/subresync.ico
Binary files differ
diff --git a/src/apps/subresync/res/subresync.manifest b/src/apps/subresync/res/subresync.manifest
new file mode 100644
index 000000000..abc7808e1
--- /dev/null
+++ b/src/apps/subresync/res/subresync.manifest
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="X86"
+ name="Microsoft.Windows.subresync"
+ type="win32"
+/>
+<description>Your app description here</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="X86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+</assembly>
diff --git a/src/apps/subresync/res/subresync.rc2 b/src/apps/subresync/res/subresync.rc2
new file mode 100644
index 000000000..79e456b05
--- /dev/null
+++ b/src/apps/subresync/res/subresync.rc2
@@ -0,0 +1,13 @@
+//
+// subresync.RC2 - resources Microsoft Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/src/apps/subresync/resource.h b/src/apps/subresync/resource.h
new file mode 100644
index 000000000..71c2b67ff
--- /dev/null
+++ b/src/apps/subresync/resource.h
@@ -0,0 +1,56 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by subresync.rc
+//
+#define IDR_MANIFEST 1
+#define VS_VERSION_INFO 1
+#define IDC_EDIT3 3
+#define IDM_ABOUTBOX 0x0010
+#define IDS_ABOUTBOX 101
+#define IDD_SUBRESYNC_DIALOG 102
+#define IDS_RG_SPACESENS 102
+#define IDS_R_GENERAL 103
+#define IDS_SKIP 104
+#define IDS_ADD 105
+#define IDR_MAINFRAME 128
+#define IDB_BITMAP1 130
+#define IDB_BITMAP2 131
+#define IDD_SAVEASTMPLT 131
+#define IDD_ASKCHARDLG 137
+#define IDD_OPENTMPLT 138
+#define IDD_ABOUTBOX 142
+#define IDC_HOMEPAGEBTN 202
+#define IDC_BUGREPORTBTN 212
+#define IDC_LIST1 1003
+#define IDC_OPENBTN 1004
+#define IDC_SAVEBTN 1005
+#define IDC_RESET 1006
+#define IDC_COMBO1 1007
+#define IDC_EDIT1 1008
+#define IDC_EDITSUB 1008
+#define IDC_EXTEND 1010
+#define IDC_UNDOEXTEND 1011
+#define IDC_EDIT4 1011
+#define IDC_CHECK1 1012
+#define IDC_CHECK2 1013
+#define IDC_SLIDER1 1014
+#define IDC_STATIC1 1015
+#define IDC_STATIC2 1016
+#define IDC_STATIC3 1017
+#define IDC_EDIT2 1018
+#define IDC_STATIC4 1019
+#define IDC_TIMEFORMATLABEL 1020
+#define IDC_AT 1025
+#define IDC_OCRDLL 1026
+#define IDC_COMBO2 2000
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 129
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/apps/subresync/stdafx.cpp b/src/apps/subresync/stdafx.cpp
new file mode 100644
index 000000000..6d5255033
--- /dev/null
+++ b/src/apps/subresync/stdafx.cpp
@@ -0,0 +1,28 @@
+/*
+ * SubResync. Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// stdafx.cpp : source file that includes just the standard includes
+// subresync.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
diff --git a/src/apps/subresync/stdafx.h b/src/apps/subresync/stdafx.h
new file mode 100644
index 000000000..0acab6d71
--- /dev/null
+++ b/src/apps/subresync/stdafx.h
@@ -0,0 +1,63 @@
+/*
+ * SubResync. Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+#endif
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
+#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
+#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
+#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.
+#endif
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
+
+// turns off MFC's hiding of some common and often safely ignored warning messages
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+#include <afxdisp.h> // MFC Automation classes
+
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
diff --git a/src/apps/subresync/subresync.cpp b/src/apps/subresync/subresync.cpp
new file mode 100644
index 000000000..bee844ac7
--- /dev/null
+++ b/src/apps/subresync/subresync.cpp
@@ -0,0 +1,98 @@
+/*
+ * SubResync. Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// subresync.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "subresync.h"
+#include "subresyncDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CSubresyncApp
+
+BEGIN_MESSAGE_MAP(CSubresyncApp, CWinApp)
+ ON_COMMAND(ID_HELP, CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CSubresyncApp construction
+
+CSubresyncApp::CSubresyncApp()
+{
+}
+
+
+// The one and only CSubresyncApp object
+
+CSubresyncApp theApp;
+
+
+// CSubresyncApp initialization
+
+BOOL CSubresyncApp::InitInstance()
+{
+ // InitCommonControls() is required on Windows XP if an application
+ // manifest specifies use of ComCtl32.dll version 6 or later to enable
+ // visual styles. Otherwise, any window creation will fail.
+ InitCommonControls();
+
+ CWinApp::InitInstance();
+
+ AfxEnableControlContainer();
+
+ SetRegistryKey(_T("Gabest"));
+
+ CoInitialize(NULL);
+
+ CCommandLineInfo cmdInfo;
+ ParseCommandLine(cmdInfo);
+
+ CSubresyncDlg dlg(cmdInfo.m_strFileName);
+ m_pMainWnd = &dlg;
+
+ INT_PTR nResponse = dlg.DoModal();
+ if (nResponse == IDOK)
+ {
+ // TODO: Place code here to handle when the dialog is
+ // dismissed with OK
+ }
+ else if (nResponse == IDCANCEL)
+ {
+ // TODO: Place code here to handle when the dialog is
+ // dismissed with Cancel
+ }
+
+ // Since the dialog has been closed, return FALSE so that we exit the
+ // application, rather than start the application's message pump.
+ return FALSE;
+}
+
+int CSubresyncApp::ExitInstance()
+{
+ CoUninitialize();
+
+ return CWinApp::ExitInstance();
+}
diff --git a/src/apps/subresync/subresync.h b/src/apps/subresync/subresync.h
new file mode 100644
index 000000000..44bfc4df0
--- /dev/null
+++ b/src/apps/subresync/subresync.h
@@ -0,0 +1,53 @@
+/*
+ * SubResync. Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// subresync.h : main header file for the PROJECT_NAME application
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h" // main symbols
+
+
+// CsubresyncApp:
+// See subresync.cpp for the implementation of this class
+//
+
+class CSubresyncApp : public CWinApp
+{
+public:
+ CSubresyncApp();
+
+// Overrides
+ public:
+ virtual BOOL InitInstance();
+ virtual int ExitInstance();
+
+// Implementation
+
+ DECLARE_MESSAGE_MAP()
+};
+
+extern CSubresyncApp theApp; \ No newline at end of file
diff --git a/src/apps/subresync/subresync.rc b/src/apps/subresync/subresync.rc
new file mode 100644
index 000000000..52cfe7a55
--- /dev/null
+++ b/src/apps/subresync/subresync.rc
@@ -0,0 +1,352 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Hungarian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_HUN)
+#ifdef _WIN32
+LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
+#pragma code_page(1250)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#include ""res\\subresync.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Hungarian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON "res\\subresync.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_ABOUTBOX, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 198
+ VERTGUIDE, 14
+ VERTGUIDE, 190
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 122
+ END
+
+ IDD_ASKCHARDLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 115
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 92
+ END
+
+ IDD_OPENTMPLT, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 285
+ VERTGUIDE, 54
+ TOPMARGIN, 1
+ BOTTOMMARGIN, 33
+ HORZGUIDE, 7
+ END
+
+ IDD_SAVEASTMPLT, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 271
+ TOPMARGIN, 2
+ BOTTOMMARGIN, 63
+ END
+
+ IDD_SUBRESYNC_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 334
+ VERTGUIDE, 13
+ VERTGUIDE, 68
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 190
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// RT_MANIFEST
+//
+
+IDR_MANIFEST RT_MANIFEST "res\\subresync.manifest"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_BITMAP1 BITMAP "res\\bitmap1.bmp"
+IDB_BITMAP2 BITMAP "res\\bitmap2.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 205, 129
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "About..."
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,137,98,50,14,WS_GROUP
+ GROUPBOX "",IDC_STATIC,7,7,191,115,BS_CENTER
+ LTEXT "Subresync Version 2.24\nCopyright 2001-2002 Gabest",
+ IDC_STATIC,14,17,179,19
+ PUSHBUTTON "Homepage",IDC_HOMEPAGEBTN,17,98,50,14,BS_FLAT
+ PUSHBUTTON "Bug Report",IDC_BUGREPORTBTN,77,98,50,14,BS_FLAT
+ LTEXT "Credits:\n- SAMI format support by Sanger && Wilowisp of SPKOR\n- Handling of some basic html style modifier tags in SAMI done by [maven]\n- Advanced Text Renderer is using the 'Rasterizer' class of Avery Lee's subtitler plugin",
+ IDC_STATIC,14,40,176,51
+END
+
+IDD_ASKCHARDLG DIALOGEX 0, 0, 122, 99
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_TOOLWINDOW
+CAPTION "Enter matching letter(s)"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ EDITTEXT 1008,7,7,108,28,ES_CENTER | ES_AUTOHSCROLL
+ DEFPUSHBUTTON "&OK",IDOK,7,40,108,14
+ PUSHBUTTON "&Extend",IDC_EXTEND,65,59,50,14
+ PUSHBUTTON "Un&do Extend",IDC_UNDOEXTEND,7,59,50,14
+ EDITTEXT 1018,7,78,108,14,ES_AUTOHSCROLL | ES_READONLY
+END
+
+IDD_OPENTMPLT DIALOGEX 0, 0, 292, 40
+STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ LTEXT "Character Set:",IDC_STATIC4,5,3,47,8
+ COMBOBOX 1007,54,1,74,76,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ LTEXT "Fps:",IDC_STATIC,143,3,14,8
+ COMBOBOX IDC_COMBO2,161,1,37,69,CBS_DROPDOWN | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "Append",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,5,22,48,10
+ EDITTEXT IDC_EDIT1,54,20,21,13,ES_CENTER | ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT2,78,20,21,13,ES_CENTER | ES_AUTOHSCROLL |
+ ES_NUMBER
+ EDITTEXT IDC_EDIT3,102,20,21,13,ES_CENTER | ES_AUTOHSCROLL |
+ ES_NUMBER
+ EDITTEXT IDC_EDIT4,126,20,21,13,ES_CENTER | ES_AUTOHSCROLL |
+ ES_NUMBER
+ LTEXT "(hh:mm:ss.ms)",IDC_TIMEFORMATLABEL,152,23,49,8
+ LTEXT "at:",IDC_AT,44,23,8,8
+END
+
+IDD_SAVEASTMPLT DIALOGEX 0, 0, 278, 68
+STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Unicode output",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,18,15,63,10
+ CONTROL "Clear image->letter(s) database",IDC_CHECK2,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,99,15,110,10
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,120,40,123,13
+ LTEXT "Space detecting sensitivity:",IDC_STATIC1,99,29,87,8
+ LTEXT "More",IDC_STATIC2,99,42,17,8
+ LTEXT "Less",IDC_STATIC3,247,42,16,8
+ GROUPBOX "MBCS<->Unicode",IDC_STATIC,9,2,77,58
+ GROUPBOX "OCR Settings",IDC_STATIC,93,2,178,58
+ CONTROL "Use ocrdll.dll",IDC_OCRDLL,"Button",BS_AUTOCHECKBOX |
+ NOT WS_VISIBLE | WS_TABSTOP,212,15,52,10
+END
+
+IDD_SUBRESYNC_DIALOG DIALOGEX 0, 0, 342, 197
+STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE |
+ WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_ACCEPTFILES | WS_EX_APPWINDOW
+CAPTION "Subresync"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ PUSHBUTTON "&Open...",IDC_OPENBTN,7,7,52,14
+ PUSHBUTTON "Save &As...",IDC_SAVEBTN,7,28,52,14
+ PUSHBUTTON "&Reset timing",IDC_RESET,7,49,52,14
+ PUSHBUTTON "&Edit...",IDC_EDITSUB,7,70,52,14,WS_DISABLED
+ COMBOBOX IDC_COMBO1,7,71,52,30,CBS_DROPDOWNLIST | NOT WS_VISIBLE |
+ WS_VSCROLL | WS_TABSTOP
+ CONTROL "Render",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,13,92,42,10
+ CONTROL "Unlink",IDC_CHECK2,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,13,107,43,10
+ PUSHBUTTON "E&xit",IDOK,7,176,52,14
+ CONTROL "List1",IDC_LIST1,"SysListView32",LVS_REPORT |
+ LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | LVS_EDITLABELS |
+ LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,68,7,266,183,
+ WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog Info
+//
+
+IDD_OPENTMPLT DLGINIT
+BEGIN
+ IDC_COMBO2, 0x403, 7, 0
+0x3332, 0x392e, 0x3637, "\000"
+ IDC_COMBO2, 0x403, 3, 0
+0x3432, "\000"
+ IDC_COMBO2, 0x403, 3, 0
+0x3532, "\000"
+ IDC_COMBO2, 0x403, 6, 0
+0x3932, 0x392e, 0x0037,
+ IDC_COMBO2, 0x403, 3, 0
+0x3033, "\000"
+ 0
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 2,0,24,0
+ PRODUCTVERSION 2,0,24,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Visit http://gabest.org/ for updates"
+ VALUE "CompanyName", "Gabest"
+ VALUE "FileDescription", "Subresync"
+ VALUE "FileVersion", "2, 0, 24, 0"
+ VALUE "InternalName", "subresync"
+ VALUE "LegalCopyright", "Copyright (C) 2001-2002 Gabest"
+ VALUE "OriginalFilename", "subresync.EXE"
+ VALUE "ProductName", "Subresync"
+ VALUE "ProductVersion", "2, 0, 24, 0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_ABOUTBOX "&About subresync..."
+ IDS_RG_SPACESENS "SpaceSensitivity"
+ IDS_R_GENERAL "General"
+ IDS_SKIP "&Skip"
+ IDS_ADD "&Add"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#include "res\subresync.rc2" // non-Microsoft Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/src/apps/subresync/subresync.sln b/src/apps/subresync/subresync.sln
new file mode 100644
index 000000000..374a23124
--- /dev/null
+++ b/src/apps/subresync/subresync.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 7.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "subresync", "subresync.vcproj", "{0B232385-29E3-4F64-92F6-1029204A08F3}"
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ ConfigName.0 = Debug
+ ConfigName.1 = Release
+ EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {0B232385-29E3-4F64-92F6-1029204A08F3}.Debug.ActiveCfg = Debug|Win32
+ {0B232385-29E3-4F64-92F6-1029204A08F3}.Debug.Build.0 = Debug|Win32
+ {0B232385-29E3-4F64-92F6-1029204A08F3}.Release.ActiveCfg = Release|Win32
+ {0B232385-29E3-4F64-92F6-1029204A08F3}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/src/apps/subresync/subresync.vcproj b/src/apps/subresync/subresync.vcproj
new file mode 100644
index 000000000..9e97d3281
--- /dev/null
+++ b/src/apps/subresync/subresync.vcproj
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding = "windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.00"
+ Name="subresync"
+ ProjectGUID="{0B232385-29E3-4F64-92F6-1029204A08F3}"
+ Keyword="MFCProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ TreatWChar_tAsBuiltInType="TRUE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="TRUE"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ StringPooling="TRUE"
+ MinimalRebuild="FALSE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ TreatWChar_tAsBuiltInType="TRUE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
+ <File
+ RelativePath="stdafx.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="subresync.cpp">
+ </File>
+ <File
+ RelativePath="subresyncDlg.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc">
+ <File
+ RelativePath="Resource.h">
+ </File>
+ <File
+ RelativePath="stdafx.h">
+ </File>
+ <File
+ RelativePath="subresync.h">
+ </File>
+ <File
+ RelativePath="subresyncDlg.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest">
+ <File
+ RelativePath="res\subresync.ico">
+ </File>
+ <File
+ RelativePath="res\subresync.manifest">
+ </File>
+ <File
+ RelativePath="subresync.rc">
+ </File>
+ <File
+ RelativePath="res\subresync.rc2">
+ </File>
+ </Filter>
+ <File
+ RelativePath="ReadMe.txt">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/apps/subresync/subresyncDlg.cpp b/src/apps/subresync/subresyncDlg.cpp
new file mode 100644
index 000000000..2c0c5ce94
--- /dev/null
+++ b/src/apps/subresync/subresyncDlg.cpp
@@ -0,0 +1,169 @@
+/*
+ * SubResync. Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// subresyncDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "subresync.h"
+#include "subresyncDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CAboutDlg dialog used for App About
+
+class CAboutDlg : public CDialog
+{
+public:
+ CAboutDlg();
+
+// Dialog Data
+ enum { IDD = IDD_ABOUTBOX };
+
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+// Implementation
+protected:
+ DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+END_MESSAGE_MAP()
+
+
+// CSubresyncDlg dialog
+
+
+
+CSubresyncDlg::CSubresyncDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CSubresyncDlg::IDD, pParent)
+{
+ m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+void CSubresyncDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CSubresyncDlg, CDialog)
+ ON_WM_SYSCOMMAND()
+ ON_WM_PAINT()
+ ON_WM_QUERYDRAGICON()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+// CSubresyncDlg message handlers
+
+BOOL CSubresyncDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ // Add "About..." menu item to system menu.
+
+ // IDM_ABOUTBOX must be in the system command range.
+ ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+ ASSERT(IDM_ABOUTBOX < 0xF000);
+
+ CMenu* pSysMenu = GetSystemMenu(FALSE);
+ if (pSysMenu != NULL)
+ {
+ CString strAboutMenu;
+ strAboutMenu.LoadString(IDS_ABOUTBOX);
+ if (!strAboutMenu.IsEmpty())
+ {
+ pSysMenu->AppendMenu(MF_SEPARATOR);
+ pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+ }
+ }
+
+ // Set the icon for this dialog. The framework does this automatically
+ // when the application's main window is not a dialog
+ SetIcon(m_hIcon, TRUE); // Set big icon
+ SetIcon(m_hIcon, FALSE); // Set small icon
+
+ // TODO: Add extra initialization here
+
+ return TRUE; // return TRUE unless you set the focus to a control
+}
+
+void CSubresyncDlg::OnSysCommand(UINT nID, LPARAM lParam)
+{
+ if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+ {
+ CAboutDlg dlgAbout;
+ dlgAbout.DoModal();
+ }
+ else
+ {
+ CDialog::OnSysCommand(nID, lParam);
+ }
+}
+
+// If you add a minimize button to your dialog, you will need the code below
+// to draw the icon. For MFC applications using the document/view model,
+// this is automatically done for you by the framework.
+
+void CSubresyncDlg::OnPaint()
+{
+ if (IsIconic())
+ {
+ CPaintDC dc(this); // device context for painting
+
+ SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
+
+ // Center icon in client rectangle
+ int cxIcon = GetSystemMetrics(SM_CXICON);
+ int cyIcon = GetSystemMetrics(SM_CYICON);
+ CRect rect;
+ GetClientRect(&rect);
+ int x = (rect.Width() - cxIcon + 1) / 2;
+ int y = (rect.Height() - cyIcon + 1) / 2;
+
+ // Draw the icon
+ dc.DrawIcon(x, y, m_hIcon);
+ }
+ else
+ {
+ CDialog::OnPaint();
+ }
+}
+
+// The system calls this function to obtain the cursor to display while the user drags
+// the minimized window.
+HCURSOR CSubresyncDlg::OnQueryDragIcon()
+{
+ return static_cast<HCURSOR>(m_hIcon);
+}
diff --git a/src/apps/subresync/subresyncDlg.h b/src/apps/subresync/subresyncDlg.h
new file mode 100644
index 000000000..b03e4799a
--- /dev/null
+++ b/src/apps/subresync/subresyncDlg.h
@@ -0,0 +1,97 @@
+/*
+ * SubResync. Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// subresyncDlg.h : header file
+//
+
+#pragma once
+
+class CharImg
+{
+public:
+ CString m_str;
+
+ CSize m_size;
+ CAutoVectorPtr<BYTE> m_p;
+
+ // feature list
+ int m_topbottom;
+
+ CharImg(DWORD* p, int pitch, CRect r, int* left, int* right, int topbottom, CString str = _T(""));
+ CharImg(FILE* f);
+ ~CharImg();
+
+ bool Match(CharImg* img);
+
+ bool Write(FILE* f);
+ bool Read(FILE* f);
+};
+
+class CharSegment
+{
+public:
+ int* left;
+ int* right;
+ int h, srow, erow;
+
+ CharSegment(int* left, int* right, int h, int srow, int erow);
+ ~CharSegment();
+};
+
+// CSubresyncDlg dialog
+class CSubresyncDlg : public CDialog
+{
+// Construction
+public:
+ CSubresyncDlg(CString fn, CWnd* pParent = NULL); // standard constructor
+ virtual ~CSubresyncDlg();
+
+ bool Open(CString fn, int CharSet = DEFAULT_CHARSET, bool fAppend = false, int timeoff = 0);
+ bool Save(CString fn, exttype et, CTextFile::enc e, bool fClearImgLetterDb = false, bool fOcrDll = false);
+
+// Dialog Data
+ enum { IDD = IDD_SUBRESYNC_DIALOG };
+ CListCtrl m_list;
+ CButton m_saveasbtn;
+ CButton m_resetbtn;
+ CButton m_editbtn;
+ CButton m_exitbtn;
+ BOOL m_fRender;
+ CButton m_previewchk;
+ BOOL m_fUnlink;
+ CButton m_unlinkchk;
+ CComboBox m_vslangs;
+
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+
+// Implementation
+protected:
+ HICON m_hIcon;
+
+ // Generated message map functions
+ virtual BOOL OnInitDialog();
+ afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+ afx_msg void OnPaint();
+ afx_msg HCURSOR OnQueryDragIcon();
+ DECLARE_MESSAGE_MAP()
+};
diff --git a/src/apps/vsconv/Resource.h b/src/apps/vsconv/Resource.h
new file mode 100644
index 000000000..37f0b1669
--- /dev/null
+++ b/src/apps/vsconv/Resource.h
@@ -0,0 +1,20 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by vsconv.rc
+//
+#define IDR_MANIFEST 1
+#define IDM_ABOUTBOX 0x0010
+#define IDS_ABOUTBOX 101
+#define IDD_VSCONV_DIALOG 102
+#define IDR_MAINFRAME 128
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 129
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/apps/vsconv/res/vsconv.ico b/src/apps/vsconv/res/vsconv.ico
new file mode 100644
index 000000000..8a84ca3d3
--- /dev/null
+++ b/src/apps/vsconv/res/vsconv.ico
Binary files differ
diff --git a/src/apps/vsconv/res/vsconv.manifest b/src/apps/vsconv/res/vsconv.manifest
new file mode 100644
index 000000000..fa49fd4c2
--- /dev/null
+++ b/src/apps/vsconv/res/vsconv.manifest
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="X86"
+ name="Microsoft.Windows.vsconv"
+ type="win32"
+/>
+<description>Your app description here</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="X86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+</assembly>
diff --git a/src/apps/vsconv/res/vsconv.rc2 b/src/apps/vsconv/res/vsconv.rc2
new file mode 100644
index 000000000..7535c79d2
--- /dev/null
+++ b/src/apps/vsconv/res/vsconv.rc2
@@ -0,0 +1,13 @@
+//
+// vsconv.RC2 - resources Microsoft Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/src/apps/vsconv/stdafx.cpp b/src/apps/vsconv/stdafx.cpp
new file mode 100644
index 000000000..31cb1a3de
--- /dev/null
+++ b/src/apps/vsconv/stdafx.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// stdafx.cpp : source file that includes just the standard includes
+// vsconv.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
diff --git a/src/apps/vsconv/stdafx.h b/src/apps/vsconv/stdafx.h
new file mode 100644
index 000000000..bae7f7d40
--- /dev/null
+++ b/src/apps/vsconv/stdafx.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+#endif
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
+#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
+#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
+#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.
+#endif
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
+
+// turns off MFC's hiding of some common and often safely ignored warning messages
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+#include <afxdisp.h> // MFC Automation classes
+
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <dshow.h>
+#include <streams.h>
diff --git a/src/apps/vsconv/vsconv.cpp b/src/apps/vsconv/vsconv.cpp
new file mode 100644
index 000000000..576fa7bd1
--- /dev/null
+++ b/src/apps/vsconv/vsconv.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// vsconv.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "vsconv.h"
+#include "vsconvDlg.h"
+#include "..\..\subtitles\VobSubFile.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CvsconvApp
+
+BEGIN_MESSAGE_MAP(CvsconvApp, CWinApp)
+ ON_COMMAND(ID_HELP, CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CvsconvApp construction
+
+CvsconvApp::CvsconvApp()
+{
+ // TODO: add construction code here,
+ // Place all significant initialization in InitInstance
+}
+
+
+// The one and only CvsconvApp object
+
+CvsconvApp theApp;
+
+
+// CvsconvApp initialization
+
+BOOL CvsconvApp::InitInstance()
+{
+ // InitCommonControls() is required on Windows XP if an application
+ // manifest specifies use of ComCtl32.dll version 6 or later to enable
+ // visual styles. Otherwise, any window creation will fail.
+ InitCommonControls();
+
+ CWinApp::InitInstance();
+
+ AfxEnableControlContainer();
+
+ // TODO
+// if(__argc > 1)
+ {
+ CString in, out;
+ CVobSubFile::SubFormat sf = CVobSubFile::None;
+ int iLang = -1;
+ bool fIgnoreForcedOnly = false;
+ bool fForcedOnly = false;
+
+ try
+ {
+ for(int i = 1; i < __argc; i++)
+ {
+ if(__targv[i][0] == '-' || __targv[i][0] == '/')
+ {
+ CString sw(&__targv[i][1]);
+
+ if(sw == _T("f"))
+ {
+ if(++i < __argc && __targv[i][0] != '-' && __targv[i][0] != '/')
+ {
+ CString fmt = CString(__targv[i]).MakeLower();
+
+ if(fmt == _T("winsubmux"))
+ sf = CVobSubFile::WinSubMux;
+ else if(fmt == _T("scenarist"))
+ sf = CVobSubFile::Scenarist;
+ else if(fmt == _T("maestro"))
+ sf = CVobSubFile::Maestro;
+ else
+ throw _T("Unrecognized conversion format");
+ }
+ else
+ throw _T("No conversion format given");
+ }
+ else if(sw == _T("i"))
+ {
+ if(++i < __argc && __targv[i][0] != '-' && __targv[i][0] != '/')
+ in = __targv[i];
+ else
+ throw _T("Missing input file");
+ }
+ else if(sw == _T("o"))
+ {
+ if(++i < __argc && __targv[i][0] != '-' && __targv[i][0] != '/')
+ out = __targv[i];
+ else
+ throw _T("Missing output file");
+ }
+ else if(sw == _T("id"))
+ {
+ if(++i < __argc && __targv[i][0] != '-' && __targv[i][0] != '/')
+ iLang = _tcstol(__targv[i], NULL, 10);
+ else
+ throw _T("Missing stream id");
+ }
+ else if(sw == _T("ignoreforcedonly"))
+ {
+ fIgnoreForcedOnly = true;
+ }
+ else if(sw == _T("forcedonly"))
+ {
+ fForcedOnly = true;
+ }
+ }
+ }
+
+ if(!in.IsEmpty() && !out.IsEmpty() && sf != CVobSubFile::None)
+ {
+ CVobSubFile vsf(NULL);
+
+ if(!vsf.Open(in))
+ throw _T("Can't open input");
+
+ if(iLang >= 0 && iLang < 32)
+ vsf.m_iLang = iLang;
+
+ if(fForcedOnly)
+ vsf.m_fOnlyShowForcedSubs = true;
+
+ if(fIgnoreForcedOnly)
+ vsf.m_fOnlyShowForcedSubs = false;
+
+ if(!vsf.Save(out, sf))
+ throw _T("Can't save output");
+
+ return FALSE;
+ }
+ }
+ catch(LPCTSTR msg)
+ {
+ AfxMessageBox(CString(_T("Error: ")) + msg);
+ }
+
+ AfxMessageBox(
+ _T("Usage: vsconv.exe <switches>\n\n")
+ _T("-f \"format\" (winsubmux, scenarist, maestro)\n")
+ _T("-i \"input\"\n")
+ _T("-o \"output\"\n")
+ _T("-id 0-31 (optional)\n")
+ _T("-ignoreforcedonly (optional)\n")
+ _T("-forcedonly (optional)\n")
+ );
+
+ return FALSE;
+ }
+
+ // TODO
+ return FALSE;
+
+
+ CvsconvDlg dlg;
+ m_pMainWnd = &dlg;
+ INT_PTR nResponse = dlg.DoModal();
+ if (nResponse == IDOK)
+ {
+ // TODO: Place code here to handle when the dialog is
+ // dismissed with OK
+ }
+ else if (nResponse == IDCANCEL)
+ {
+ // TODO: Place code here to handle when the dialog is
+ // dismissed with Cancel
+ }
+
+ // Since the dialog has been closed, return FALSE so that we exit the
+ // application, rather than start the application's message pump.
+ return FALSE;
+}
diff --git a/src/apps/vsconv/vsconv.h b/src/apps/vsconv/vsconv.h
new file mode 100644
index 000000000..a3e44f2e4
--- /dev/null
+++ b/src/apps/vsconv/vsconv.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// vsconv.h : main header file for the PROJECT_NAME application
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h" // main symbols
+
+
+// CvsconvApp:
+// See vsconv.cpp for the implementation of this class
+//
+
+class CvsconvApp : public CWinApp
+{
+public:
+ CvsconvApp();
+
+// Overrides
+ public:
+ virtual BOOL InitInstance();
+
+// Implementation
+
+ DECLARE_MESSAGE_MAP()
+};
+
+extern CvsconvApp theApp; \ No newline at end of file
diff --git a/src/apps/vsconv/vsconv.rc b/src/apps/vsconv/vsconv.rc
new file mode 100644
index 000000000..9aa9e4364
--- /dev/null
+++ b/src/apps/vsconv/vsconv.rc
@@ -0,0 +1,199 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Hungarian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_HUN)
+#ifdef _WIN32
+LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
+#pragma code_page(1250)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#include ""res\\vsconv.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON "res\\vsconv.ico"
+#endif // Hungarian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_VSCONV_DIALOG DIALOGEX 0, 0, 320, 200
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP |
+ WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "vsconv"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,263,7,50,16
+ PUSHBUTTON "Cancel",IDCANCEL,263,25,50,16
+ CTEXT "TODO: Place dialog controls here.",IDC_STATIC,10,96,300,
+ 8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,6
+ PRODUCTVERSION 1,0,0,6
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "Gabest"
+ VALUE "FileDescription", "VobSub subtitle format converter"
+ VALUE "FileVersion", "1, 0, 0, 6"
+ VALUE "InternalName", "vsconv.exe"
+ VALUE "LegalCopyright", "2003-2004 (c) Gabest. All rights reserved."
+ VALUE "OriginalFilename", "vsconv.exe"
+ VALUE "ProductName", "VSConv"
+ VALUE "ProductVersion", "1, 0, 0, 6"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_VSCONV_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 313
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 193
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// RT_MANIFEST
+//
+
+IDR_MANIFEST RT_MANIFEST "res\\vsconv.manifest"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_ABOUTBOX "&About vsconv..."
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#include "res\vsconv.rc2" // non-Microsoft Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/src/apps/vsconv/vsconv.sln b/src/apps/vsconv/vsconv.sln
new file mode 100644
index 000000000..dc09b6934
--- /dev/null
+++ b/src/apps/vsconv/vsconv.sln
@@ -0,0 +1,40 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vsconv", "vsconv.vcproj", "{F655A8A5-A73E-4EE0-89B4-2758055B3768}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4} = {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "subtitles", "..\..\subtitles\subtitles.vcproj", "{5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Debug Unicode = Debug Unicode
+ Release = Release
+ Release Unicode = Release Unicode
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {F655A8A5-A73E-4EE0-89B4-2758055B3768}.Debug.ActiveCfg = Debug|Win32
+ {F655A8A5-A73E-4EE0-89B4-2758055B3768}.Debug.Build.0 = Debug|Win32
+ {F655A8A5-A73E-4EE0-89B4-2758055B3768}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {F655A8A5-A73E-4EE0-89B4-2758055B3768}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {F655A8A5-A73E-4EE0-89B4-2758055B3768}.Release.ActiveCfg = Release|Win32
+ {F655A8A5-A73E-4EE0-89B4-2758055B3768}.Release.Build.0 = Release|Win32
+ {F655A8A5-A73E-4EE0-89B4-2758055B3768}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {F655A8A5-A73E-4EE0-89B4-2758055B3768}.Release Unicode.Build.0 = Release Unicode|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Debug.ActiveCfg = Debug|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Debug.Build.0 = Debug|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Release.ActiveCfg = Release|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Release.Build.0 = Release|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Release Unicode.Build.0 = Release Unicode|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/src/apps/vsconv/vsconv.vcproj b/src/apps/vsconv/vsconv.vcproj
new file mode 100644
index 000000000..3dd70d035
--- /dev/null
+++ b/src/apps/vsconv/vsconv.vcproj
@@ -0,0 +1,321 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="vsconv"
+ ProjectGUID="{F655A8A5-A73E-4EE0-89B4-2758055B3768}"
+ Keyword="MFCProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)"
+ ConfigurationType="1"
+ UseOfMFC="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="subtitlesD.lib subpicD.lib strmbaseD.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../../../lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="TRUE"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ StringPooling="TRUE"
+ MinimalRebuild="FALSE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ TreatWChar_tAsBuiltInType="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="subtitlesR.lib subpicR.lib strmbaseR.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../../lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="..\..\..\bin\upx.exe --best --compress-icons=0 &quot;$(TargetPath)&quot;"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)"
+ ConfigurationType="1"
+ UseOfMFC="2"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="subtitlesDU.lib subpicDU.lib strmbaseDU.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../../../lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="TRUE"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ StringPooling="TRUE"
+ MinimalRebuild="FALSE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ TreatWChar_tAsBuiltInType="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="subtitlesRU.lib subpicRU.lib strmbaseRU.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../../lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="..\..\..\bin\upx.exe --best --compress-icons=0 &quot;$(TargetPath)&quot;"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
+ <File
+ RelativePath="stdafx.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="vsconv.cpp">
+ </File>
+ <File
+ RelativePath="vsconvDlg.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc">
+ <File
+ RelativePath="Resource.h">
+ </File>
+ <File
+ RelativePath="stdafx.h">
+ </File>
+ <File
+ RelativePath="vsconv.h">
+ </File>
+ <File
+ RelativePath="vsconvDlg.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest">
+ <File
+ RelativePath="res\vsconv.ico">
+ </File>
+ <File
+ RelativePath="res\vsconv.manifest">
+ </File>
+ <File
+ RelativePath="vsconv.rc">
+ </File>
+ <File
+ RelativePath="res\vsconv.rc2">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/apps/vsconv/vsconvDlg.cpp b/src/apps/vsconv/vsconvDlg.cpp
new file mode 100644
index 000000000..31d3348a6
--- /dev/null
+++ b/src/apps/vsconv/vsconvDlg.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// vsconvDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "vsconv.h"
+#include "vsconvDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CAboutDlg dialog used for App About
+
+class CAboutDlg : public CDialog
+{
+public:
+ CAboutDlg();
+
+// Dialog Data
+ enum { IDD = IDD_ABOUTBOX };
+
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+// Implementation
+protected:
+ DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+END_MESSAGE_MAP()
+
+
+// CvsconvDlg dialog
+
+
+
+CvsconvDlg::CvsconvDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CvsconvDlg::IDD, pParent)
+{
+ m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+void CvsconvDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CvsconvDlg, CDialog)
+ ON_WM_SYSCOMMAND()
+ ON_WM_PAINT()
+ ON_WM_QUERYDRAGICON()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+// CvsconvDlg message handlers
+
+BOOL CvsconvDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ // Add "About..." menu item to system menu.
+
+ // IDM_ABOUTBOX must be in the system command range.
+ ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+ ASSERT(IDM_ABOUTBOX < 0xF000);
+
+ CMenu* pSysMenu = GetSystemMenu(FALSE);
+ if (pSysMenu != NULL)
+ {
+ CString strAboutMenu;
+ strAboutMenu.LoadString(IDS_ABOUTBOX);
+ if (!strAboutMenu.IsEmpty())
+ {
+ pSysMenu->AppendMenu(MF_SEPARATOR);
+ pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+ }
+ }
+
+ // Set the icon for this dialog. The framework does this automatically
+ // when the application's main window is not a dialog
+ SetIcon(m_hIcon, TRUE); // Set big icon
+ SetIcon(m_hIcon, FALSE); // Set small icon
+
+ // TODO: Add extra initialization here
+
+ return TRUE; // return TRUE unless you set the focus to a control
+}
+
+void CvsconvDlg::OnSysCommand(UINT nID, LPARAM lParam)
+{
+ if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+ {
+ CAboutDlg dlgAbout;
+ dlgAbout.DoModal();
+ }
+ else
+ {
+ CDialog::OnSysCommand(nID, lParam);
+ }
+}
+
+// If you add a minimize button to your dialog, you will need the code below
+// to draw the icon. For MFC applications using the document/view model,
+// this is automatically done for you by the framework.
+
+void CvsconvDlg::OnPaint()
+{
+ if (IsIconic())
+ {
+ CPaintDC dc(this); // device context for painting
+
+ SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
+
+ // Center icon in client rectangle
+ int cxIcon = GetSystemMetrics(SM_CXICON);
+ int cyIcon = GetSystemMetrics(SM_CYICON);
+ CRect rect;
+ GetClientRect(&rect);
+ int x = (rect.Width() - cxIcon + 1) / 2;
+ int y = (rect.Height() - cyIcon + 1) / 2;
+
+ // Draw the icon
+ dc.DrawIcon(x, y, m_hIcon);
+ }
+ else
+ {
+ CDialog::OnPaint();
+ }
+}
+
+// The system calls this function to obtain the cursor to display while the user drags
+// the minimized window.
+HCURSOR CvsconvDlg::OnQueryDragIcon()
+{
+ return static_cast<HCURSOR>(m_hIcon);
+}
diff --git a/src/apps/vsconv/vsconvDlg.h b/src/apps/vsconv/vsconvDlg.h
new file mode 100644
index 000000000..07326405b
--- /dev/null
+++ b/src/apps/vsconv/vsconvDlg.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// vsconvDlg.h : header file
+//
+
+#pragma once
+
+
+// CvsconvDlg dialog
+class CvsconvDlg : public CDialog
+{
+// Construction
+public:
+ CvsconvDlg(CWnd* pParent = NULL); // standard constructor
+
+// Dialog Data
+ enum { IDD = IDD_VSCONV_DIALOG };
+
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+
+// Implementation
+protected:
+ HICON m_hIcon;
+
+ // Generated message map functions
+ virtual BOOL OnInitDialog();
+ afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+ afx_msg void OnPaint();
+ afx_msg HCURSOR OnQueryDragIcon();
+ DECLARE_MESSAGE_MAP()
+};
diff --git a/src/apps/vsrip/VSRip.cpp b/src/apps/vsrip/VSRip.cpp
new file mode 100644
index 000000000..8aee5088b
--- /dev/null
+++ b/src/apps/vsrip/VSRip.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// VSRip.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "VSRip.h"
+#include "VSRipDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CVSRipApp
+
+BEGIN_MESSAGE_MAP(CVSRipApp, CWinApp)
+ ON_COMMAND(ID_HELP, CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CVSRipApp construction
+
+CVSRipApp::CVSRipApp()
+{
+ // TODO: add construction code here,
+ // Place all significant initialization in InitInstance
+}
+
+
+// The one and only CVSRipApp object
+
+CVSRipApp theApp;
+
+// CVSRipApp initialization
+
+BOOL CVSRipApp::InitInstance()
+{
+ // InitCommonControls() is required on Windows XP if an application
+ // manifest specifies use of ComCtl32.dll version 6 or later to enable
+ // visual styles. Otherwise, any window creation will fail.
+ InitCommonControls();
+
+ CWinApp::InitInstance();
+
+ CVSRipDlg dlg;
+ m_pMainWnd = &dlg;
+ INT_PTR nResponse = dlg.DoModal();
+ if (nResponse == IDOK)
+ {
+ // TODO: Place code here to handle when the dialog is
+ // dismissed with OK
+ }
+ else if (nResponse == IDCANCEL)
+ {
+ // TODO: Place code here to handle when the dialog is
+ // dismissed with Cancel
+ }
+
+ // Since the dialog has been closed, return FALSE so that we exit the
+ // application, rather than start the application's message pump.
+ return FALSE;
+}
diff --git a/src/apps/vsrip/VSRip.h b/src/apps/vsrip/VSRip.h
new file mode 100644
index 000000000..05a38411e
--- /dev/null
+++ b/src/apps/vsrip/VSRip.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// VSRip.h : main header file for the PROJECT_NAME application
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h" // main symbols
+
+
+// CVSRipApp:
+// See VSRip.cpp for the implementation of this class
+//
+
+class CVSRipApp : public CWinApp
+{
+public:
+ CVSRipApp();
+
+// Overrides
+ public:
+ virtual BOOL InitInstance();
+
+// Implementation
+
+ DECLARE_MESSAGE_MAP()
+};
+
+extern CVSRipApp theApp; \ No newline at end of file
diff --git a/src/apps/vsrip/VSRip.rc b/src/apps/vsrip/VSRip.rc
new file mode 100644
index 000000000..51202daf1
--- /dev/null
+++ b/src/apps/vsrip/VSRip.rc
@@ -0,0 +1,263 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Hungarian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_HUN)
+#ifdef _WIN32
+LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
+#pragma code_page(1250)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#include ""res\\VSRip.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Hungarian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON "res\\VSRip.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_VSRIP_DIALOG DIALOGEX 0, 0, 320, 201
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE |
+ WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_TOOLWINDOW | WS_EX_APPWINDOW
+CAPTION "VobSub Ripper Wizard"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ PUSHBUTTON "&Cancel",IDCANCEL,260,177,50,14
+ PUSHBUTTON "< &Back",IDC_BUTTON1,145,177,50,14
+ PUSHBUTTON "&Next >",IDC_BUTTON2,196,177,50,14
+ CONTROL "",IDC_HEADERSEP,"Static",SS_ETCHEDHORZ,0,35,319,1
+ CONTROL "",IDC_DLGRECT,"Static",SS_BLACKFRAME | NOT WS_VISIBLE,6,
+ 40,307,120
+ CONTROL "",IDC_FOOTERSEP,"Static",SS_ETCHEDHORZ,0,166,319,1
+END
+
+IDD_DIALOG_FILE DIALOGEX 0, 0, 307, 120
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ EDITTEXT IDC_EDIT1,2,2,249,13,ES_AUTOHSCROLL | ES_READONLY
+ PUSHBUTTON "&Load IFO...",IDC_BUTTON1,255,2,50,13
+ EDITTEXT IDC_EDIT2,2,17,249,13,ES_AUTOHSCROLL | ES_READONLY
+ PUSHBUTTON "&Save To...",IDC_BUTTON2,255,17,50,13
+ EDITTEXT IDC_EDIT3,2,37,303,82,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_READONLY | WS_VSCROLL
+END
+
+IDD_DIALOG_PGC DIALOGEX 0, 0, 307, 120
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LISTBOX IDC_LIST1,0,12,54,107,LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
+ WS_TABSTOP
+ LISTBOX IDC_LIST2,128,12,64,107,LBS_NOINTEGRALHEIGHT |
+ WS_VSCROLL | WS_TABSTOP
+ LTEXT "Program Chains:",IDC_STATIC,0,2,54,8
+ LTEXT "Angles:",IDC_STATIC,128,2,25,8
+ LISTBOX IDC_LIST3,196,12,47,107,LBS_NOINTEGRALHEIGHT |
+ LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Vob/Cell IDs:",IDC_STATIC,196,2,42,8
+ LISTBOX IDC_LIST4,57,12,67,107,LBS_NOINTEGRALHEIGHT |
+ LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Languages:",IDC_STATIC,57,2,38,8
+ CONTROL "Reset time at the first selected cell",IDC_CHECK1,
+ "Button",BS_AUTOCHECKBOX | BS_VCENTER | BS_MULTILINE |
+ WS_TABSTOP,248,12,59,27
+ CONTROL "Extract closed caption",IDC_CHECK2,"Button",
+ BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,248,52,59,18
+ CONTROL "Forced subtitles only",IDC_CHECK3,"Button",
+ BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,248,83,59,18
+END
+
+IDD_DIALOG_INDEXING DIALOGEX 0, 0, 307, 120
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "",IDC_PROGRESS1,"msctls_progress32",WS_BORDER,0,2,252,
+ 14
+ PUSHBUTTON "&Start",IDC_BUTTON1,257,1,50,14
+ CONTROL "Close dialog",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,122,110,52,10
+ LTEXT "After a successful rip:",IDC_STATIC,0,110,71,8
+ CONTROL "Beep",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 82,110,29,10
+ EDITTEXT IDC_EDIT1,0,20,307,83,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_READONLY | WS_VSCROLL
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,6
+ PRODUCTVERSION 1,0,0,6
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "Comments", "Visit http://gabest.org/ for updates"
+ VALUE "CompanyName", "Gabest"
+ VALUE "FileDescription", "VobSub Subtitle Ripper Wizard"
+ VALUE "FileVersion", "1, 0, 0, 6"
+ VALUE "InternalName", "VSRip.exe"
+ VALUE "LegalCopyright", "2003-2004 (c) Gabest. All rights reserved."
+ VALUE "OriginalFilename", "VSRip.exe"
+ VALUE "ProductName", "VSRip"
+ VALUE "ProductVersion", "1, 0, 0, 6"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_VSRIP_DIALOG, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 200
+ HORZGUIDE, 184
+ END
+
+ IDD_DIALOG_FILE, DIALOG
+ BEGIN
+ VERTGUIDE, 2
+ VERTGUIDE, 305
+ HORZGUIDE, 2
+ HORZGUIDE, 15
+ HORZGUIDE, 17
+ HORZGUIDE, 30
+ END
+
+ IDD_DIALOG_PGC, DIALOG
+ BEGIN
+ VERTGUIDE, 57
+ VERTGUIDE, 128
+ VERTGUIDE, 196
+ VERTGUIDE, 248
+ HORZGUIDE, 2
+ HORZGUIDE, 12
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// RT_MANIFEST
+//
+
+IDR_MANIFEST RT_MANIFEST "res\\VSRip.manifest"
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#include "res\VSRip.rc2" // non-Microsoft Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/src/apps/vsrip/VSRip.sln b/src/apps/vsrip/VSRip.sln
new file mode 100644
index 000000000..b54ca4e4e
--- /dev/null
+++ b/src/apps/vsrip/VSRip.sln
@@ -0,0 +1,53 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VSRip", "VSRip.vcproj", "{E6B555EF-515E-47B6-A78A-98973397CF93}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4} = {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575} = {1A2DFD1A-3C6C-44D1-909D-294AF646B575}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "decss", "..\..\decss\decss.vcproj", "{1A2DFD1A-3C6C-44D1-909D-294AF646B575}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "subtitles", "..\..\subtitles\subtitles.vcproj", "{5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Debug Unicode = Debug Unicode
+ Release = Release
+ Release Unicode = Release Unicode
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {E6B555EF-515E-47B6-A78A-98973397CF93}.Debug.ActiveCfg = Debug|Win32
+ {E6B555EF-515E-47B6-A78A-98973397CF93}.Debug.Build.0 = Debug|Win32
+ {E6B555EF-515E-47B6-A78A-98973397CF93}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {E6B555EF-515E-47B6-A78A-98973397CF93}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {E6B555EF-515E-47B6-A78A-98973397CF93}.Release.ActiveCfg = Release|Win32
+ {E6B555EF-515E-47B6-A78A-98973397CF93}.Release.Build.0 = Release|Win32
+ {E6B555EF-515E-47B6-A78A-98973397CF93}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {E6B555EF-515E-47B6-A78A-98973397CF93}.Release Unicode.Build.0 = Release Unicode|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Debug.ActiveCfg = Debug|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Debug.Build.0 = Debug|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Release.ActiveCfg = Release|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Release.Build.0 = Release|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {1A2DFD1A-3C6C-44D1-909D-294AF646B575}.Release Unicode.Build.0 = Release Unicode|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Debug.ActiveCfg = Debug|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Debug.Build.0 = Debug|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Debug Unicode.Build.0 = Debug Unicode|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Release.ActiveCfg = Release|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Release.Build.0 = Release|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Release Unicode.ActiveCfg = Release Unicode|Win32
+ {5E56335F-0FB1-4EEA-B240-D8DC5E0608E4}.Release Unicode.Build.0 = Release Unicode|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/src/apps/vsrip/VSRip.vcproj b/src/apps/vsrip/VSRip.vcproj
new file mode 100644
index 000000000..c1fc6e539
--- /dev/null
+++ b/src/apps/vsrip/VSRip.vcproj
@@ -0,0 +1,349 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="VSRip"
+ ProjectGUID="{E6B555EF-515E-47B6-A78A-98973397CF93}"
+ Keyword="MFCProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ UseOfMFC="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="decssD.lib strmbaseD.lib subtitlesD.lib subpicD.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../../../lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="TRUE"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ StringPooling="TRUE"
+ MinimalRebuild="FALSE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ TreatWChar_tAsBuiltInType="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="delayimp.lib decssR.lib strmbaseR.lib subtitlesR.lib subpicR.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../../lib"
+ DelayLoadDLLs="oleacc.dll"
+ GenerateDebugInformation="TRUE"
+ GenerateMapFile="FALSE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="..\..\..\bin\upx.exe --best --compress-icons=0 &quot;$(TargetPath)&quot;"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory="Debug Unicode"
+ IntermediateDirectory="Debug Unicode"
+ ConfigurationType="1"
+ UseOfMFC="2"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="decssDU.lib strmbaseDU.lib subtitlesDU.lib subpicDU.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../../../lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="Release Unicode"
+ IntermediateDirectory="Release Unicode"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="TRUE"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ StringPooling="TRUE"
+ MinimalRebuild="FALSE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ TreatWChar_tAsBuiltInType="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="delayimp.lib decssRU.lib strmbaseRU.lib subtitlesRU.lib subpicRU.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../../lib"
+ DelayLoadDLLs="oleacc.dll"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="..\..\..\bin\upx.exe --best --compress-icons=0 &quot;$(TargetPath)&quot;"
+ ExcludedFromBuild="TRUE"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
+ <File
+ RelativePath="stdafx.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="VSRip.cpp">
+ </File>
+ <File
+ RelativePath="VSRipDlg.cpp">
+ </File>
+ <File
+ RelativePath="VSRipFileDlg.cpp">
+ </File>
+ <File
+ RelativePath="VSRipIndexingDlg.cpp">
+ </File>
+ <File
+ RelativePath="VSRipPage.cpp">
+ </File>
+ <File
+ RelativePath="VSRipPGCDlg.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc">
+ <File
+ RelativePath="Resource.h">
+ </File>
+ <File
+ RelativePath="stdafx.h">
+ </File>
+ <File
+ RelativePath="VSRip.h">
+ </File>
+ <File
+ RelativePath="VSRipDlg.h">
+ </File>
+ <File
+ RelativePath="VSRipFileDlg.h">
+ </File>
+ <File
+ RelativePath="VSRipIndexingDlg.h">
+ </File>
+ <File
+ RelativePath="VSRipPage.h">
+ </File>
+ <File
+ RelativePath="VSRipPGCDlg.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest">
+ <File
+ RelativePath="res\VSRip.ico">
+ </File>
+ <File
+ RelativePath="res\VSRip.manifest">
+ </File>
+ <File
+ RelativePath="VSRip.rc">
+ </File>
+ <File
+ RelativePath="res\VSRip.rc2">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/apps/vsrip/VSRipDlg.cpp b/src/apps/vsrip/VSRipDlg.cpp
new file mode 100644
index 000000000..91680d301
--- /dev/null
+++ b/src/apps/vsrip/VSRipDlg.cpp
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// VSRipDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include <afxpriv.h>
+#include "VSRip.h"
+#include "VSRipDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CVSRipDlg dialog
+
+CVSRipDlg::CVSRipDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CVSRipDlg::IDD, pParent)
+{
+ m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+ m_dlgpos = NULL;
+
+ m_pVSFRipper = new CVobSubFileRipper();
+}
+
+CVSRipDlg::~CVSRipDlg()
+{
+ m_pVSFRipper->SetCallBack(NULL);
+}
+
+void CVSRipDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_DLGRECT, m_dlgrect);
+ DDX_Control(pDX, IDC_HEADERSEP, m_hdrline);
+ DDX_Control(pDX, IDC_FOOTERSEP, m_ftrline);
+}
+
+void CVSRipDlg::ShowNext()
+{
+ POSITION prev = m_dlgpos;
+ m_dlgpos = GetNext();
+
+ if(prev && prev != m_dlgpos)
+ {
+ m_dlgs.GetAt(prev)->OnNext();
+ m_dlgs.GetAt(prev)->ShowWindow(SW_HIDE);
+ }
+
+ if(m_dlgpos)
+ {
+ CVSRipPage* pDlg = m_dlgs.GetAt(m_dlgpos);
+ CRect dr;
+ m_dlgrect.GetClientRect(dr);
+ m_dlgrect.MapWindowPoints(this, dr);
+ pDlg->MoveWindow(dr);
+ pDlg->ShowWindow(SW_SHOWNORMAL);
+ Invalidate();
+ }
+}
+
+void CVSRipDlg::ShowPrev()
+{
+ POSITION next = m_dlgpos;
+ m_dlgpos = GetPrev();
+
+ if(next && next != m_dlgpos)
+ {
+ m_dlgs.GetAt(next)->OnPrev();
+ m_dlgs.GetAt(next)->ShowWindow(SW_HIDE);
+ }
+
+ if(m_dlgpos)
+ {
+ CVSRipPage* pDlg = m_dlgs.GetAt(m_dlgpos);
+ CRect dr;
+ m_dlgrect.GetClientRect(dr);
+ m_dlgrect.MapWindowPoints(this, dr);
+ pDlg->MoveWindow(dr);
+ pDlg->ShowWindow(SW_SHOWNORMAL);
+ Invalidate();
+ }
+}
+
+POSITION CVSRipDlg::GetNext()
+{
+ POSITION pos = m_dlgpos;
+ if(pos && m_dlgs.GetAt(pos)->CanGoNext()) m_dlgs.GetNext(pos);
+ else if(pos && !m_dlgs.GetAt(pos)->CanGoNext()) pos = NULL;
+ else pos = m_dlgs.GetHeadPosition();
+ return(pos);
+}
+
+POSITION CVSRipDlg::GetPrev()
+{
+ POSITION pos = m_dlgpos;
+ if(pos && m_dlgs.GetAt(pos)->CanGoPrev()) m_dlgs.GetPrev(pos);
+ else if(pos && !m_dlgs.GetAt(pos)->CanGoPrev()) pos = NULL;
+ else pos = m_dlgs.GetTailPosition();
+ return(pos);
+}
+
+BEGIN_MESSAGE_MAP(CVSRipDlg, CDialog)
+ ON_WM_PAINT()
+ ON_WM_QUERYDRAGICON()
+ ON_MESSAGE_VOID(WM_KICKIDLE, OnKickIdle)
+ ON_BN_CLICKED(IDC_BUTTON1, OnPrev)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdatePrev)
+ ON_BN_CLICKED(IDC_BUTTON2, OnNext)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateNext)
+ ON_BN_CLICKED(IDCANCEL, OnClose)
+ ON_UPDATE_COMMAND_UI(IDCANCEL, OnUpdateClose)
+END_MESSAGE_MAP()
+
+// CVSRipDlg message handlers
+
+BOOL CVSRipDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ // Set the icon for this dialog. The framework does this automatically
+ // when the application's main window is not a dialog
+ SetIcon(m_hIcon, TRUE); // Set big icon
+ SetIcon(m_hIcon, FALSE); // Set small icon
+
+ if(CMenu* pSysMenu = GetSystemMenu(FALSE))
+ {
+ pSysMenu->RemoveMenu(SC_SIZE, MF_BYCOMMAND);
+ pSysMenu->RemoveMenu(SC_MAXIMIZE, MF_BYCOMMAND);
+ }
+
+ CRect cr;
+ GetClientRect(cr);
+ CRect r;
+ m_hdrline.GetClientRect(r);
+ m_hdrline.MapWindowPoints(this, r);
+ r.left = 0;
+ r.right = cr.right;
+ r.bottom+=2;
+ m_hdrline.MoveWindow(r);
+ m_ftrline.GetClientRect(r);
+ m_ftrline.MapWindowPoints(this, r);
+ r.left = 0;
+ r.right = cr.right;
+ r.bottom+=2;
+ m_ftrline.MoveWindow(r);
+
+ m_pVSFRipper = new CVobSubFileRipper();
+
+ CAutoPtr<CVSRipPage> pPage;
+
+ pPage.Attach(new CVSRipFileDlg(m_pVSFRipper));
+ pPage->Create(CVSRipFileDlg::IDD, this);
+ m_dlgs.AddTail(pPage);
+
+ pPage.Attach(new CVSRipPGCDlg(m_pVSFRipper));
+ pPage->Create(CVSRipPGCDlg::IDD, this);
+ m_dlgs.AddTail(pPage);
+
+ pPage.Attach(new CVSRipIndexingDlg(m_pVSFRipper));
+ pPage->Create(CVSRipIndexingDlg::IDD, this);
+ m_dlgs.AddTail(pPage);
+
+ if(__argc > 1)
+ {
+ m_pVSFRipper->SetCallBack((IVSFRipperCallback*)m_dlgs.GetTail());
+
+ if(S_OK != m_pVSFRipper->LoadParamFile(CString(__targv[1])))
+ {
+ AfxMessageBox(_T("Error parsing parameter file!"), MB_OK);
+ EndDialog(IDCANCEL);
+ return FALSE;
+ }
+
+ ShowPrev();
+ }
+ else
+ {
+ ShowNext();
+ }
+
+ return TRUE; // return TRUE unless you set the focus to a control
+}
+
+// If you add a minimize button to your dialog, you will need the code below
+// to draw the icon. For MFC applications using the document/view model,
+// this is automatically done for you by the framework.
+
+void CVSRipDlg::OnPaint()
+{
+ if (IsIconic())
+ {
+ CPaintDC dc(this); // device context for painting
+
+ SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
+
+ // Center icon in client rectangle
+ int cxIcon = GetSystemMetrics(SM_CXICON);
+ int cyIcon = GetSystemMetrics(SM_CYICON);
+ CRect rect;
+ GetClientRect(&rect);
+ int x = (rect.Width() - cxIcon + 1) / 2;
+ int y = (rect.Height() - cyIcon + 1) / 2;
+
+ // Draw the icon
+ dc.DrawIcon(x, y, m_hIcon);
+ }
+ else
+ {
+ CPaintDC dc(this); // device context for painting
+
+ CWnd* pHdrSep = GetDlgItem(IDC_HEADERSEP);
+ CRect r;
+ m_hdrline.GetClientRect(r);
+ m_hdrline.MapWindowPoints(this, r);
+ CRect cr;
+ GetClientRect(cr);
+ dc.FillSolidRect(CRect(0,0,cr.right,r.top), 0xffffff);
+
+ if(m_dlgpos)
+ {
+ CVSRipPage* pWnd = m_dlgs.GetAt(m_dlgpos);
+ CFont hdrfont, descfont;
+ hdrfont.CreateFont(16,0,0,0,FW_BOLD,0,0,0,DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH,
+ _T("Times New Roman"));
+ descfont.CreateFont(14,0,0,0,FW_NORMAL,0,0,0,DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH,
+ _T("Arial"));
+ CFont* pOld = dc.SelectObject(&hdrfont);
+ dc.DrawText(pWnd->GetHeaderText(), CRect(10,5,cr.right,r.top), DT_WORDBREAK);
+ dc.SelectObject(&descfont);
+ dc.DrawText(pWnd->GetDescText(), CRect(20,22,cr.right,r.top), DT_WORDBREAK);
+ dc.SelectObject(pOld);
+ }
+
+ CDialog::OnPaint();
+ }
+}
+
+void CVSRipDlg::OnKickIdle()
+{
+ UpdateDialogControls(this, false);
+
+ for(CWnd* pChild = GetWindow(GW_CHILD); pChild; pChild = pChild->GetNextWindow())
+ {
+ if(pChild->IsKindOf(RUNTIME_CLASS(CVSRipPage)))
+ pChild->UpdateDialogControls(pChild, false);
+ }
+}
+
+// The system calls this function to obtain the cursor to display while the user drags
+// the minimized window.
+HCURSOR CVSRipDlg::OnQueryDragIcon()
+{
+ return static_cast<HCURSOR>(m_hIcon);
+}
+
+void CVSRipDlg::OnPrev()
+{
+ ShowPrev();
+}
+
+void CVSRipDlg::OnUpdatePrev(CCmdUI* pCmdUI)
+{
+ if(m_dlgpos) pCmdUI->SetText(m_dlgs.GetAt(m_dlgpos)->GetPrevText());
+ pCmdUI->Enable(!!GetPrev());
+}
+
+void CVSRipDlg::OnNext()
+{
+ ShowNext();
+}
+
+void CVSRipDlg::OnUpdateNext(CCmdUI* pCmdUI)
+{
+ if(m_dlgpos) pCmdUI->SetText(m_dlgs.GetAt(m_dlgpos)->GetNextText());
+ pCmdUI->Enable(!!GetNext());
+}
+
+void CVSRipDlg::OnClose()
+{
+ if(m_dlgpos) m_dlgs.GetAt(m_dlgpos)->OnClose();
+
+ OnCancel();
+}
+
+void CVSRipDlg::OnUpdateClose(CCmdUI* pCmdUI)
+{
+ if(m_dlgpos) pCmdUI->SetText(m_dlgs.GetAt(m_dlgpos)->GetCloseText());
+ pCmdUI->Enable(!m_dlgpos || m_dlgs.GetAt(m_dlgpos)->CanClose());
+}
diff --git a/src/apps/vsrip/VSRipDlg.h b/src/apps/vsrip/VSRipDlg.h
new file mode 100644
index 000000000..9e6067e45
--- /dev/null
+++ b/src/apps/vsrip/VSRipDlg.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "VSRipFileDlg.h"
+#include "VSRipPGCDlg.h"
+#include "VSRipIndexingDlg.h"
+
+// CVSRipDlg dialog
+class CVSRipDlg : public CDialog
+{
+// Construction
+public:
+ CVSRipDlg(CWnd* pParent = NULL); // standard constructor
+ virtual ~CVSRipDlg();
+
+// Dialog Data
+ enum { IDD = IDD_VSRIP_DIALOG };
+
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+
+// Implementation
+protected:
+ HICON m_hIcon;
+
+ CStatic m_dlgrect;
+ CStatic m_hdrline;
+
+ CAutoPtrList<CVSRipPage> m_dlgs;
+ POSITION m_dlgpos;
+ void ShowNext(), ShowPrev();
+ POSITION GetNext(), GetPrev();
+
+ CComPtr<IVSFRipper> m_pVSFRipper;
+
+ // Generated message map functions
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnPaint();
+ afx_msg void OnKickIdle();
+ afx_msg HCURSOR OnQueryDragIcon();
+ afx_msg void OnPrev();
+ afx_msg void OnUpdatePrev(CCmdUI* pCmdUI);
+ afx_msg void OnNext();
+ afx_msg void OnUpdateNext(CCmdUI* pCmdUI);
+ afx_msg void OnClose();
+ afx_msg void OnUpdateClose(CCmdUI* pCmdUI);
+ CStatic m_ftrline;
+};
diff --git a/src/apps/vsrip/VSRipFileDlg.cpp b/src/apps/vsrip/VSRipFileDlg.cpp
new file mode 100644
index 000000000..6ae7e0afc
--- /dev/null
+++ b/src/apps/vsrip/VSRipFileDlg.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// VSRipFileDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "VSRip.h"
+#include <atlcoll.h>
+#include "..\..\..\include\winddk\devioctl.h"
+#include "..\..\..\include\winddk\ntddcdrm.h"
+#include "VSRipFileDlg.h"
+
+
+// CVSRipFileDlg dialog
+
+IMPLEMENT_DYNAMIC(CVSRipFileDlg, CVSRipPage)
+CVSRipFileDlg::CVSRipFileDlg(IVSFRipper* pVSFRipper, CWnd* pParent /*=NULL*/)
+ : CVSRipPage(pVSFRipper, CVSRipFileDlg::IDD, pParent)
+{
+}
+
+CVSRipFileDlg::~CVSRipFileDlg()
+{
+}
+
+void CVSRipFileDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CVSRipPage::DoDataExchange(pDX);
+ DDX_Text(pDX, IDC_EDIT1, m_infn);
+ DDX_Text(pDX, IDC_EDIT2, m_outfn);
+ DDX_Control(pDX, IDC_EDIT3, m_log);
+}
+
+BEGIN_MESSAGE_MAP(CVSRipFileDlg, CVSRipPage)
+ ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
+ ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
+END_MESSAGE_MAP()
+
+STDMETHODIMP CVSRipFileDlg::OnMessage(LPCTSTR msg)
+{
+ if(CEdit* pLog = (CEdit*)CEdit::FromHandle(m_log.m_hWnd))
+ {
+ CString str = msg;
+ str += _T("\r\n");
+ int len = pLog->GetWindowTextLength();
+ pLog->SetSel(len, len);
+ pLog->ReplaceSel(str);
+ }
+
+ return S_OK;
+}
+
+// CVSRipFileDlg message handlers
+
+void CVSRipFileDlg::OnBnClickedButton1()
+{
+ CFileDialog fd(TRUE, NULL, NULL,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_PATHMUSTEXIST,
+ _T("Video Title Set IFO file (*.ifo)|*.ifo|"), this, 0);
+
+ if(fd.DoModal() == IDOK)
+ {
+ m_log.SetWindowText(_T(""));
+ m_log.SetMargins(0, 0);
+
+ CString fn = fd.GetPathName();
+ if(FAILED(m_pVSFRipper->SetInput(fn))) fn.Empty();
+ m_infn = fn;
+
+ UpdateData(FALSE);
+ }
+
+}
+
+void CVSRipFileDlg::OnBnClickedButton2()
+{
+ CString fn = m_infn.Mid(m_infn.ReverseFind('\\')+1);
+ int i = fn.ReverseFind('.');
+ if(i > 0) fn = fn.Left(i);
+
+ CFileDialog fd(FALSE, NULL, fn,
+ OFN_EXPLORER|OFN_ENABLESIZING|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST,
+ _T("VobSub index file (*.idx)|*.idx|"), this, 0);
+
+ if(fd.DoModal() == IDOK)
+ {
+ CString fn = fd.GetPathName();
+ if(FAILED(m_pVSFRipper->SetOutput(fn))) fn.Empty();
+ m_outfn = fn;
+
+ UpdateData(FALSE);
+ }
+}
diff --git a/src/apps/vsrip/VSRipFileDlg.h b/src/apps/vsrip/VSRipFileDlg.h
new file mode 100644
index 000000000..15d00784e
--- /dev/null
+++ b/src/apps/vsrip/VSRipFileDlg.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include <afxwin.h>
+#include "VSRipPage.h"
+#include "afxwin.h"
+
+// CVSRipFileDlg dialog
+
+class CVSRipFileDlg : public CVSRipPage
+{
+ DECLARE_DYNAMIC(CVSRipFileDlg)
+
+protected:
+ // IVSFRipperCallback
+ STDMETHODIMP OnMessage(LPCTSTR msg);
+
+public:
+ CVSRipFileDlg(IVSFRipper* pVSFRipper, CWnd* pParent = NULL); // standard constructor
+ virtual ~CVSRipFileDlg();
+
+ virtual bool CanGoPrev() {return(false);}
+ virtual bool CanGoNext() {return(!m_infn.IsEmpty() && !m_outfn.IsEmpty());}
+ virtual CString GetHeaderText() {return(_T("Select input and output"));}
+ virtual CString GetDescText() {return(_T("First choose a video title set ifo, then select an ")
+ _T("output path for the idx/sub files. Make sure the vob files ")
+ _T("have some standard naming, this util can't read your mind."));}
+
+// Dialog Data
+ enum { IDD = IDD_DIALOG_FILE };
+ CEdit m_log;
+ CString m_infn, m_outfn;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnBnClickedButton1();
+ afx_msg void OnBnClickedButton2();
+};
diff --git a/src/apps/vsrip/VSRipIndexingDlg.cpp b/src/apps/vsrip/VSRipIndexingDlg.cpp
new file mode 100644
index 000000000..dd5983cfb
--- /dev/null
+++ b/src/apps/vsrip/VSRipIndexingDlg.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// VSRipIndexingDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include <afxpriv.h>
+#include "VSRip.h"
+#include "VSRipIndexingDlg.h"
+
+// CVSRipIndexingDlg dialog
+
+IMPLEMENT_DYNAMIC(CVSRipIndexingDlg, CVSRipPage)
+CVSRipIndexingDlg::CVSRipIndexingDlg(IVSFRipper* pVSFRipper, CWnd* pParent /*=NULL*/)
+ : CVSRipPage(pVSFRipper, CVSRipIndexingDlg::IDD, pParent)
+ , m_bBeep(FALSE), m_bExit(FALSE)
+ , m_fFinished(false)
+ , m_fAuto(false)
+{
+}
+
+CVSRipIndexingDlg::~CVSRipIndexingDlg()
+{
+}
+
+void CVSRipIndexingDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CVSRipPage::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_PROGRESS1, m_progress);
+ DDX_Control(pDX, IDC_EDIT1, m_log);
+ DDX_Check(pDX, IDC_CHECK1, m_bExit);
+ DDX_Check(pDX, IDC_CHECK2, m_bBeep);
+}
+
+STDMETHODIMP CVSRipIndexingDlg::OnMessage(LPCTSTR msg)
+{
+ if(CEdit* pLog = (CEdit*)CEdit::FromHandle(m_log.m_hWnd))
+ {
+ CString str = msg;
+ str += _T("\r\n");
+ int len = pLog->GetWindowTextLength();
+ pLog->SetSel(len, len);
+ pLog->ReplaceSel(str);
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP CVSRipIndexingDlg::OnProgress(double progress)
+{
+ if(CProgressCtrl* pProgress = (CProgressCtrl*)CProgressCtrl::FromHandle(m_progress.m_hWnd))
+ {
+ pProgress->SetPos((int)(progress * 100));
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP CVSRipIndexingDlg::OnFinished(bool fSucceeded)
+{
+ m_fFinished = fSucceeded;
+
+ GetParent()->PostMessage(WM_KICKIDLE); // and kick it hard :)
+
+ if(m_fFinished && m_bBeep) MessageBeep(-1);
+ if(m_fFinished && m_bExit) GetParent()->PostMessage(WM_COMMAND, IDCANCEL);
+
+ if(!fSucceeded)
+ {
+ VSFRipperData rd;
+ m_pVSFRipper->GetRipperData(rd);
+ if(rd.fCloseIgnoreError) GetParent()->PostMessage(WM_COMMAND, IDCANCEL);
+ }
+
+ return S_OK;
+}
+
+BEGIN_MESSAGE_MAP(CVSRipIndexingDlg, CVSRipPage)
+ ON_BN_CLICKED(IDC_BUTTON1, OnIndex)
+ ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateIndex)
+ ON_WM_SHOWWINDOW()
+ ON_BN_CLICKED(IDC_CHECK2, OnBnClickedCheck2)
+ ON_BN_CLICKED(IDC_CHECK1, OnBnClickedCheck1)
+END_MESSAGE_MAP()
+
+
+// CVSRipIndexingDlg message handlers
+
+void CVSRipIndexingDlg::OnIndex()
+{
+ if(S_OK == m_pVSFRipper->IsIndexing())
+ {
+ m_pVSFRipper->Abort(false);
+ }
+ else
+ {
+ m_progress.SetRange(0, 100);
+ m_progress.SetPos(0);
+ m_log.SetWindowText(_T(""));
+ m_log.SetMargins(0, 0);
+
+ m_pVSFRipper->Index();
+ }
+
+ GetParent()->PostMessage(WM_KICKIDLE); // and kick it hard :)
+}
+
+void CVSRipIndexingDlg::OnUpdateIndex(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetText(S_OK == m_pVSFRipper->IsIndexing() ? _T("&Stop") : _T("Re&start"));
+}
+
+void CVSRipIndexingDlg::OnShowWindow(BOOL bShow, UINT nStatus)
+{
+ __super::OnShowWindow(bShow, nStatus);
+
+ m_fFinished = false;
+
+ if(bShow)
+ {
+ VSFRipperData rd;
+ m_pVSFRipper->GetRipperData(rd);
+ m_bBeep = rd.fBeep;
+ m_bExit = rd.fClose;
+ m_fAuto = rd.fAuto;
+ UpdateData(FALSE);
+
+ if(S_OK != m_pVSFRipper->IsIndexing())
+ {
+ if(!m_fAuto)
+ {
+ m_progress.SetRange(0, 100);
+ m_progress.SetPos(0);
+ m_log.SetWindowText(_T(""));
+ m_log.SetMargins(0, 0);
+ }
+
+ m_pVSFRipper->Index();
+ }
+ }
+ else
+ {
+ VSFRipperData rd;
+ m_pVSFRipper->GetRipperData(rd);
+ UpdateData();
+ rd.fBeep = !m_bBeep;
+ rd.fClose = !!m_bExit;
+ m_pVSFRipper->UpdateRipperData(rd);
+ }
+}
+
+void CVSRipIndexingDlg::OnBnClickedCheck2()
+{
+ UpdateData();
+}
+
+void CVSRipIndexingDlg::OnBnClickedCheck1()
+{
+ UpdateData();
+}
diff --git a/src/apps/vsrip/VSRipIndexingDlg.h b/src/apps/vsrip/VSRipIndexingDlg.h
new file mode 100644
index 000000000..4fbf120cb
--- /dev/null
+++ b/src/apps/vsrip/VSRipIndexingDlg.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "VSRipPage.h"
+
+// CVSRipIndexingDlg dialog
+
+class CVSRipIndexingDlg : public CVSRipPage
+{
+ DECLARE_DYNAMIC(CVSRipIndexingDlg)
+
+private:
+ BOOL m_bBeep, m_bExit;
+ bool m_fAuto;
+
+protected:
+ // IVSFRipperCallback
+ STDMETHODIMP OnMessage(LPCTSTR msg);
+ STDMETHODIMP OnProgress(double progress /*0->1*/);
+ STDMETHODIMP OnFinished(bool fSucceeded);
+
+public:
+ CVSRipIndexingDlg(IVSFRipper* pVSFRipper, CWnd* pParent = NULL); // standard constructor
+ virtual ~CVSRipIndexingDlg();
+
+ virtual bool CanGoPrev() {return(S_OK != m_pVSFRipper->IsIndexing() && !m_fAuto);}
+ virtual bool CanGoNext() {return(false);}
+ virtual bool CanClose() {return(S_OK != m_pVSFRipper->IsIndexing());}
+ virtual CString GetCloseText() {return(m_fFinished ? _T("&Close") : _T("&Cancel"));}
+ virtual CString GetHeaderText() {return(_T("Extracting subtitles"));}
+ virtual CString GetDescText() {return(_T("This may take a while, please sit back and relax... ")
+ _T("If you wish you can abort the process and go back to ")
+ _T("adjust the settings again."));}
+
+ bool m_fFinished;
+
+// Dialog Data
+ enum { IDD = IDD_DIALOG_INDEXING };
+
+ CEdit m_log;
+ CProgressCtrl m_progress;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+ DECLARE_MESSAGE_MAP()
+
+public:
+ afx_msg void OnIndex();
+ afx_msg void OnUpdateIndex(CCmdUI* pCmdUI);
+ afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
+ afx_msg void OnBnClickedCheck2();
+ afx_msg void OnBnClickedCheck1();
+};
diff --git a/src/apps/vsrip/VSRipPGCDlg.cpp b/src/apps/vsrip/VSRipPGCDlg.cpp
new file mode 100644
index 000000000..01b02b13e
--- /dev/null
+++ b/src/apps/vsrip/VSRipPGCDlg.cpp
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// VSRipPGCDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include <atlcoll.h>
+#include "VSRip.h"
+#include "VSRipPGCDlg.h"
+#include "..\..\subtitles\VobSubFile.h"
+
+
+// CVSRipPGCDlg dialog
+
+IMPLEMENT_DYNAMIC(CVSRipPGCDlg, CVSRipPage)
+CVSRipPGCDlg::CVSRipPGCDlg(IVSFRipper* pVSFRipper, CWnd* pParent /*=NULL*/)
+ : CVSRipPage(pVSFRipper, CVSRipPGCDlg::IDD, pParent)
+ , m_bResetTime(TRUE)
+ , m_bClosedCaption(FALSE)
+ , m_bForcedOnly(FALSE)
+{
+ m_rd.Reset();
+}
+
+CVSRipPGCDlg::~CVSRipPGCDlg()
+{
+}
+
+void CVSRipPGCDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CVSRipPage::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_LIST1, m_pgclist);
+ DDX_Control(pDX, IDC_LIST2, m_anglelist);
+ DDX_Control(pDX, IDC_LIST3, m_vclist);
+ DDX_Control(pDX, IDC_LIST4, m_langlist);
+ DDX_Check(pDX, IDC_CHECK1, m_bResetTime);
+ DDX_Check(pDX, IDC_CHECK2, m_bClosedCaption);
+ DDX_Check(pDX, IDC_CHECK3, m_bForcedOnly);
+}
+
+void CVSRipPGCDlg::OnPrev()
+{
+ OnNext();
+}
+
+void CVSRipPGCDlg::OnNext()
+{
+ CAutoVectorPtr<int> items;
+
+ m_rd.iSelPGC = m_pgclist.GetCurSel();
+
+ m_rd.selids.RemoveAll();
+ if(items.Allocate(m_langlist.GetSelCount()))
+ {
+ int j = m_langlist.GetSelItems(m_langlist.GetSelCount(), items);
+ for(int i = 0; i < j; i++)
+ m_rd.selids[(BYTE)m_langlist.GetItemData(items[i])] = true;
+ items.Free();
+ }
+
+ m_rd.pgcs[m_rd.iSelPGC].iSelAngle = m_anglelist.GetCurSel();
+
+ m_rd.selvcs.RemoveAll();
+ if(items.Allocate(m_vclist.GetSelCount()))
+ {
+ int j = m_vclist.GetSelItems(m_vclist.GetSelCount(), items);
+ for(int i = 0; i < j; i++)
+ m_rd.selvcs.Add((DWORD)m_vclist.GetItemData(items[i]));
+ items.Free();
+ }
+
+ m_rd.fClosedCaption = !!m_bClosedCaption;
+ m_rd.fResetTime = !!m_bResetTime;
+ m_rd.fForcedOnly = !!m_bForcedOnly;
+
+ m_pVSFRipper->UpdateRipperData(m_rd);
+}
+
+bool CVSRipPGCDlg::CanGoNext()
+{
+ UpdateData();
+
+ return(m_pgclist.GetCurSel() >= 0
+ && m_anglelist.GetCurSel() >= 0
+ && m_vclist.GetSelCount() > 0
+ && (m_langlist.GetSelCount() > 0 || m_bClosedCaption));
+}
+
+void CVSRipPGCDlg::SetupPGCList()
+{
+ ASSERT(m_rd.iSelPGC >= 0);
+
+ m_pgclist.ResetContent();
+
+ for(int i = 0; i < m_rd.pgcs.GetCount(); i++)
+ {
+ CString str;
+ str.Format(_T("PGC %d"), i+1);
+ m_pgclist.AddString(str);
+ }
+
+ m_pgclist.SetCurSel(m_rd.iSelPGC);
+
+ SetupLangList();
+ SetupAngleList();
+}
+
+void CVSRipPGCDlg::SetupLangList()
+{
+ m_langlist.ResetContent();
+
+ for(BYTE i = 0; i < 32; i++)
+ {
+ WORD id = m_rd.pgcs[m_rd.iSelPGC].ids[i];
+
+ CString str;
+
+ if(id == 0)
+ {
+ str.Format(_T("%02d (empty)"), (int)i);
+ }
+ else if(!isalpha(id>>8) || !isalpha(id&0xff))
+ {
+ str.Format(_T("%02d (unknown)"), (int)i);
+ }
+ else
+ {
+ str.Format(_T("%02d %s (%c%c)"), (int)i, FindLangFromId(id), TCHAR(id>>8), TCHAR(id&0xff));
+ }
+
+ int j = m_langlist.AddString(str);
+ m_langlist.SetSel(j, !!id);
+ m_langlist.SetItemData(j, (DWORD_PTR)i);
+ }
+
+ m_langlist.SetTopIndex(0);
+}
+
+void CVSRipPGCDlg::SetupAngleList()
+{
+ m_anglelist.ResetContent();
+
+ m_rd.pgcs[m_rd.iSelPGC].iSelAngle = m_rd.pgcs[m_rd.iSelPGC].nAngles > 0 ? 1 : 0;
+
+ for(int i = 0; i < 10; i++)
+ {
+ CString str;
+
+ if(i == 0)
+ {
+ str = _T("Everything");
+ }
+ else
+ {
+ str.Format(_T("Angle %d"), i);
+ if(i > m_rd.pgcs[m_rd.iSelPGC].nAngles)
+ str += _T(" (empty)");
+ }
+
+ m_anglelist.AddString(str);
+ }
+
+ m_anglelist.SetCurSel(m_rd.pgcs[m_rd.iSelPGC].iSelAngle);
+
+ SetupVCList();
+}
+
+void CVSRipPGCDlg::SetupVCList()
+{
+ m_vclist.ResetContent();
+
+ CArray<vc_t>& vca = m_rd.pgcs[m_rd.iSelPGC].angles[m_rd.pgcs[m_rd.iSelPGC].iSelAngle];
+
+ for(int i = 0; i < vca.GetCount(); i++)
+ {
+ CString str;
+ str.Format(_T("V%02d C%02d"), vca[i].vob, vca[i].cell);
+
+ DWORD vc = (vca[i].vob<<16)|vca[i].cell;
+
+ int j = m_vclist.AddString(str);
+ m_vclist.SetSel(j, TRUE);
+ m_vclist.SetItemData(j, (DWORD_PTR)vc);
+ }
+
+ m_vclist.SetTopIndex(0);
+}
+
+BEGIN_MESSAGE_MAP(CVSRipPGCDlg, CVSRipPage)
+ ON_LBN_SELCHANGE(IDC_LIST1, OnLbnSelchangeList1)
+ ON_LBN_SELCHANGE(IDC_LIST2, OnLbnSelchangeList2)
+ ON_WM_SHOWWINDOW()
+END_MESSAGE_MAP()
+
+
+// CVSRipPGCDlg message handlers
+
+void CVSRipPGCDlg::OnLbnSelchangeList1()
+{
+ if(m_rd.iSelPGC == m_pgclist.GetCurSel()) return;
+ m_rd.iSelPGC = m_pgclist.GetCurSel();
+ SetupAngleList();
+}
+
+void CVSRipPGCDlg::OnLbnSelchangeList2()
+{
+ if(m_rd.pgcs[m_rd.iSelPGC].iSelAngle == m_anglelist.GetCurSel()) return;
+ m_rd.pgcs[m_rd.iSelPGC].iSelAngle = m_anglelist.GetCurSel();
+ SetupVCList();
+}
+
+void CVSRipPGCDlg::OnShowWindow(BOOL bShow, UINT nStatus)
+{
+ CVSRipPage::OnShowWindow(bShow, nStatus);
+
+ if(!bShow) return;
+
+ m_pVSFRipper->GetRipperData(m_rd);
+
+ if(m_rd.iSelPGC == -1)
+ {
+ m_rd.iSelPGC = 0;
+ SetupPGCList();
+
+ m_bClosedCaption = m_rd.vidinfo.line21_1 || m_rd.vidinfo.line21_2;
+ UpdateData(FALSE);
+ }
+}
diff --git a/src/apps/vsrip/VSRipPGCDlg.h b/src/apps/vsrip/VSRipPGCDlg.h
new file mode 100644
index 000000000..91802b525
--- /dev/null
+++ b/src/apps/vsrip/VSRipPGCDlg.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "VSRipPage.h"
+#include "afxwin.h"
+
+
+// CVSRipPGCDlg dialog
+
+class CVSRipPGCDlg : public CVSRipPage
+{
+ DECLARE_DYNAMIC(CVSRipPGCDlg)
+
+private:
+ VSFRipperData m_rd;
+ void SetupPGCList();
+ void SetupAngleList();
+ void SetupVCList();
+ void SetupLangList();
+
+public:
+ CVSRipPGCDlg(IVSFRipper* pVSFRipper, CWnd* pParent = NULL); // standard constructor
+ virtual ~CVSRipPGCDlg();
+
+ virtual void OnPrev();
+ virtual void OnNext();
+ virtual bool CanGoPrev() {return(true);}
+ virtual bool CanGoNext();
+ virtual CString GetHeaderText() {return(_T("Extraction settings"));}
+ virtual CString GetDescText() {return(_T("Select the program chain and angle you did or ")
+ _T("will do in the dvd ripper. Optionally, remove any not ")
+ _T("needed language streams and vob/cell ids."));}
+
+// Dialog Data
+ enum { IDD = IDD_DIALOG_PGC };
+ CListBox m_pgclist;
+ CListBox m_anglelist;
+ CListBox m_vclist;
+ CListBox m_langlist;
+ BOOL m_bResetTime;
+ BOOL m_bClosedCaption;
+ BOOL m_bForcedOnly;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+ DECLARE_MESSAGE_MAP()
+public:
+ afx_msg void OnLbnSelchangeList1();
+ afx_msg void OnLbnSelchangeList2();
+ afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
+};
diff --git a/src/apps/vsrip/VSRipPage.cpp b/src/apps/vsrip/VSRipPage.cpp
new file mode 100644
index 000000000..d6d2ba1d3
--- /dev/null
+++ b/src/apps/vsrip/VSRipPage.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// VSRipPage.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include <afxpriv.h>
+#include "VSRip.h"
+#include "VSRipPage.h"
+
+// CVSRipPage dialog
+
+IMPLEMENT_DYNAMIC(CVSRipPage, CDialog)
+CVSRipPage::CVSRipPage(IVSFRipper* pVSFRipper, UINT nIDTemplate, CWnd* pParent /*=NULL*/)
+ : CDialog(nIDTemplate, pParent)
+ , m_pVSFRipper(pVSFRipper)
+{
+ m_cRef = 1;
+}
+
+CVSRipPage::~CVSRipPage()
+{
+}
+
+void CVSRipPage::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CVSRipPage, CDialog)
+ ON_WM_SHOWWINDOW()
+END_MESSAGE_MAP()
+
+
+// CVSRipPage message handlers
+
+void CVSRipPage::OnShowWindow(BOOL bShow, UINT nStatus)
+{
+ __super::OnShowWindow(bShow, nStatus);
+
+ m_pVSFRipper->SetCallBack(bShow ? (IVSFRipperCallback*)this : NULL);
+}
+
diff --git a/src/apps/vsrip/VSRipPage.h b/src/apps/vsrip/VSRipPage.h
new file mode 100644
index 000000000..72e50f674
--- /dev/null
+++ b/src/apps/vsrip/VSRipPage.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include <afxtempl.h>
+#include "..\..\subtitles\VobSubFileRipper.h"
+
+// CVSRipPage dialog
+
+class CVSRipPage : public CDialog, public IVSFRipperCallbackImpl
+{
+ DECLARE_DYNAMIC(CVSRipPage)
+
+protected:
+ CComPtr<IVSFRipper> m_pVSFRipper;
+
+public:
+ CVSRipPage(IVSFRipper* pVSFRipper, UINT nIDTemplate, CWnd* pParent = NULL); // standard constructor
+ virtual ~CVSRipPage();
+
+// static bool ParseParamFile(CString fn);
+
+ virtual void OnPrev() {}
+ virtual void OnNext() {}
+ virtual void OnClose() {}
+ virtual bool CanGoPrev() {return(false);}
+ virtual bool CanGoNext() {return(false);}
+ virtual bool CanClose() {return(true);}
+ virtual CString GetPrevText() {return(_T("< &Back"));}
+ virtual CString GetNextText() {return(_T("&Next >"));}
+ virtual CString GetCloseText() {return(_T("&Cancel"));}
+ virtual CString GetHeaderText() {return(_T("Header Text"));}
+ virtual CString GetDescText() {return(_T("Hello World"));}
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+ DECLARE_MESSAGE_MAP()
+public:
+ afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
+};
diff --git a/src/apps/vsrip/res/VSRip.ico b/src/apps/vsrip/res/VSRip.ico
new file mode 100644
index 000000000..8a84ca3d3
--- /dev/null
+++ b/src/apps/vsrip/res/VSRip.ico
Binary files differ
diff --git a/src/apps/vsrip/res/VSRip.manifest b/src/apps/vsrip/res/VSRip.manifest
new file mode 100644
index 000000000..3d1f3b957
--- /dev/null
+++ b/src/apps/vsrip/res/VSRip.manifest
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="X86"
+ name="Microsoft.Windows.VSRip"
+ type="win32"
+/>
+<description>Your app description here</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="X86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+</assembly>
diff --git a/src/apps/vsrip/res/VSRip.rc2 b/src/apps/vsrip/res/VSRip.rc2
new file mode 100644
index 000000000..e8572ddbd
--- /dev/null
+++ b/src/apps/vsrip/res/VSRip.rc2
@@ -0,0 +1,13 @@
+//
+// VSRip.RC2 - resources Microsoft Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/src/apps/vsrip/resource.h b/src/apps/vsrip/resource.h
new file mode 100644
index 000000000..96a8a3219
--- /dev/null
+++ b/src/apps/vsrip/resource.h
@@ -0,0 +1,37 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by VSRip.rc
+//
+#define IDR_MANIFEST 1
+#define IDD_VSRIP_DIALOG 102
+#define IDR_MAINFRAME 128
+#define IDD_DIALOG_FILE 129
+#define IDD_DIALOG_PGC 130
+#define IDD_DIALOG_INDEXING 131
+#define IDC_BUTTON1 1000
+#define IDC_BUTTON2 1001
+#define IDC_HEADERSEP 1002
+#define IDC_DLGRECT 1003
+#define IDC_CHECK1 1004
+#define IDC_EDIT1 1005
+#define IDC_LIST1 1007
+#define IDC_LIST2 1008
+#define IDC_PROGRESS1 1009
+#define IDC_LIST3 1010
+#define IDC_LIST4 1011
+#define IDC_CHECK2 1012
+#define IDC_FOOTERSEP 1013
+#define IDC_EDIT2 1014
+#define IDC_CHECK3 1015
+#define IDC_EDIT3 1017
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 132
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1018
+#define _APS_NEXT_SYMED_VALUE 104
+#endif
+#endif
diff --git a/src/apps/vsrip/stdafx.cpp b/src/apps/vsrip/stdafx.cpp
new file mode 100644
index 000000000..958e3681c
--- /dev/null
+++ b/src/apps/vsrip/stdafx.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// stdafx.cpp : source file that includes just the standard includes
+// VSRip.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
diff --git a/src/apps/vsrip/stdafx.h b/src/apps/vsrip/stdafx.h
new file mode 100644
index 000000000..291cf4180
--- /dev/null
+++ b/src/apps/vsrip/stdafx.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2003-2005 Gabest
+ * http://www.gabest.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+#endif
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
+#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
+#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
+#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.
+#endif
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
+
+// turns off MFC's hiding of some common and often safely ignored warning messages
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <streams.h>
+