yoshy - 0.2.1.0 trunk を stable-0.2 branche に反映
@@ -1,48 +0,0 @@ | ||
1 | -foo_mixi_feat_winamp 0.0.0.7, | |
2 | -Mixi Music plugin for Winamp, bridge component. | |
3 | -Copyright (C) 2006,2007 Yossiepon Oniichan, All Rights Reserved. | |
4 | - | |
5 | - | |
6 | -* Copying | |
7 | - | |
8 | - This program is free software: you can redistribute it and/or modify | |
9 | - it under the terms of the GNU Lesser General Public License as | |
10 | - published by the Free Software Foundation, either version 3 of | |
11 | - the License, or (at your option) any later version. | |
12 | - | |
13 | - This program is distributed in the hope that it will be useful, | |
14 | - but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | - GNU Lesser General Public License for more details. | |
17 | - | |
18 | - You should have received a copy of the GNU Lesser General Public License | |
19 | - along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 | - | |
21 | - Please see the file COPYING and COPYING.LESSER in this directory for | |
22 | - full copyright information. | |
23 | - | |
24 | - | |
25 | -* Compilation and Installation | |
26 | - | |
27 | - Please read INSTALL for compilation instructions. | |
28 | - | |
29 | - | |
30 | -* See also | |
31 | - | |
32 | - The latest version of foo_mixi_feat_winamp can be obtained at | |
33 | - http://foo-mixi.sourceforge.net/ | |
34 | - | |
35 | - There are two mailing lists | |
36 | - foo-mixi-users@lists.sourceforge.jp | |
37 | - foo-mixi-dev@lists.sourceforge.jp | |
38 | - | |
39 | - please follow the link in | |
40 | - | |
41 | - http://sourceforge.jp/projects/foo-mixi | |
42 | - | |
43 | - to subscribe to the lists or to visit the archives. | |
44 | - | |
45 | - | |
46 | -Enjoy, | |
47 | - | |
48 | -Yossiepon Oniichan (yoshy at users.sourceforge.jp) (06 November 2007) |
@@ -1,58 +0,0 @@ | ||
1 | -//{{NO_DEPENDENCIES}} | |
2 | -// Microsoft Visual C++ generated include file. | |
3 | -// Used by foo_mixi_feat_winamp.rc | |
4 | -// | |
5 | -#define IDD_PREFERENCE 101 | |
6 | -#define IDD_ADVANCED_SETTINGS 102 | |
7 | -#define IDD_DEBUG_SETTINGS 103 | |
8 | -#define IDC_CONFIGURE 1000 | |
9 | -#define IDC_USE_PLUGIN 1001 | |
10 | -#define IDC_VERSION 1002 | |
11 | -#define IDC_BUILD 1003 | |
12 | -#define IDC_SEND_INTERVAL_1ST 1004 | |
13 | -#define IDC_SEND_INTERVAL_2ND 1005 | |
14 | -#define IDC_SEND_INTERVAL_SLIDER_2ND 1006 | |
15 | -#define IDC_SEND_INTERVAL_SLIDER_1ST 1007 | |
16 | -#define IDC_DISABLE_DUPLICATE_SONG 1008 | |
17 | -#define IDC_DISABLE_DUMMY_MP3 1009 | |
18 | -#define IDC_SEND_INTERVAL_SLIDER_3RD 1010 | |
19 | -#define IDC_SEND_INTERVAL_3RD 1011 | |
20 | -#define IDC_CAPTION_ADVANCED 1012 | |
21 | -#define IDC_DUMMY_MP3_LOCATION 1013 | |
22 | -#define IDC_VERSION_ADVANCED 1014 | |
23 | -#define IDC_BUILD_ADVANCED 1015 | |
24 | -#define IDC_MEDIA_LIBRARY_REGISTERED_FILE_ONLY 1016 | |
25 | -#define IDC_EXPLICITLY_TAGGED_FILE_ONLY 1017 | |
26 | -#define IDC_GEN_MIXI_PATH 1018 | |
27 | -#define IDC_GEN_MIXI_PATH_REF 1019 | |
28 | -#define IDC_CAPTION_DEBUG 1020 | |
29 | -#define IDC_ENABLE_DEBUG_LOG 1021 | |
30 | -#define IDC_DEBUG_DUMMYAMP_INIT 1022 | |
31 | -#define IDC_DEBUG_DUMMYAMP_PROC 1023 | |
32 | -#define IDC_DEBUG_TRACK_INFO 1024 | |
33 | -#define IDC_DEBUG_PLUGIN 1025 | |
34 | -#define IDC_DEBUG_CALLBACK 1026 | |
35 | -#define IDC_VERSION_DEBUG 1027 | |
36 | -#define IDC_BUILD_DEBUG 1028 | |
37 | -#define IDC_SHOW_DUMMYAMP 1029 | |
38 | -#define IDC_DUMMYAMP_TITLE_FORMAT 1030 | |
39 | -#define IDC_DUMMYAMP_PLAYLIST_FORMAT 1031 | |
40 | -#define IDC_DISABLE_ANSI_TRANS 1032 | |
41 | -#define IDC_ENABLE_EXT_IPC_PROC 1033 | |
42 | -#define IDC_DUMMYAMP_FRAME 1034 | |
43 | -#define IDC_ENABLE_STREAMING_FILE 1035 | |
44 | -#define IDC_NO_ARTIST_NAME 1036 | |
45 | -#define IDC_NO_TITLE_NAME 1037 | |
46 | -#define IDC_NO_ALBUM_NAME 1038 | |
47 | -#define IDC_NO_GENRE_NAME 1039 | |
48 | - | |
49 | -// Next default values for new objects | |
50 | -// | |
51 | -#ifdef APSTUDIO_INVOKED | |
52 | -#ifndef APSTUDIO_READONLY_SYMBOLS | |
53 | -#define _APS_NEXT_RESOURCE_VALUE 104 | |
54 | -#define _APS_NEXT_COMMAND_VALUE 40001 | |
55 | -#define _APS_NEXT_CONTROL_VALUE 1040 | |
56 | -#define _APS_NEXT_SYMED_VALUE 101 | |
57 | -#endif | |
58 | -#endif |
@@ -1,4309 +0,0 @@ | ||
1 | -#define BUILD_UNICODE | |
2 | - | |
3 | -#if defined(BUILD_UNICODE) | |
4 | -#if !defined(UNICODE) | |
5 | -#define _UNICODE | |
6 | -#define UNICODE | |
7 | -#endif | |
8 | -#endif | |
9 | - | |
10 | -#if defined(UNICODE) && !defined(BUILD_UNICODE) | |
11 | -#define BUILD_UNICODE | |
12 | -#endif | |
13 | - | |
14 | -#define LONG_PTR_TO_WNDPROC(p) (reinterpret_cast<WNDPROC>(p)) | |
15 | -#define WNDPROC_TO_LONG_PTR(p) (reinterpret_cast<LONG_PTR>(p)) | |
16 | - | |
17 | -#include <windows.h> | |
18 | -#include <lmcons.h> | |
19 | -#include <process.h> | |
20 | -#include <shlobj.h> | |
21 | - | |
22 | -#include <string> | |
23 | -#include <vector> | |
24 | -#include <map> | |
25 | - | |
26 | -typedef std::vector<std::string> Strings; | |
27 | -typedef Strings::iterator StringsIt; | |
28 | -typedef Strings::const_iterator StringsCIt; | |
29 | - | |
30 | -typedef std::map<std::string, std::string> StringMap; | |
31 | -typedef StringMap::iterator StringMapIt; | |
32 | -typedef StringMap::const_iterator StringMapCIt; | |
33 | - | |
34 | -typedef std::map<std::string, UINT> UIntMap; | |
35 | -typedef UIntMap::iterator UIntMapIt; | |
36 | -typedef UIntMap::const_iterator UIntMapCIt; | |
37 | - | |
38 | -#include "../SDK/foobar2000.h" | |
39 | -#include "../helpers/helpers.h" | |
40 | - | |
41 | -#if 0 | |
42 | -#include <wx/string.h> | |
43 | -#endif | |
44 | - | |
45 | -#include "GEN.h" | |
46 | -#include "wa_ipc.h" | |
47 | - | |
48 | -#if 0 | |
49 | -#define ID3LIB_LINKOPTION 3 | |
50 | -#include <id3/tag.h> | |
51 | -#include <id3/misc_support.h> | |
52 | -#endif | |
53 | - | |
54 | -#include "resource.h" | |
55 | - | |
56 | -#if defined(_FOOBAR2000_UTF8API_H_) | |
57 | -# define FB2K_MAJOR_VERSION 8 | |
58 | -#else | |
59 | -# define FB2K_MAJOR_VERSION 9 | |
60 | -#endif | |
61 | - | |
62 | -#define IS_FB2K_VER08 (FB2K_MAJOR_VERSION == 8) | |
63 | -#define IS_FB2K_VER09 (FB2K_MAJOR_VERSION == 9) | |
64 | - | |
65 | -#define FB2K_COMPONENTS_DIR _T("components\\") | |
66 | -#define GEN_MIXI_FILE_NAME _T("gen_mixi_for_winamp.dll") | |
67 | -#define GEN_MIXI_FUNC_NAME_GET_GENERAL_PURPOSE_PLUGIN "winampGetGeneralPurposePlugin" | |
68 | - | |
69 | -#define DUMMY_MP3_FILE_NAME _T("foo_mixi_feat_winamp.mp3") | |
70 | -#define APPDATA_MIXI_STATION_DIR _T("\\mixi\\mixi") | |
71 | -#define DEFAULT_WINAMP_TITLE "Winamp" | |
72 | -#define DEFAULT_DUMMYAMP_TITLE "DummyAmp" | |
73 | - | |
74 | -#define CODEC_TYPE_VORBIS "Vorbis" | |
75 | -#define CODEC_TYPE_MP3 "MP3" | |
76 | - | |
77 | -#define IS_SUPPORTED_FORMAT_BY_GEN_MIXI(codec) ( !::lstrcmpA(codec, CODEC_TYPE_VORBIS) || !::lstrcmpA(codec, CODEC_TYPE_MP3)) | |
78 | - | |
79 | -#if !defined(ENABLE_MSN) | |
80 | -#define PLUGIN_CAPTION "mixi music plugin for Winamp, bridge component" | |
81 | -#define PLUGIN_CAPTION_JP "mixi ミュージック" | |
82 | -#else | |
83 | -#define PLUGIN_CAPTION "Mixi Music plugin for M2M" | |
84 | -#endif | |
85 | - | |
86 | -#define ADVANCED_SETTINGS_CAPTION "高度な設定" | |
87 | -#define DUMMYAMP_FRAME_CAPTION _T("DummyAmp の設定 (動作状態:%s)") | |
88 | -#define DUMMYAMP_BEFORE_INIT_MODE _T("初回再生の待機中") | |
89 | -#define DUMMYAMP_HOOK_MODE _T("既存 Winamp API Emulator をフック中") | |
90 | -#define DUMMYAMP_STANDALONE_MODE _T("単独で Winamp API をエミュレート中") | |
91 | -#define DEBUG_SETTINGS_CAPTION "デバッグ用の設定" | |
92 | -#define PLUGIN_VERSION "0.2.0.1" | |
93 | - | |
94 | -#define DEFAULT_DUMMYAMP_TITLE_FORMAT "[%artist% - ]$if(%title%,%title%,%_filename%)" | |
95 | - | |
96 | -#define URL_FOO_MIXI_HOME "http://foo-mixi.sourceforge.jp/" | |
97 | - | |
98 | -#define FORMAT_FILEPATH "%_path%" | |
99 | -#define FORMAT_FILEPATHRAW "%_path_raw%" | |
100 | -#define FORMAT_ARTIST "%artist%" | |
101 | -#define FORMAT_TRACKTITLE "%title%" | |
102 | -#define FORMAT_ALBUMTITLE "%album%" | |
103 | -#define FORMAT_GENRE "%genre%" | |
104 | -#define FORMAT_CODEC "%__codec%" | |
105 | - | |
106 | -#if IS_FB2K_VER08 | |
107 | -#define FORMAT_LISTINDEX "%_playlist_number%" | |
108 | -#elif IS_FB2K_VER09 | |
109 | -#define FORMAT_LISTINDEX "%list_index%" | |
110 | -#endif | |
111 | - | |
112 | -#define IPC_GETOUTPUTTIME_PositionMSec 0 | |
113 | -#define IPC_GETOUTPUTTIME_TotalSec 1 | |
114 | - | |
115 | -#define IPC_INTERNAL_REFRESHLISTINFO 0x4000 | |
116 | -#define IPC_INTERNAL_REFRESHDYNINFO 0x4001 | |
117 | - | |
118 | -#define RESENT_INTERVAL 5000 | |
119 | -#define FORCE_RESENT_MODE 0 | |
120 | -//#define DISABLE_KICK_GEN_MIXI_LOOP | |
121 | - | |
122 | -#define REQUIRED_MINIMUM_TIME 3 | |
123 | -#define SEND_TIME_RATE_LOWERBOUND 33 | |
124 | -#define REQUIRED_MAXIMUM_TIME 20 | |
125 | - | |
126 | -#define CONTROL_SEND_TIMING | |
127 | - | |
128 | -//#define ENABLE_MSN | |
129 | - | |
130 | -#if IS_FB2K_VER09 | |
131 | -using namespace pfc; | |
132 | -using namespace pfc::stringcvt; | |
133 | -#define pfc_string_to_float string_to_float | |
134 | -#endif | |
135 | - | |
136 | -/* | |
137 | - foo_mixi_feat_winamp: project dependencies | |
138 | - | |
139 | - foo_mixi_feat_winamp | |
140 | - foobar2000_SDK | |
141 | - utf8api(0.8.3) | |
142 | - pfc | |
143 | - foobar2000_sdk_helpers | |
144 | - pfc | |
145 | - foobar2000_component_client(0.9.X) | |
146 | - id3lib | |
147 | - zlib | |
148 | - | |
149 | - library dependencies: wxbase28.lib, id3lib.lib, ../shared/shared.lib(0.9.X) | |
150 | - runtime library: Multi-Thread (DLL) or (Debug,DLL) | |
151 | - !! ensure all projects that depended from this project are correctly set to MT DLL !! | |
152 | - ignore: LIBCMT [Win32 Release] (or LIBCMTD [Win32 Debug]) | |
153 | -*/ | |
154 | - | |
155 | -// if wxWidgets are updated, change lib names below and linker libpath option. | |
156 | - | |
157 | -#if 0 | |
158 | -#if defined(_DEBUG) | |
159 | -#if defined(BUILD_UNICODE) | |
160 | -#pragma comment(lib, "wxbase28ud.lib") | |
161 | -#else | |
162 | -#pragma comment(lib, "wxbase28d.lib") | |
163 | -#endif | |
164 | -#else | |
165 | -#if defined(BUILD_UNICODE) | |
166 | -#pragma comment(lib, "wxbase28u.lib") | |
167 | -#else | |
168 | -#pragma comment(lib, "wxbase28.lib") | |
169 | -#endif | |
170 | -#endif | |
171 | -#endif | |
172 | - | |
173 | -// now id3lib automatically added to linker target, | |
174 | -// because it generated from depended project. | |
175 | -//#pragma comment(lib, "id3lib.lib") | |
176 | - | |
177 | -#if IS_FB2K_VER09 | |
178 | -#pragma comment(lib, "../shared/shared.lib") | |
179 | -#endif | |
180 | - | |
181 | -typedef std::basic_string<TCHAR> tstring; | |
182 | - | |
183 | -typedef TCHAR Str64K[65536]; | |
184 | -typedef char StrDBCS64K[65536]; | |
185 | - | |
186 | -tstring GetErrorMessage(DWORD errCode); | |
187 | -void putLogError(LPCTSTR pMethod, LPCTSTR pErrMsg, DWORD dwErrCode); | |
188 | -void DebugPrint(int severity, LPCTSTR lpszFormat, ...); | |
189 | -void DebugPrintDBCS(int severity, LPCSTR lpszFormat, ...); | |
190 | -void DebugPrint8(int severity, LPCSTR lpszFormat, ...); | |
191 | - | |
192 | -#define LOGLEVEL_NONE 0 | |
193 | -#define LOGLEVEL_WARNING 1 | |
194 | -#define LOGLEVEL_ERROR 2 | |
195 | - | |
196 | -#if IS_FB2K_VER09 | |
197 | -namespace console | |
198 | -{ | |
199 | - enum { | |
200 | - SEVERITY_INFO = 0, | |
201 | - SEVERITY_WARNING = 1, | |
202 | - SEVERITY_CRITICAL = 2 | |
203 | - }; | |
204 | -}; | |
205 | -#endif | |
206 | - | |
207 | -#define LOG_TRACE(f, ...) if(cfg_enable_debug_log) DebugPrint(console::SEVERITY_INFO, f, __VA_ARGS__) | |
208 | -#define LOG_DEBUG(f, ...) if(cfg_enable_debug_log) DebugPrint(console::SEVERITY_INFO, f, __VA_ARGS__) | |
209 | - | |
210 | -#define LOG_TRACE8(f, ...) if(cfg_enable_debug_log) DebugPrint8(console::SEVERITY_INFO, f, __VA_ARGS__) | |
211 | -#define LOG_DEBUG8(f, ...) if(cfg_enable_debug_log) DebugPrint8(console::SEVERITY_INFO, f, __VA_ARGS__) | |
212 | - | |
213 | -#define LOG_TRACE_ANSI(f, ...) if(cfg_enable_debug_log) DebugPrintDBCS(console::SEVERITY_INFO, f, __VA_ARGS__) | |
214 | -#define LOG_DEBUG_ANSI(f, ...) if(cfg_enable_debug_log) DebugPrintDBCS(console::SEVERITY_INFO, f, __VA_ARGS__) | |
215 | - | |
216 | -#define LOG_INFO(f, ...) DebugPrint(console::SEVERITY_INFO, f, __VA_ARGS__) | |
217 | -#define LOG_WARN(f, ...) DebugPrint(console::SEVERITY_WARNING, f, __VA_ARGS__) | |
218 | -#define LOG_ERROR(f, ...) DebugPrint(console::SEVERITY_CRITICAL, f, __VA_ARGS__) | |
219 | - | |
220 | -#if defined(BUILD_UNICODE) | |
221 | -#define TRACE_DBCS(f, ...) if(cfg_enable_debug_log) DebugPrintDBCS(console::SEVERITY_INFO, f, __VA_ARGS__) | |
222 | -#else | |
223 | -#define TRACE_DBCS(f, ...) if(cfg_enable_debug_log) DebugPrint(console::SEVERITY_INFO, f, __VA_ARGS__) | |
224 | -#endif | |
225 | - | |
226 | -#define DEBUG_DUMMYAMP_INIT(f, ...) if(cfg_debug_dummyamp_init >= LOGLEVEL_WARNING) LOG_DEBUG(f, __VA_ARGS__) | |
227 | -#define TRACE_DUMMYAMP_INIT(f, ...) if(cfg_debug_dummyamp_init >= LOGLEVEL_ERROR) LOG_TRACE(f, __VA_ARGS__) | |
228 | - | |
229 | -#define DEBUG_DUMMYAMP_PROC(f, ...) if(cfg_debug_dummyamp_proc >= LOGLEVEL_WARNING) LOG_DEBUG(f, __VA_ARGS__) | |
230 | -#define DEBUG_DUMMYAMP_PROC8(f, ...) if(cfg_debug_dummyamp_proc >= LOGLEVEL_WARNING) LOG_DEBUG8(f, __VA_ARGS__) | |
231 | -#define TRACE_DUMMYAMP_PROC(f, ...) if(cfg_debug_dummyamp_proc >= LOGLEVEL_ERROR) LOG_TRACE(f, __VA_ARGS__) | |
232 | -#define TRACE_DUMMYAMP_PROC8(f, ...) if(cfg_debug_dummyamp_proc >= LOGLEVEL_ERROR) LOG_TRACE8(f, __VA_ARGS__) | |
233 | - | |
234 | -#define DEBUG_TRACK_INFO(f, ...) if(cfg_debug_track_info >= LOGLEVEL_WARNING) LOG_DEBUG(f, __VA_ARGS__) | |
235 | -#define DEBUG_TRACK_INFO8(f, ...) if(cfg_debug_track_info >= LOGLEVEL_WARNING) LOG_DEBUG8(f, __VA_ARGS__) | |
236 | -#define DEBUG_TRACK_INFO_ANSI(f, ...) if(cfg_debug_track_info >= LOGLEVEL_WARNING) LOG_DEBUG_ANSI(f, __VA_ARGS__) | |
237 | -#define TRACE_TRACK_INFO(f, ...) if(cfg_debug_track_info >= LOGLEVEL_ERROR) LOG_TRACE(f, __VA_ARGS__) | |
238 | -#define TRACE_TRACK_INFO8(f, ...) if(cfg_debug_track_info >= LOGLEVEL_ERROR) LOG_TRACE8(f, __VA_ARGS__) | |
239 | -#define TRACE_TRACK_INFO_ANSI(f, ...) if(cfg_debug_track_info >= LOGLEVEL_ERROR) LOG_TRACE_ANSI(f, __VA_ARGS__) | |
240 | - | |
241 | -#define DEBUG_PLUGIN(f, ...) if(cfg_debug_plugin >= LOGLEVEL_WARNING) LOG_DEBUG(f, __VA_ARGS__) | |
242 | -#define TRACE_PLUGIN(f, ...) if(cfg_debug_plugin >= LOGLEVEL_ERROR) LOG_TRACE(f, __VA_ARGS__) | |
243 | - | |
244 | -#define DEBUG_CALLBACK(f, ...) if(cfg_debug_callback >= LOGLEVEL_WARNING) LOG_DEBUG(f, __VA_ARGS__) | |
245 | -#define TRACE_CALLBACK(f, ...) if(cfg_debug_callback >= LOGLEVEL_ERROR) LOG_TRACE(f, __VA_ARGS__) | |
246 | - | |
247 | -static string_utf8_from_os g_pluginCaption8(_T(PLUGIN_CAPTION_JP)); | |
248 | -static string_utf8_from_os g_pluginVersion8(_T(PLUGIN_VERSION)); | |
249 | -static string_utf8_from_os g_pluginAbout8( | |
250 | - _T(PLUGIN_CAPTION_JP) _T(" ") _T(PLUGIN_VERSION) _T("\nCopyright (C) 2006-2008 Yossiepon Oniichan, All Rights Reserved.")); | |
251 | - | |
252 | -DECLARE_COMPONENT_VERSION(g_pluginCaption8, g_pluginVersion8, g_pluginAbout8); | |
253 | - | |
254 | -static string_utf8_from_os g_advancedSettingsCaption8(_T(ADVANCED_SETTINGS_CAPTION)); | |
255 | -static string_utf8_from_os g_debugSettingsCaption8(_T(DEBUG_SETTINGS_CAPTION)); | |
256 | - | |
257 | -static string_utf8_from_os g_menu_item(_T("Components/Mixi/mixiミュージック連携を有効にする")); | |
258 | - | |
259 | -static string_utf8_from_os g_menu_item_title(_T("mixiミュージック連携を有効にする")); | |
260 | -static string_utf8_from_os g_menu_item_description(_T("mixiミュージックへの曲情報の送信について、有効/無効を切り替えます")); | |
261 | - | |
262 | -#if IS_FB2K_VER08 | |
263 | -static cfg_int cfg_use_plugin("usePlugin", 1); | |
264 | - | |
265 | -static cfg_string cfg_no_artist_name("NoArtistName", "No Artist"); | |
266 | -static cfg_string cfg_no_title_name("NoTitleName", "No Title"); | |
267 | -static cfg_string cfg_no_album_name("NoAlbumName", "No Title"); | |
268 | -static cfg_string cfg_no_genre_name("NoGenreName", "Other"); | |
269 | - | |
270 | -static cfg_string cfg_send_interval1("SendInterval1", "20"); | |
271 | -static cfg_string cfg_send_interval2("SendInterval2", "66"); | |
272 | -static cfg_string cfg_send_interval3("SendInterval3", "300"); | |
273 | - | |
274 | -static cfg_int cfg_disable_duplicate_song("DisableDuplicateSong", 0); | |
275 | -static cfg_int cfg_media_library_registered_file_only("MediaLibraryRegisteredFileOnly", 0); | |
276 | -static cfg_int cfg_explicitly_tagged_file_only("ExplicitlyTaggedFileOnly", 0); | |
277 | -static cfg_int cfg_enable_streaming_file("EnableStreamingFile", 0); | |
278 | - | |
279 | -static cfg_int cfg_disable_dummy_mp3("DisableDummyMp3", 0); | |
280 | -static cfg_int cfg_dummy_mp3_location("DummyMp3Location", 0); | |
281 | - | |
282 | -static cfg_int cfg_show_dummyamp("ShowDummyAmp", 0); | |
283 | -static cfg_string cfg_dummyamp_title_format("DummyAmpTitleFormat", DEFAULT_DUMMYAMP_TITLE_FORMAT); | |
284 | -static cfg_string cfg_dummyamp_playlist_format("DummyAmpPlaylistFormat", DEFAULT_DUMMYAMP_TITLE_FORMAT); | |
285 | -static cfg_int cfg_disable_ansi_trans("DisableAnsiTrans", 0); | |
286 | -static cfg_int cfg_enable_ext_ipc_proc("EnableExtIpcProc", 1); | |
287 | - | |
288 | -static cfg_int cfg_enable_debug_log("EnableDebugLog", 1); | |
289 | -static cfg_int cfg_debug_dummyamp_init("DebugDummyAmpInit", 1); | |
290 | -static cfg_int cfg_debug_dummyamp_proc("DebugDummyAmpProc", 1); | |
291 | -static cfg_int cfg_debug_track_info("DebugTrackInfo", 1); | |
292 | -static cfg_int cfg_debug_plugin("DebugPlugin", 1); | |
293 | -static cfg_int cfg_debug_callback("DebugCallback", 1); | |
294 | -#elif IS_FB2K_VER09 | |
295 | -// {DB051102-6DAE-4ff8-B5ED-AA06C2ACFEDE} | |
296 | -static const GUID cfg_use_plugin_guid = { 0xdb051102, 0x6dae, 0x4ff8, { 0xb5, 0xed, 0xaa, 0x6, 0xc2, 0xac, 0xfe, 0xde } }; | |
297 | -static cfg_int cfg_use_plugin(cfg_use_plugin_guid, 1); | |
298 | - | |
299 | -// {1B27EDEC-A28A-4dac-96D4-1E3B51C92004} | |
300 | -static const GUID cfg_no_artist_name_guid = { 0x1b27edec, 0xa28a, 0x4dac, { 0x96, 0xd4, 0x1e, 0x3b, 0x51, 0xc9, 0x20, 0x4 } }; | |
301 | -static cfg_string cfg_no_artist_name(cfg_no_artist_name_guid, "No Artist"); | |
302 | -// {A8CFD50C-05EA-447d-AA74-F4C6975E750E} | |
303 | -static const GUID cfg_no_title_name_guid = { 0xa8cfd50c, 0x5ea, 0x447d, { 0xaa, 0x74, 0xf4, 0xc6, 0x97, 0x5e, 0x75, 0xe } }; | |
304 | -static cfg_string cfg_no_title_name(cfg_no_title_name_guid, "No Title"); | |
305 | -// {A7593537-8B09-4016-9B3C-0EF5516BBFF9} | |
306 | -static const GUID cfg_no_album_name_guid = { 0xa7593537, 0x8b09, 0x4016, { 0x9b, 0x3c, 0xe, 0xf5, 0x51, 0x6b, 0xbf, 0xf9 } }; | |
307 | -static cfg_string cfg_no_album_name(cfg_no_album_name_guid, "No Title"); | |
308 | -// {15774319-0CBE-45fd-B0E8-52D4728319A3} | |
309 | -static const GUID cfg_no_genre_name_guid = { 0x15774319, 0xcbe, 0x45fd, { 0xb0, 0xe8, 0x52, 0xd4, 0x72, 0x83, 0x19, 0xa3 } }; | |
310 | -static cfg_string cfg_no_genre_name(cfg_no_genre_name_guid, "Other"); | |
311 | - | |
312 | -// {ED0C715A-D06D-4641-A29A-AE4485A0B9EF} | |
313 | -static const GUID cfg_send_interval1_guid = { 0xed0c715a, 0xd06d, 0x4641, { 0xa2, 0x9a, 0xae, 0x44, 0x85, 0xa0, 0xb9, 0xef } }; | |
314 | -static cfg_string cfg_send_interval1(cfg_send_interval1_guid, "20"); | |
315 | -// {25989711-B458-4624-8A85-7304FCE799A3} | |
316 | -static const GUID cfg_send_interval2_guid = { 0x25989711, 0xb458, 0x4624, { 0x8a, 0x85, 0x73, 0x4, 0xfc, 0xe7, 0x99, 0xa3 } }; | |
317 | -static cfg_string cfg_send_interval2(cfg_send_interval2_guid, "66"); | |
318 | -// {4287A873-015D-44b5-A31E-34DEE1BF0525} | |
319 | -static const GUID cfg_send_interval3_guid = { 0x4287a873, 0x15d, 0x44b5, { 0xa3, 0x1e, 0x34, 0xde, 0xe1, 0xbf, 0x5, 0x25 } }; | |
320 | -static cfg_string cfg_send_interval3(cfg_send_interval3_guid, "300"); | |
321 | - | |
322 | -// {5C318451-2B6A-405f-814B-2795A764C1DE} | |
323 | -static const GUID cfg_disable_duplicate_song_guid = { 0x5c318451, 0x2b6a, 0x405f, { 0x81, 0x4b, 0x27, 0x95, 0xa7, 0x64, 0xc1, 0xde } }; | |
324 | -static cfg_int cfg_disable_duplicate_song(cfg_disable_duplicate_song_guid, 0); | |
325 | -// {56688AED-A76D-4759-A835-A380D39D34D1} | |
326 | -static const GUID cfg_media_library_registered_file_only_guid = { 0x56688aed, 0xa76d, 0x4759, { 0xa8, 0x35, 0xa3, 0x80, 0xd3, 0x9d, 0x34, 0xd1 } }; | |
327 | -static cfg_int cfg_media_library_registered_file_only(cfg_media_library_registered_file_only_guid, 0); | |
328 | -// {91E0D3D4-85DD-4c45-ADB5-7FAC6F3360CD} | |
329 | -static const GUID cfg_explicitly_tagged_file_only_guid = { 0x91e0d3d4, 0x85dd, 0x4c45, { 0xad, 0xb5, 0x7f, 0xac, 0x6f, 0x33, 0x60, 0xcd } }; | |
330 | -static cfg_int cfg_explicitly_tagged_file_only(cfg_explicitly_tagged_file_only_guid, 0); | |
331 | -// {F4E85669-6EEF-4b75-AFC1-7964AEBE10B0} | |
332 | -static const GUID cfg_enable_streaming_file_guid = { 0xf4e85669, 0x6eef, 0x4b75, { 0xaf, 0xc1, 0x79, 0x64, 0xae, 0xbe, 0x10, 0xb0 } }; | |
333 | -static cfg_int cfg_enable_streaming_file(cfg_enable_streaming_file_guid, 0); | |
334 | - | |
335 | -// {67341E11-A385-45d8-9DE6-B1FABA35AC62} | |
336 | -static const GUID cfg_disable_dummy_mp3_guid = { 0x67341e11, 0xa385, 0x45d8, { 0x9d, 0xe6, 0xb1, 0xfa, 0xba, 0x35, 0xac, 0x62 } }; | |
337 | -static cfg_int cfg_disable_dummy_mp3(cfg_disable_dummy_mp3_guid, 0); | |
338 | -// {87D4D72C-43AB-42ab-8CAC-D689961DA5EA} | |
339 | -static const GUID cfg_dummy_mp3_location_guid = { 0x87d4d72c, 0x43ab, 0x42ab, { 0x8c, 0xac, 0xd6, 0x89, 0x96, 0x1d, 0xa5, 0xea } }; | |
340 | -static cfg_int cfg_dummy_mp3_location(cfg_dummy_mp3_location_guid, 0); | |
341 | - | |
342 | -// {F9DB10F0-1A01-40dd-A342-486A6CB596E7} | |
343 | -static const GUID cfg_show_dummyamp_guid = { 0xf9db10f0, 0x1a01, 0x40dd, { 0xa3, 0x42, 0x48, 0x6a, 0x6c, 0xb5, 0x96, 0xe7 } }; | |
344 | -static cfg_int cfg_show_dummyamp(cfg_show_dummyamp_guid, 0); | |
345 | -// {CC7785CA-B019-4107-9115-161A543B3952} | |
346 | -static const GUID cfg_dummyamp_title_format_guid = { 0xcc7785ca, 0xb019, 0x4107, { 0x91, 0x15, 0x16, 0x1a, 0x54, 0x3b, 0x39, 0x52 } }; | |
347 | -static cfg_string cfg_dummyamp_title_format(cfg_dummyamp_title_format_guid, DEFAULT_DUMMYAMP_TITLE_FORMAT); | |
348 | -// {B964EB32-4957-4e7a-81B5-E89B4405AAAD} | |
349 | -static const GUID cfg_dummyamp_playlist_format_guid = { 0xb964eb32, 0x4957, 0x4e7a, { 0x81, 0xb5, 0xe8, 0x9b, 0x44, 0x5, 0xaa, 0xad } }; | |
350 | -static cfg_string cfg_dummyamp_playlist_format(cfg_dummyamp_title_format_guid, DEFAULT_DUMMYAMP_TITLE_FORMAT); | |
351 | - | |
352 | -// {094571BA-1484-455c-9D6E-E18B13296149} | |
353 | -static const GUID cfg_disable_ansi_trans_guid = { 0x94571ba, 0x1484, 0x455c, { 0x9d, 0x6e, 0xe1, 0x8b, 0x13, 0x29, 0x61, 0x49 } }; | |
354 | -static cfg_int cfg_disable_ansi_trans(cfg_disable_ansi_trans_guid, 0); | |
355 | -// {8961A829-F010-461c-9CC8-C06308BFA4A2} | |
356 | -static const GUID cfg_enable_ext_ipc_proc_guid = { 0x8961a829, 0xf010, 0x461c, { 0x9c, 0xc8, 0xc0, 0x63, 0x8, 0xbf, 0xa4, 0xa2 } }; | |
357 | -static cfg_int cfg_enable_ext_ipc_proc(cfg_enable_ext_ipc_proc_guid, 1); | |
358 | - | |
359 | -// {3B6B73F9-F6AF-4b6c-8015-E73A1B87AD5C} | |
360 | -static const GUID cfg_enable_debug_log_guid = { 0x3b6b73f9, 0xf6af, 0x4b6c, { 0x80, 0x15, 0xe7, 0x3a, 0x1b, 0x87, 0xad, 0x5c } }; | |
361 | -static cfg_int cfg_enable_debug_log(cfg_enable_debug_log_guid, 1); // debug log enabled | |
362 | -// {0BF3522F-BC55-4f77-AA95-B02F6E159544} | |
363 | -static const GUID cfg_debug_dummyamp_init_guid = { 0xbf3522f, 0xbc55, 0x4f77, { 0xaa, 0x95, 0xb0, 0x2f, 0x6e, 0x15, 0x95, 0x44 } }; | |
364 | -static cfg_int cfg_debug_dummyamp_init(cfg_debug_dummyamp_init_guid, 1); // debug level | |
365 | -// {D1256573-7560-41db-A781-9985AE50CE07} | |
366 | -static const GUID cfg_debug_dummyamp_proc_guid = { 0xd1256573, 0x7560, 0x41db, { 0xa7, 0x81, 0x99, 0x85, 0xae, 0x50, 0xce, 0x7 } }; | |
367 | -static cfg_int cfg_debug_dummyamp_proc(cfg_debug_dummyamp_proc_guid, 1); // debug level | |
368 | -// {0A7E2CAE-905F-4ecb-A82D-8DD853FBFFF3} | |
369 | -static const GUID cfg_debug_track_info_guid = { 0xa7e2cae, 0x905f, 0x4ecb, { 0xa8, 0x2d, 0x8d, 0xd8, 0x53, 0xfb, 0xff, 0xf3 } }; | |
370 | -static cfg_int cfg_debug_track_info(cfg_debug_track_info_guid, 1); // debug level | |
371 | -// {67A78DB7-3591-4416-84FC-96436082B619} | |
372 | -static const GUID cfg_debug_plugin_guid = { 0x67a78db7, 0x3591, 0x4416, { 0x84, 0xfc, 0x96, 0x43, 0x60, 0x82, 0xb6, 0x19 } }; | |
373 | -static cfg_int cfg_debug_plugin(cfg_debug_plugin_guid, 1); // debug level | |
374 | -// {DBED8400-527F-4b98-9227-2C0BA95B3206} | |
375 | -static const GUID cfg_debug_callback_guid = { 0xdbed8400, 0x527f, 0x4b98, { 0x92, 0x27, 0x2c, 0xb, 0xa9, 0x5b, 0x32, 0x6 } }; | |
376 | -static cfg_int cfg_debug_callback(cfg_debug_callback_guid, 1); // debug level | |
377 | -#endif | |
378 | - | |
379 | -class TrackInfo | |
380 | -{ | |
381 | -public: | |
382 | - std::string m_nullStr; | |
383 | - | |
384 | - StringMap m_infoMap8; | |
385 | - StringMap m_infoMapAnsi; | |
386 | - | |
387 | - UIntMap m_infoMapNum; | |
388 | - | |
389 | - TrackInfo() { | |
390 | - } | |
391 | - | |
392 | - TrackInfo(const TrackInfo &other) | |
393 | - : m_infoMap8(other.m_infoMap8) | |
394 | - , m_infoMapAnsi(other.m_infoMapAnsi) | |
395 | - , m_infoMapNum(other.m_infoMapNum) { | |
396 | - } | |
397 | - | |
398 | - ~TrackInfo() { | |
399 | - } | |
400 | - | |
401 | - TrackInfo &operator =(const TrackInfo &other) | |
402 | - { | |
403 | - TrackInfo temp(other); | |
404 | - swap(temp); | |
405 | - | |
406 | - return *this; | |
407 | - } | |
408 | - | |
409 | - void show_map(StringMap &map, bool bAnsi = false) | |
410 | - { | |
411 | - StringMapCIt beginIt(map.begin()), endIt(map.end()), it; | |
412 | - | |
413 | - for(it = beginIt; it != endIt; it ++) { | |
414 | - | |
415 | - if(bAnsi) { | |
416 | - TRACE_TRACK_INFO_ANSI("show_map_ansi: [%s, %s]", it->first.c_str(), it->second.c_str()); | |
417 | - } else { | |
418 | - TRACE_TRACK_INFO8("show_map8: [%s, %s]", it->first.c_str(), it->second.c_str()); | |
419 | - } | |
420 | - } | |
421 | - } | |
422 | - | |
423 | - void swap(TrackInfo &other) | |
424 | - { | |
425 | - m_infoMap8.swap(other.m_infoMap8); | |
426 | - m_infoMapAnsi.swap(other.m_infoMapAnsi); | |
427 | - m_infoMapNum.swap(other.m_infoMapNum); | |
428 | - } | |
429 | - | |
430 | - void clear() | |
431 | - { | |
432 | - TRACE_TRACK_INFO(_T("TRACK_INFO::clear - called.")); | |
433 | - | |
434 | - m_infoMap8.clear(); | |
435 | - m_infoMapAnsi.clear(); | |
436 | - m_infoMapNum.clear(); | |
437 | - } | |
438 | - | |
439 | - bool isEmpty() const { return m_infoMap8.empty() & m_infoMapNum.empty(); } | |
440 | - | |
441 | -public: | |
442 | - | |
443 | -#if IS_FB2K_VER08 | |
444 | - void setStrings(const Strings &keys, metadb_handle * track) | |
445 | -#elif IS_FB2K_VER09 | |
446 | - void setStrings(const Strings &keys, metadb_handle_ptr track) | |
447 | -#endif | |
448 | - { | |
449 | - TRACE_TRACK_INFO(_T("TrackInfo::setStrings - called.")); | |
450 | - | |
451 | - StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
452 | - | |
453 | - for(it = beginIt; it != endIt; it ++) { | |
454 | - | |
455 | - string8 info8; | |
456 | - | |
457 | -#if IS_FB2K_VER08 | |
458 | - track->handle_format_title(info8, it->c_str(), 0); | |
459 | -#elif IS_FB2K_VER09 | |
460 | - service_ptr_t<titleformat_object> titleformat; | |
461 | - | |
462 | - static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, it->c_str()); | |
463 | - track->format_title(NULL, info8, titleformat, 0); | |
464 | -#endif | |
465 | -// DEBUG_TRACK_INFO8("TrackInfo::setStrings - %s: %s", it->c_str(), (LPCSTR)info8); | |
466 | - | |
467 | - putString(it->c_str(), (LPCSTR)info8); | |
468 | - } | |
469 | - } | |
470 | - | |
471 | - void setDynamicStrings(const Strings &keys) | |
472 | - { | |
473 | - TRACE_TRACK_INFO(_T("TrackInfo::setDynamicStrings - called.")); | |
474 | - | |
475 | -#if IS_FB2K_VER08 | |
476 | - metadb_handle *track = play_control::get()->get_now_playing(); | |
477 | -#elif IS_FB2K_VER09 | |
478 | - metadb_handle_ptr track; | |
479 | - static_api_ptr_t<playback_control>()->get_now_playing(track); | |
480 | -#endif | |
481 | - | |
482 | - StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
483 | - | |
484 | - for(it = beginIt; it != endIt; it ++) { | |
485 | - | |
486 | - string8 info8; | |
487 | - | |
488 | -#if IS_FB2K_VER08 | |
489 | - play_control::get()->playback_format_title_ex(track, info8, it->c_str(), NULL, false, true); | |
490 | -#elif IS_FB2K_VER09 | |
491 | - service_ptr_t<titleformat_object> titleformat; | |
492 | - | |
493 | - static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, it->c_str()); | |
494 | - static_api_ptr_t<playback_control>()->playback_format_title_ex(track, NULL, info8, titleformat, NULL, play_control::display_level_titles); | |
495 | -#endif | |
496 | -// DEBUG_TRACK_INFO8("TrackInfo::setDynamicStrings - %s: %s", it->c_str(), (LPCSTR)info8); | |
497 | - | |
498 | - const std::string &oldValue = getString(*it); | |
499 | - | |
500 | - if((::lstrcmpA(info8, "?") != 0) || (oldValue.length() == 0)) | |
501 | - { | |
502 | - putString(it->c_str(), (LPCSTR)info8); | |
503 | - } | |
504 | - } | |
505 | - | |
506 | -#if IS_FB2K_VER08 | |
507 | - if(track) { | |
508 | - track->handle_release(); | |
509 | - } | |
510 | -#endif | |
511 | - } | |
512 | - | |
513 | - void setPlaylistStrings(const Strings &keys) | |
514 | - { | |
515 | - TRACE_TRACK_INFO(_T("TrackInfo::setPlaylistStrings - called.")); | |
516 | - | |
517 | -#if IS_FB2K_VER08 | |
518 | - int track_index; | |
519 | - track_index = playlist_oper::get()->get_now_playing(); | |
520 | -#elif IS_FB2K_VER09 | |
521 | - t_size playlist_index, track_index; | |
522 | - static_api_ptr_t<playlist_manager>()->get_playing_item_location(&playlist_index, &track_index); | |
523 | -#endif | |
524 | - | |
525 | - StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
526 | - | |
527 | - for(it = beginIt; it != endIt; it ++) { | |
528 | - | |
529 | - string8 info8; | |
530 | - | |
531 | -#if IS_FB2K_VER08 | |
532 | - playlist_oper::get()->format_title(track_index, info8, it->c_str(), NULL); | |
533 | -#elif IS_FB2K_VER09 | |
534 | - service_ptr_t<titleformat_object> titleformat; | |
535 | - | |
536 | - static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, it->c_str()); | |
537 | - static_api_ptr_t<playlist_manager>()->playlist_item_format_title(playlist_index, track_index, | |
538 | - NULL, info8, titleformat, NULL, play_control::display_level_titles); | |
539 | -#endif | |
540 | -// DEBUG_TRACK_INFO8("TrackInfo::setPlaylistStrings - %s: %s", it->c_str(), (LPCSTR)info8); | |
541 | - | |
542 | - putString(it->c_str(), (LPCSTR)info8); | |
543 | - } | |
544 | - } | |
545 | - | |
546 | -#if IS_FB2K_VER08 | |
547 | - void setNumbers(const Strings &keys, metadb_handle * track) | |
548 | -#elif IS_FB2K_VER09 | |
549 | - void setNumbers(const Strings &keys, metadb_handle_ptr track) | |
550 | -#endif | |
551 | - { | |
552 | - TRACE_TRACK_INFO(_T("TrackInfo::setNumbers - called.")); | |
553 | - | |
554 | - StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
555 | - | |
556 | - for(it = beginIt; it != endIt; it ++) { | |
557 | - | |
558 | - string8 info8; | |
559 | - | |
560 | -#if IS_FB2K_VER08 | |
561 | - track->handle_format_title(info8, it->c_str(), 0); | |
562 | -#elif IS_FB2K_VER09 | |
563 | - service_ptr_t<titleformat_object> titleformat; | |
564 | - | |
565 | - static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, it->c_str()); | |
566 | - track->format_title(NULL, info8, titleformat, 0); | |
567 | -#endif | |
568 | -// DEBUG_TRACK_INFO8("TrackInfo::setNumbers - %s: %s", it->c_str(), (LPCSTR)info8); | |
569 | - | |
570 | - putNumber(it->c_str(), static_cast<UINT>(::atol(info8)) ); | |
571 | - } | |
572 | - } | |
573 | - | |
574 | - void setDynamicNumbers(const Strings &keys) | |
575 | - { | |
576 | - TRACE_TRACK_INFO(_T("TrackInfo::setDynamicNumbers - called.")); | |
577 | - | |
578 | -#if IS_FB2K_VER08 | |
579 | - metadb_handle *track = play_control::get()->get_now_playing(); | |
580 | -#elif IS_FB2K_VER09 | |
581 | - metadb_handle_ptr track; | |
582 | - static_api_ptr_t<playback_control>()->get_now_playing(track); | |
583 | -#endif | |
584 | - | |
585 | - StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
586 | - | |
587 | - for(it = beginIt; it != endIt; it ++) { | |
588 | - | |
589 | - string8 info8; | |
590 | - | |
591 | -#if IS_FB2K_VER08 | |
592 | - play_control::get()->playback_format_title_ex(track, info8, it->c_str(), NULL, false, true); | |
593 | -#elif IS_FB2K_VER09 | |
594 | - service_ptr_t<titleformat_object> titleformat; | |
595 | - | |
596 | - static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, it->c_str()); | |
597 | - static_api_ptr_t<playback_control>()->playback_format_title_ex(track, NULL, info8, titleformat, NULL, play_control::display_level_titles); | |
598 | -#endif | |
599 | -// DEBUG_TRACK_INFO8("TrackInfo::setDynamicNumbers - %s: %s", it->c_str(), (LPCSTR)info8); | |
600 | - | |
601 | - UINT newValue = static_cast<UINT>(::atol(info8)); | |
602 | - UINT oldValue = getNumber(*it); | |
603 | - | |
604 | - if((newValue != 0) || (oldValue == 0)) { | |
605 | - putNumber(it->c_str(), newValue); | |
606 | - } | |
607 | - } | |
608 | - | |
609 | -#if IS_FB2K_VER08 | |
610 | - if(track) { | |
611 | - track->handle_release(); | |
612 | - } | |
613 | -#endif | |
614 | - } | |
615 | - | |
616 | - void setPlaylistNumbers(const Strings &keys) | |
617 | - { | |
618 | - TRACE_TRACK_INFO(_T("TrackInfo::setPlaylistNumbers - called.")); | |
619 | - | |
620 | -#if IS_FB2K_VER08 | |
621 | - int track_index; | |
622 | - track_index = playlist_oper::get()->get_now_playing(); | |
623 | -#elif IS_FB2K_VER09 | |
624 | - t_size playlist_index, track_index; | |
625 | - static_api_ptr_t<playlist_manager>()->get_playing_item_location(&playlist_index, &track_index); | |
626 | -#endif | |
627 | - | |
628 | - StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
629 | - | |
630 | - for(it = beginIt; it != endIt; it ++) { | |
631 | - | |
632 | - string8 info8; | |
633 | - | |
634 | -#if IS_FB2K_VER08 | |
635 | - playlist_oper::get()->format_title(track_index, info8, it->c_str(), NULL); | |
636 | -#elif IS_FB2K_VER09 | |
637 | - service_ptr_t<titleformat_object> titleformat; | |
638 | - | |
639 | - static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, it->c_str()); | |
640 | - static_api_ptr_t<playlist_manager>()->playlist_item_format_title(playlist_index, track_index, | |
641 | - NULL, info8, titleformat, NULL, play_control::display_level_titles); | |
642 | -#endif | |
643 | -// DEBUG_TRACK_INFO8("TrackInfo::setPlaylistNumbers - %s: %s", it->c_str(), (LPCSTR)info8); | |
644 | - | |
645 | - putNumber(it->c_str(), static_cast<UINT>(::atol(info8)) ); | |
646 | - } | |
647 | - } | |
648 | - | |
649 | - void putString(const std::string &key, const std::string &value) | |
650 | - { | |
651 | - DEBUG_TRACK_INFO8("TrackInfo::putString - %s: %s", key.c_str(), value.c_str()); | |
652 | - | |
653 | - insert(m_infoMap8, key.c_str(), value.c_str()); | |
654 | - | |
655 | - string_ansi_from_utf8 valueAnsi(value.c_str()); | |
656 | - | |
657 | - insert(m_infoMapAnsi, key.c_str(), (LPCSTR)valueAnsi, true); | |
658 | - } | |
659 | - | |
660 | - void putNumber(const std::string &key, UINT value) | |
661 | - { | |
662 | - DEBUG_TRACK_INFO8("TrackInfo::putNumber - %s: %u", key.c_str(), value); | |
663 | - | |
664 | - insert(m_infoMapNum, key.c_str(), value); | |
665 | - } | |
666 | - | |
667 | - const std::string &getString(const std::string &key, bool bForceUTF8 = false) const { | |
668 | - | |
669 | - if((bForceUTF8 == true) || (cfg_disable_ansi_trans == 1)) | |
670 | - { | |
671 | - StringMapCIt it(m_infoMap8.find(key)), endIt(m_infoMap8.end()); | |
672 | - | |
673 | - if(it == endIt) { | |
674 | - return m_nullStr; | |
675 | - } | |
676 | - | |
677 | - return it->second; | |
678 | - } | |
679 | - else | |
680 | - { | |
681 | - StringMapCIt it(m_infoMapAnsi.find(key)), endIt(m_infoMapAnsi.end()); | |
682 | - | |
683 | - if(it == endIt) { | |
684 | - return m_nullStr; | |
685 | - } | |
686 | - | |
687 | - return it->second; | |
688 | - } | |
689 | - } | |
690 | - | |
691 | - const UINT getNumber(const std::string &key) const { | |
692 | - | |
693 | - UIntMapCIt it(m_infoMapNum.find(key)), endIt(m_infoMapNum.end()); | |
694 | - | |
695 | - if(it == endIt) { | |
696 | - return 0; | |
697 | - } | |
698 | - | |
699 | - return it->second; | |
700 | - } | |
701 | - | |
702 | - void removeStrings(const Strings &keys) | |
703 | - { | |
704 | - TRACE_TRACK_INFO(_T("TrackInfo::removeStrings - called.")); | |
705 | - | |
706 | - StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
707 | - | |
708 | - for(it = beginIt; it != endIt; it ++) { | |
709 | - removeString(*it); | |
710 | - } | |
711 | - } | |
712 | - | |
713 | - void removeString(const std::string &key) | |
714 | - { | |
715 | - TRACE_TRACK_INFO8("TrackInfo::removeString - %s", key.c_str()); | |
716 | - | |
717 | - m_infoMap8.erase(m_infoMap8.find(key)); | |
718 | - m_infoMapAnsi.erase(m_infoMapAnsi.find(key)); | |
719 | - } | |
720 | - | |
721 | - void removeNumbers(const Strings &keys) | |
722 | - { | |
723 | - TRACE_TRACK_INFO(_T("TrackInfo::removeNumbers - called.")); | |
724 | - | |
725 | - StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
726 | - | |
727 | - for(it = beginIt; it != endIt; it ++) { | |
728 | - removeNumber(*it); | |
729 | - } | |
730 | - } | |
731 | - | |
732 | - void removeNumber(const std::string &key) | |
733 | - { | |
734 | - TRACE_TRACK_INFO8("TrackInfo::removeNumber - %s", key.c_str()); | |
735 | - | |
736 | - m_infoMapNum.erase(m_infoMapNum.find(key)); | |
737 | - } | |
738 | - | |
739 | -protected: | |
740 | - | |
741 | - static void insert(StringMap &map, LPCSTR pKey, LPCSTR pValue, bool bAnsi = false) | |
742 | - { | |
743 | -#if 0 | |
744 | - if(bAnsi) { | |
745 | - TRACE_TRACK_INFO_ANSI("insertAnsi: [%s, %s]", pKey, pValue); | |
746 | - } else { | |
747 | - TRACE_TRACK_INFO8("insert8: [%s, %s]", pKey, pValue); | |
748 | - } | |
749 | -#endif | |
750 | - | |
751 | - map.insert(std::make_pair(pKey, pValue)); | |
752 | - } | |
753 | - | |
754 | - static void insert(UIntMap &map, LPCSTR pKey, UINT value) | |
755 | - { | |
756 | -// TRACE_TRACK_INFO8("insertNum: [%s, %u]", pKey, value); | |
757 | - | |
758 | - map.insert(std::make_pair(pKey, value)); | |
759 | - } | |
760 | -}; | |
761 | - | |
762 | -class PathInfo | |
763 | -{ | |
764 | - protected: | |
765 | - PathInfo() { | |
766 | - } | |
767 | - | |
768 | - public: | |
769 | - static tstring getFB2Kpath() | |
770 | - { | |
771 | - TCHAR modulePath[_MAX_PATH], moduleDrive[_MAX_DRIVE], moduleDir[_MAX_DIR]; | |
772 | - TCHAR returnPath[_MAX_PATH]; | |
773 | - | |
774 | - ::GetModuleFileName(NULL, modulePath, _MAX_PATH); | |
775 | - ::_tsplitpath_s(modulePath, moduleDrive, _MAX_DRIVE, moduleDir, _MAX_DIR, NULL, 0, NULL, 0); | |
776 | - ::_tmakepath_s(returnPath, _MAX_PATH, moduleDrive, moduleDir, NULL, NULL); | |
777 | - | |
778 | - return tstring(returnPath); | |
779 | - } | |
780 | - | |
781 | - static tstring getFB2KComponentsPath() { | |
782 | - return getFB2Kpath() + FB2K_COMPONENTS_DIR; | |
783 | - } | |
784 | - | |
785 | - static std::string getGenMixiDefaultPath() | |
786 | - { | |
787 | - string_utf8_from_os path(getFB2KComponentsPath().c_str()); | |
788 | - return (LPCSTR)path; | |
789 | - } | |
790 | - | |
791 | - static tstring getMixiStationAppPath() { | |
792 | - return getSpecialFolderPath(CSIDL_APPDATA, FALSE) + APPDATA_MIXI_STATION_DIR; | |
793 | - } | |
794 | - | |
795 | - static tstring getFooMixiPlayInfoPath() | |
796 | - { | |
797 | - switch(cfg_dummy_mp3_location) | |
798 | - { | |
799 | - case 1: | |
800 | - return getTemporaryFolderPath(); | |
801 | - | |
802 | - case 2: | |
803 | - return getFB2KComponentsPath() ; | |
804 | - | |
805 | - case 0: | |
806 | - default: | |
807 | - return getMixiStationAppPath() + _T("\\"); | |
808 | - } | |
809 | - } | |
810 | - | |
811 | - static tstring getDummyPlayInfoMp3Path() { | |
812 | - return getFooMixiPlayInfoPath() + DUMMY_MP3_FILE_NAME; | |
813 | - } | |
814 | - | |
815 | - static tstring splitPath(const string8 &srcPath) | |
816 | - { | |
817 | - string_os_from_utf8 srcPathOs(srcPath); | |
818 | - return splitPath(srcPathOs); | |
819 | - } | |
820 | - | |
821 | - static tstring splitPath(LPCTSTR srcPath) | |
822 | - { | |
823 | - TCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], dstPath[_MAX_PATH]; | |
824 | - ::_tsplitpath_s(srcPath, drive, _MAX_DRIVE, dir, _MAX_DIR, NULL, 0, NULL, 0); | |
825 | - ::_tmakepath_s(dstPath, _MAX_PATH, drive, dir, NULL, NULL); | |
826 | - return dstPath; | |
827 | - } | |
828 | - | |
829 | - //! get the special folder path | |
830 | - static tstring getSpecialFolderPath(int nFolder, BOOL bCreate) | |
831 | - { | |
832 | - tstring resStr; | |
833 | - HRESULT hr = NO_ERROR; | |
834 | - | |
835 | - IMalloc *pMalloc = 0; | |
836 | - ITEMIDLIST *pItemID = 0; | |
837 | - TCHAR folderPath[MAX_PATH]; | |
838 | - | |
839 | - folderPath[0] = _T('\0'); | |
840 | - hr = SHGetMalloc(&pMalloc); | |
841 | - | |
842 | - if(hr == NO_ERROR) | |
843 | - { | |
844 | - hr = SHGetSpecialFolderLocation(0, nFolder, &pItemID); | |
845 | - | |
846 | - if(hr == NO_ERROR) | |
847 | - { | |
848 | - if(SHGetPathFromIDList(pItemID, folderPath) == FALSE) | |
849 | - hr = GetLastError(); | |
850 | - | |
851 | - pMalloc->Free(pItemID); | |
852 | - } | |
853 | - | |
854 | - pMalloc->Release(); | |
855 | - } | |
856 | - | |
857 | - resStr = folderPath; | |
858 | - | |
859 | - if(hr != NO_ERROR) | |
860 | - { | |
861 | - return _T(""); | |
862 | - } | |
863 | - | |
864 | - return resStr; | |
865 | - } | |
866 | - | |
867 | - //! get the temporary folder path | |
868 | - static tstring getTemporaryFolderPath() { | |
869 | - | |
870 | - TCHAR strTempPath[MAX_PATH]; | |
871 | - ::GetTempPath(MAX_PATH, strTempPath); | |
872 | - | |
873 | - return strTempPath; | |
874 | - } | |
875 | -}; | |
876 | - | |
877 | -#if IS_FB2K_VER08 | |
878 | -static cfg_string cfg_gen_mixi_path("GenMixiPath", PathInfo::getGenMixiDefaultPath().c_str()); | |
879 | -#elif IS_FB2K_VER09 | |
880 | -// {1EC28435-C243-483c-81EC-E0E57A96727E} | |
881 | -static const GUID cfg_gen_mixi_path_guid = { 0x1ec28435, 0xc243, 0x483c, { 0x81, 0xec, 0xe0, 0xe5, 0x7a, 0x96, 0x72, 0x7e } }; | |
882 | -static cfg_string cfg_gen_mixi_path(cfg_gen_mixi_path_guid, PathInfo::getGenMixiDefaultPath().c_str()); | |
883 | -#endif | |
884 | - | |
885 | -class PlayInfo | |
886 | -{ | |
887 | - public: | |
888 | - | |
889 | - enum EPlayStatus | |
890 | - { | |
891 | - PLAY_STOP = 0, | |
892 | - PLAY_START = 1, | |
893 | - PLAY_PAUSE = 3 | |
894 | - }; | |
895 | - | |
896 | - public: | |
897 | - | |
898 | - PlayInfo() : | |
899 | - m_playStatus(PLAY_STOP), | |
900 | - m_isResentMode(false), | |
901 | - m_playLength(0), | |
902 | - m_playPosition(0), | |
903 | - m_playCount(0), | |
904 | - m_isPlayInfoMp3Available(false), | |
905 | - m_resetBasePosition(0) { | |
906 | - } | |
907 | - | |
908 | - public: | |
909 | - | |
910 | - void setPlayStatusStart() { | |
911 | - setPlayStatus(PLAY_START); | |
912 | - } | |
913 | - | |
914 | - void setPlayStatusStop() { | |
915 | - setPlayStatus(PLAY_STOP); | |
916 | - } | |
917 | - | |
918 | - void setPlayStatusPause() { | |
919 | - setPlayStatus(PLAY_PAUSE); | |
920 | - } | |
921 | - | |
922 | - void clearPlayInfo(bool isResentMode = true) | |
923 | - { | |
924 | - setPlayStatusStop(); | |
925 | - m_isResentMode = isResentMode; | |
926 | - setPlayPosition(0); | |
927 | - setPlayLength(0); | |
928 | - setPlayInfoMp3Available(false); | |
929 | - m_resetBasePosition = 0; | |
930 | - } | |
931 | - | |
932 | - void setResentMode(bool bIncrementCounter = true) | |
933 | - { | |
934 | - if(bIncrementCounter) { | |
935 | - incrementPlayCount(); | |
936 | - } | |
937 | - m_isResentMode = true; | |
938 | - m_resetBasePosition = m_playPosition; | |
939 | - } | |
940 | - | |
941 | - void clearResentMode() { | |
942 | - m_isResentMode = false; | |
943 | - } | |
944 | - | |
945 | - void incrementPlayCount() { | |
946 | - setPlayCount(getPlayCount() + 1); | |
947 | - } | |
948 | - | |
949 | - public: | |
950 | - | |
951 | - EPlayStatus getPlayStatus() const | |
952 | - { | |
953 | - if((m_playStatus == PLAY_START) && m_isResentMode) { | |
954 | - return PLAY_STOP; | |
955 | - } | |
956 | - return m_playStatus; | |
957 | - } | |
958 | - | |
959 | - void setPlayStatus(EPlayStatus status) { | |
960 | - m_playStatus = status; | |
961 | - } | |
962 | - | |
963 | - int getPlayPosition() const | |
964 | - { | |
965 | - if(m_resetBasePosition > 0) { | |
966 | - return m_playPosition - m_resetBasePosition; | |
967 | - } | |
968 | - return m_playPosition; | |
969 | - } | |
970 | - | |
971 | - void setPlayPosition(int pos) { | |
972 | - m_playPosition = pos; | |
973 | - } | |
974 | - | |
975 | - int getPlayLength() const | |
976 | - { | |
977 | -#if FORCE_RESENT_MODE == 0 | |
978 | - if(m_resetBasePosition > 0) { | |
979 | -#else | |
980 | - if(true) { | |
981 | -#endif | |
982 | - return 0; | |
983 | - } | |
984 | - return m_playLength; | |
985 | - } | |
986 | - | |
987 | - void setPlayLength(int len) { | |
988 | - m_playLength = len; | |
989 | - } | |
990 | - | |
991 | - int getPlayCount() const { | |
992 | - return m_playCount; | |
993 | - } | |
994 | - | |
995 | - void setPlayCount(int count) { | |
996 | - m_playCount = count; | |
997 | - } | |
998 | - | |
999 | - bool isPlayInfoMp3Available() const { | |
1000 | - return m_isPlayInfoMp3Available; | |
1001 | - } | |
1002 | - | |
1003 | - void setPlayInfoMp3Available(bool isAvailable) { | |
1004 | - m_isPlayInfoMp3Available = isAvailable; | |
1005 | - } | |
1006 | - | |
1007 | - void setPlayInfoMp3Path(LPCSTR path) | |
1008 | - { | |
1009 | -#if 0 | |
1010 | - m_playInfoMp3Path = path; | |
1011 | - | |
1012 | - string_utf8_from_os path8(path); | |
1013 | - | |
1014 | - if(cfg_disable_ansi_trans == 1) | |
1015 | - { | |
1016 | - | |
1017 | - m_playInfoMp3Path8 = path8; | |
1018 | - } | |
1019 | - else | |
1020 | - { | |
1021 | - string_ansi_from_utf8 pathAnsi(path8); | |
1022 | - | |
1023 | - m_playInfoMp3Path8 = pathAnsi; | |
1024 | - } | |
1025 | -#else | |
1026 | - m_playInfoMp3Path8 = path; | |
1027 | -#endif | |
1028 | - } | |
1029 | - | |
1030 | - const string8 &getPlayInfoMp3Path8() const { | |
1031 | - return m_playInfoMp3Path8; | |
1032 | - } | |
1033 | - | |
1034 | - bool isResentMode() const { | |
1035 | - return m_isResentMode; | |
1036 | - } | |
1037 | - | |
1038 | - protected: | |
1039 | - | |
1040 | - EPlayStatus m_playStatus; | |
1041 | - | |
1042 | - int m_playLength; | |
1043 | - int m_playPosition; | |
1044 | - int m_playCount; | |
1045 | - | |
1046 | - bool m_isPlayInfoMp3Available; | |
1047 | - bool m_isResentMode; | |
1048 | - int m_resetBasePosition; | |
1049 | - | |
1050 | - string8 m_playInfoMp3Path8; | |
1051 | -}; | |
1052 | - | |
1053 | -class id3Info | |
1054 | -{ | |
1055 | - public: | |
1056 | - | |
1057 | - typedef std::vector<UINT16> UInt16Array; | |
1058 | - | |
1059 | - id3Info(const TrackInfo & info) : m_info(info), m_hMp3File(INVALID_HANDLE_VALUE) { | |
1060 | - } | |
1061 | - | |
1062 | - ~id3Info() { | |
1063 | - close(); | |
1064 | - } | |
1065 | - | |
1066 | - DWORD write(LPCTSTR path) { | |
1067 | - | |
1068 | - string_wide_from_utf8 title_utf16(m_info.getString(FORMAT_TRACKTITLE, true).c_str()); | |
1069 | - string_wide_from_utf8 artist_utf16(m_info.getString(FORMAT_ARTIST, true).c_str()); | |
1070 | - string_wide_from_utf8 album_utf16(m_info.getString(FORMAT_ALBUMTITLE, true).c_str()); | |
1071 | - string_wide_from_utf8 genre_utf16(m_info.getString(FORMAT_GENRE, true).c_str()); | |
1072 | - | |
1073 | - DWORD dwErr = S_OK; | |
1074 | - | |
1075 | - if((dwErr = open(path)) != S_OK) { | |
1076 | - return dwErr; | |
1077 | - } | |
1078 | - | |
1079 | - UInt16Array title = makeTextFrame("TIT2", makeUTF16LE(title_utf16)); | |
1080 | - UInt16Array album = makeTextFrame("TALB", makeUTF16LE(album_utf16)); | |
1081 | - UInt16Array artist = makeTextFrame("TPE1", makeUTF16LE(artist_utf16)); | |
1082 | - UInt16Array genre = makeTextFrame("TCON", makeUTF16LE(genre_utf16)); | |
1083 | - | |
1084 | - dwErr = writeHeader(static_cast<UINT32>( | |
1085 | - title.size()*2 + album.size()*2 + artist.size()*2 + genre.size()*2 + 4)); | |
1086 | - // add charset code size (4bytes) | |
1087 | - | |
1088 | - if(dwErr == S_OK) { | |
1089 | - dwErr = writeTextFrame(title); | |
1090 | - } | |
1091 | - | |
1092 | - if(dwErr == S_OK) { | |
1093 | - dwErr = writeTextFrame(album); | |
1094 | - } | |
1095 | - | |
1096 | - if(dwErr == S_OK) { | |
1097 | - dwErr = writeTextFrame(artist); | |
1098 | - } | |
1099 | - | |
1100 | - if(dwErr == S_OK) { | |
1101 | - dwErr = writeTextFrame(genre); | |
1102 | - } | |
1103 | - | |
1104 | - close(); | |
1105 | - | |
1106 | - return dwErr; | |
1107 | - } | |
1108 | - | |
1109 | - protected: | |
1110 | - | |
1111 | - DWORD open(LPCTSTR path) | |
1112 | - { | |
1113 | - close(); | |
1114 | - | |
1115 | - // open dummy mp3 file | |
1116 | - m_hMp3File = ::CreateFile( | |
1117 | - path, GENERIC_WRITE, 0, NULL, | |
1118 | - TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL | |
1119 | - ); | |
1120 | - | |
1121 | - if(m_hMp3File == INVALID_HANDLE_VALUE) | |
1122 | - { | |
1123 | - return ::GetLastError(); | |
1124 | - } | |
1125 | - | |
1126 | - return S_OK; | |
1127 | - } | |
1128 | - | |
1129 | - UInt16Array makeUTF16LE(const string_wide_from_utf8 &str) { | |
1130 | - | |
1131 | - LPCWSTR pStr = str.get_ptr(); | |
1132 | - size_t len = ::lstrlenW(pStr); | |
1133 | - UInt16Array utf16(len + 2); | |
1134 | - | |
1135 | - utf16[0] = 0xfeff; // BOM | |
1136 | - ::CopyMemory(&utf16[1], str.get_ptr(), len * 2); | |
1137 | - | |
1138 | - // swap byte order (big endian to little endian); | |
1139 | - for(size_t i = 0; i < len + 1; i++) { | |
1140 | - utf16[i] = (utf16[i] << 8) | (utf16[i] >> 8); | |
1141 | - } | |
1142 | - | |
1143 | - utf16[len + 1] = 0; // add NULL character | |
1144 | - | |
1145 | - return utf16; | |
1146 | - } | |
1147 | - | |
1148 | - UInt16Array makeTextFrame(LPCSTR pFrameID, const UInt16Array &data) { | |
1149 | - | |
1150 | - UInt16Array frame(data.size() + 5); | |
1151 | - | |
1152 | - UINT32 size = static_cast<UINT32>(data.size() * 2 + 1); // add charset code size (1byte) | |
1153 | - | |
1154 | - const UCHAR *pUCFrameID = reinterpret_cast<const UCHAR *>(pFrameID); | |
1155 | - const UCHAR *pUCSize = reinterpret_cast<const UCHAR *>(&size); | |
1156 | - | |
1157 | - frame[0] = ((UINT16)pUCFrameID[1]) << 8 | pUCFrameID[0]; | |
1158 | - frame[1] = ((UINT16)pUCFrameID[3]) << 8 | pUCFrameID[2]; | |
1159 | - | |
1160 | - frame[2] = ((UINT16)pUCSize[2]) << 8 | pUCSize[3]; | |
1161 | - frame[3] = ((UINT16)pUCSize[0]) << 8 | pUCSize[1]; | |
1162 | - | |
1163 | - frame[4] = 0; // frame flag | |
1164 | - | |
1165 | - ::CopyMemory(&frame[5], &data[0], data.size() * 2); | |
1166 | - | |
1167 | - return frame; | |
1168 | - } | |
1169 | - | |
1170 | - void close() { | |
1171 | - if(m_hMp3File != INVALID_HANDLE_VALUE) { | |
1172 | - ::CloseHandle(m_hMp3File); | |
1173 | - m_hMp3File = INVALID_HANDLE_VALUE; | |
1174 | - } | |
1175 | - } | |
1176 | - | |
1177 | - DWORD writeHeader(UINT32 size) | |
1178 | - { | |
1179 | - UInt16Array header(5); | |
1180 | - | |
1181 | - header[0] = ((UINT16)'D') << 8 | (UCHAR)'I'; | |
1182 | - header[1] = ((UINT16) 3 ) << 8 | (UCHAR)'3'; | |
1183 | - | |
1184 | - header[2] = 0; | |
1185 | - | |
1186 | - UInt16Array length = makeLength(size); | |
1187 | - | |
1188 | - header[3] = length[0]; | |
1189 | - header[4] = length[1]; | |
1190 | - | |
1191 | - DWORD dwSize; | |
1192 | - if(!::WriteFile(m_hMp3File, &header[0], 10, &dwSize, NULL)) { | |
1193 | - return ::GetLastError(); | |
1194 | - } | |
1195 | - | |
1196 | - return S_OK; | |
1197 | - } | |
1198 | - | |
1199 | - DWORD writeTextFrame(const UInt16Array &packet) | |
1200 | - { | |
1201 | - DWORD dwErr = S_OK; | |
1202 | - | |
1203 | - UCHAR charsetCode = 0x01; // UNICODE | |
1204 | - | |
1205 | - DWORD dwSize; | |
1206 | - if(!::WriteFile(m_hMp3File, &packet[0], 10, &dwSize, NULL)) { | |
1207 | - return ::GetLastError(); | |
1208 | - } | |
1209 | - if(!::WriteFile(m_hMp3File, &charsetCode, 1, &dwSize, NULL)) { | |
1210 | - return ::GetLastError(); | |
1211 | - } | |
1212 | - if(!::WriteFile(m_hMp3File, &packet[5], static_cast<DWORD>(packet.size() * 2 - 10), &dwSize, NULL)) { | |
1213 | - return ::GetLastError(); | |
1214 | - } | |
1215 | - | |
1216 | - return S_OK; | |
1217 | - } | |
1218 | - | |
1219 | - UInt16Array makeLength(UINT32 size) | |
1220 | - { | |
1221 | - UInt16Array length(2); | |
1222 | - UCHAR sizes[4]; | |
1223 | - | |
1224 | - /* | |
1225 | - 00001111111111111111111111111111 | |
1226 | - | |
1227 | - 1111111000000000000000000000 | |
1228 | - f e 0 0 0 0 0 | |
1229 | - 111111100000000000000 | |
1230 | - 1 f c 0 0 0 | |
1231 | - 11111110000000 | |
1232 | - 3 f 8 0 | |
1233 | - 1111111 | |
1234 | - 7 f | |
1235 | - */ | |
1236 | - | |
1237 | - sizes[3] = static_cast<UCHAR>((size & 0x0000007f) >> 0); | |
1238 | - sizes[2] = static_cast<UCHAR>((size & 0x00003f80) >> 7); | |
1239 | - sizes[1] = static_cast<UCHAR>((size & 0x001fc000) >> 14); | |
1240 | - sizes[0] = static_cast<UCHAR>((size & 0x0fe00000) >> 21); | |
1241 | - | |
1242 | - | |
1243 | - length[0] = ((UINT16)sizes[1]) << 8 | sizes[0]; | |
1244 | - length[1] = ((UINT16)sizes[3]) << 8 | sizes[2]; | |
1245 | - | |
1246 | - return length; | |
1247 | - } | |
1248 | - | |
1249 | - protected: | |
1250 | - | |
1251 | - TrackInfo m_info; | |
1252 | - HANDLE m_hMp3File; | |
1253 | -}; | |
1254 | - | |
1255 | -class DummyAmp | |
1256 | -{ | |
1257 | - public: | |
1258 | - | |
1259 | - DummyAmp() | |
1260 | - : m_bReady(false) | |
1261 | - , m_hInstGenMixi((HINSTANCE)INVALID_HANDLE_VALUE) | |
1262 | - , m_pGenMixi(NULL) | |
1263 | - , m_hWinampWnd((HWND)INVALID_HANDLE_VALUE) | |
1264 | - , m_GETPLAYLISTFILE_time(0) | |
1265 | - , m_hDirChangeNotify((HANDLE)INVALID_HANDLE_VALUE) | |
1266 | - , m_isDummyPlayInfoMp3Available(false) | |
1267 | - , m_isAnotherWinampWindowAvailable(false) | |
1268 | - { | |
1269 | - | |
1270 | - m_winampTitle = _T("Winamp"); | |
1271 | - } | |
1272 | - | |
1273 | - ~DummyAmp() | |
1274 | - { | |
1275 | - release(); | |
1276 | - destroyWindow(); | |
1277 | - closeDirChangeNotifyHandle(); | |
1278 | - } | |
1279 | - | |
1280 | - public: | |
1281 | - | |
1282 | - static DummyAmp *getInstance() | |
1283 | - { | |
1284 | - if(m_pMe == NULL) | |
1285 | - { | |
1286 | - m_pMe = new DummyAmp(); | |
1287 | - } | |
1288 | - | |
1289 | - return m_pMe; | |
1290 | - } | |
1291 | - | |
1292 | - void load() | |
1293 | - { | |
1294 | - TRACE_DUMMYAMP_INIT(_T("DummyAmp::load - called.")); | |
1295 | - | |
1296 | - // initialize gen_mixi_for_winamp | |
1297 | - initGenMixi(); | |
1298 | - | |
1299 | - // initialize dummy mp3 file, if dummy mp3 is enabled | |
1300 | - if(cfg_disable_dummy_mp3 == 0) { | |
1301 | - initDummyMp3(); | |
1302 | - } | |
1303 | - | |
1304 | - // set ready flag, if initialization successfully done | |
1305 | - if( (getGenMixi() != NULL) && ((cfg_disable_dummy_mp3 == 0) || (isDummyPlayInfoMp3Available() == true)) ){ | |
1306 | - setReady(true); | |
1307 | - } | |
1308 | - } | |
1309 | - | |
1310 | - void config() | |
1311 | - { | |
1312 | - TRACE_DUMMYAMP_INIT(_T("DummyAmp::config - called.")); | |
1313 | - | |
1314 | - if(getGenMixi() != NULL) { | |
1315 | - getGenMixi()->config(); | |
1316 | - } | |
1317 | - } | |
1318 | - | |
1319 | - void release() | |
1320 | - { | |
1321 | - TRACE_DUMMYAMP_INIT(_T("DummyAmp::release - called.")); | |
1322 | - | |
1323 | - // finalize gen_mixi_for_winamp | |
1324 | - finalizeGenMixi(); | |
1325 | - | |
1326 | - // finalize dummy mp3 file, if dummy mp3 is enbaled | |
1327 | - if(isDummyPlayInfoMp3Available()) | |
1328 | - { | |
1329 | - finalizeDummyMp3(); | |
1330 | - } | |
1331 | - } | |
1332 | - | |
1333 | - void clearDummyAmpTitle() | |
1334 | - { | |
1335 | - uSetWindowText(getWnd(), DEFAULT_DUMMYAMP_TITLE); | |
1336 | - } | |
1337 | - | |
1338 | - void createWindow() | |
1339 | - { | |
1340 | - TRACE_PLUGIN(_T("DummyAmp::createWindow - called.")); | |
1341 | - | |
1342 | - if(getWnd() == INVALID_HANDLE_VALUE) | |
1343 | - { | |
1344 | - if(getGenMixi() != NULL) | |
1345 | - { | |
1346 | - HWND hAnotherWinamp = FindWindowEx(NULL, NULL, _T("Winamp v1.x"), NULL); | |
1347 | - | |
1348 | - // found another winamp window | |
1349 | - if(hAnotherWinamp != NULL) | |
1350 | - { | |
1351 | - DEBUG_PLUGIN(_T("DummyAmp::createWindow - Winamp のウィンドウを検出しました。ハンドル: %08x"), hAnotherWinamp); | |
1352 | - | |
1353 | - DWORD dwAnotherWndProcessID; | |
1354 | - ::GetWindowThreadProcessId(hAnotherWinamp, &dwAnotherWndProcessID); | |
1355 | - | |
1356 | - DWORD dwFb2kProcessID = ::GetCurrentProcessId(); | |
1357 | - | |
1358 | - DEBUG_PLUGIN(_T("DummyAmp::createWindow - Winamp ウィンドウが属するプロセスのハンドル: %08x"), dwAnotherWndProcessID); | |
1359 | - DEBUG_PLUGIN(_T("DummyAmp::createWindow - 現在実行中の foobar2000 プロセスのハンドル: %08x"), dwFb2kProcessID); | |
1360 | - | |
1361 | - // another winamp window owned by foobar2000 process | |
1362 | - if(dwAnotherWndProcessID == dwFb2kProcessID) { | |
1363 | - // subclass it, because it's winamp api simulator plugin's window | |
1364 | - setWnd(subclassWinampWindow(hAnotherWinamp)); | |
1365 | - } else { | |
1366 | - LOG_ERROR( | |
1367 | - _T("DummyAmp::createWindow - 検出した Winamp ウィンドウが他のプロセスに属しています")); | |
1368 | - LOG_ERROR( | |
1369 | - _T("DummyAmp::createWindow - Winamp と思われるプログラムが実行されているため、") | |
1370 | - _T("mixi station への送信機能は使用できません")); | |
1371 | - LOG_ERROR( | |
1372 | - _T("DummyAmp::createWindow - 該当のプログラム(プロセスID:%d)を終了し、") | |
1373 | - _T("foobar2000 を再起動してください") | |
1374 | - , dwAnotherWndProcessID); | |
1375 | - | |
1376 | - // unset dummyAmp ready flag | |
1377 | - setReady(false); | |
1378 | - } | |
1379 | - } | |
1380 | - // create own winamp simulating window | |
1381 | - else | |
1382 | - { | |
1383 | - setWnd(createWinampWindow()); | |
1384 | - } | |
1385 | - | |
1386 | - // initialize gen_mixi_for_winamp, if winamp window successfully created or subclassed | |
1387 | - if(getWnd() != INVALID_HANDLE_VALUE) | |
1388 | - { | |
1389 | - getGenMixi()->hwndParent = getWnd(); | |
1390 | - getGenMixi()->hDllInstance = getHInstance(); | |
1391 | - getGenMixi()->init(); | |
1392 | - } | |
1393 | - else | |
1394 | - { | |
1395 | - // unset dummyAmp ready flag | |
1396 | - setReady(false); | |
1397 | - } | |
1398 | - } | |
1399 | - } | |
1400 | - } | |
1401 | - | |
1402 | - void refreshAmpInfo() | |
1403 | - { | |
1404 | -#if !defined(CONTROL_SEND_TIMING) | |
1405 | - // increment play counter on dummyamp | |
1406 | - getPlayInfo().incrementPlayCount(); | |
1407 | - | |
1408 | - // update dummyamp title | |
1409 | - updateDummyAmpTitle(); | |
1410 | -#endif | |
1411 | - // use currently playing mp3 or ogg/vorbis file instead when dummy playinfo mp3 file disabled by user | |
1412 | - // (other codec types will be ignored, because they are not supported by gen_mixi_for_winamp) | |
1413 | - if(cfg_disable_dummy_mp3 == 1) | |
1414 | - { | |
1415 | - // set playinfo mp3 file path to dummyAmp | |
1416 | - getPlayInfo().setPlayInfoMp3Path(m_trackInfo.getString(FORMAT_FILEPATH).c_str()); | |
1417 | - | |
1418 | - // set playinfo mp3 file available flag to dummyAmp | |
1419 | - LPCSTR codec = m_trackInfo.getString(FORMAT_CODEC).c_str(); | |
1420 | - getPlayInfo().setPlayInfoMp3Available(IS_SUPPORTED_FORMAT_BY_GEN_MIXI(codec)); | |
1421 | - } | |
1422 | - else | |
1423 | - { | |
1424 | - // check dummy playinfo mp3 exists and writable | |
1425 | - if(isDummyPlayInfoMp3Available()) | |
1426 | - { | |
1427 | - // update dummy mp3 file | |
1428 | - tstring playInfoMp3Path = PathInfo::getDummyPlayInfoMp3Path(); | |
1429 | -#if 1 | |
1430 | - id3Info id3Info(m_trackInfo); | |
1431 | - DWORD dwErrCode; | |
1432 | - | |
1433 | - if(( dwErrCode = id3Info.write(playInfoMp3Path.c_str()) ) == S_OK) | |
1434 | - { | |
1435 | - string_utf8_from_os dummyMp3Path8(playInfoMp3Path.c_str()); | |
1436 | - | |
1437 | - // set dummy playinfo mp3 file path to dummyAmp | |
1438 | - getPlayInfo().setPlayInfoMp3Path(dummyMp3Path8); | |
1439 | - | |
1440 | - // set playinfo mp3 file available flag to dummyAmp | |
1441 | - getPlayInfo().setPlayInfoMp3Available(true); | |
1442 | - } | |
1443 | - else | |
1444 | - { | |
1445 | - putLogError(_T("DummyAmp::refreshAmpInfo"), _T("ダミーMP3ファイルの書き込み中にエラーが発生しました"), dwErrCode); | |
1446 | - LOG_ERROR(_T("DummyAmp::refreshAmpInfo - ファイルパス: %s"), playInfoMp3Path.c_str()); | |
1447 | - | |
1448 | - // set playinfo mp3 file available flag | |
1449 | - getPlayInfo().setPlayInfoMp3Available(false); | |
1450 | - | |
1451 | - // unset dummyAmp ready flag | |
1452 | - setReady(false); | |
1453 | - } | |
1454 | -#else | |
1455 | - // set id3v2 informations | |
1456 | - | |
1457 | - string_utf8_from_os dummyMp3Path8(playInfoMp3Path.c_str()); | |
1458 | - string_ansi_from_utf8 dummyMp3PathAnsi(dummyMp3Path8); | |
1459 | - ID3_Tag dummySong(dummyMp3PathAnsi); | |
1460 | - | |
1461 | - string_wide_from_utf8 title_utf16(m_trackInfo.getString(FORMAT_TRACKTITLE, true).c_str()); | |
1462 | - string_wide_from_utf8 artist_utf16(m_trackInfo.getString(FORMAT_ARTIST, true).c_str()); | |
1463 | - string_wide_from_utf8 album_utf16(m_trackInfo.getString(FORMAT_ALBUMTITLE, true).c_str()); | |
1464 | - string_wide_from_utf8 genre_utf16(m_trackInfo.getString(FORMAT_GENRE, true).c_str()); | |
1465 | - | |
1466 | - AddTitle(&dummySong, title_utf16, true); | |
1467 | - AddArtist(&dummySong, artist_utf16, true); | |
1468 | - AddAlbum(&dummySong, album_utf16, true); | |
1469 | - AddGenre(&dummySong, genre_utf16, true); | |
1470 | - | |
1471 | - // write id3v2 tag | |
1472 | - dummySong.SetPadding(false); | |
1473 | - dummySong.SetUnsync(false); | |
1474 | - if(dummySong.Update(ID3TT_ID3V2) != ID3TT_NONE) | |
1475 | - { | |
1476 | - // set dummy playinfo mp3 file path to dummyAmp | |
1477 | - getPlayInfo().setPlayInfoMp3Path(dummyMp3Path8); | |
1478 | - | |
1479 | - // set playinfo mp3 file available flag to dummyAmp | |
1480 | - getPlayInfo().setPlayInfoMp3Available(true); | |
1481 | - } | |
1482 | - else | |
1483 | - { | |
1484 | - LOG_ERROR(_T("DummyAmp::refreshAmpInfo - ID3_Tag::Update(ID3TT_ID3V2) failed.")); | |
1485 | - | |
1486 | - // set playinfo mp3 file available flag | |
1487 | - getPlayInfo().setPlayInfoMp3Available(false); | |
1488 | - | |
1489 | - // unset dummyAmp ready flag | |
1490 | - setReady(false); | |
1491 | - } | |
1492 | -#endif | |
1493 | - } | |
1494 | - else | |
1495 | - { | |
1496 | - // reset playinfo mp3 file available flag | |
1497 | - getPlayInfo().setPlayInfoMp3Available(false); | |
1498 | - | |
1499 | - LOG_WARN(_T("DummyAmp::refreshAmpInfo - ダミーMP3ファイルが無効になっているため、送信情報を書き込めません。")); | |
1500 | - } | |
1501 | - } | |
1502 | - | |
1503 | -#if !defined(CONTROL_SEND_TIMING) | |
1504 | - // set dummyamp status PLAY_START | |
1505 | - getPlayInfo().setPlayStatusStart(); | |
1506 | -#endif | |
1507 | - } | |
1508 | - | |
1509 | - public: | |
1510 | - | |
1511 | - bool isReady() const { | |
1512 | - return m_bReady; | |
1513 | - } | |
1514 | - | |
1515 | - HWND getWnd() const { | |
1516 | - return m_hWinampWnd; | |
1517 | - } | |
1518 | - | |
1519 | - const TrackInfo &getTrackInfo() const { | |
1520 | - return m_trackInfo; | |
1521 | - } | |
1522 | - | |
1523 | - TrackInfo &getMutableTrackInfo() { | |
1524 | - return m_trackInfo; | |
1525 | - } | |
1526 | - | |
1527 | - void setTrackInfo(const TrackInfo &trackInfo) { | |
1528 | - m_trackInfo = trackInfo; | |
1529 | - } | |
1530 | - | |
1531 | - PlayInfo &getPlayInfo() { | |
1532 | - return m_playInfo; | |
1533 | - } | |
1534 | - | |
1535 | - PlayInfo &getRawPlayInfo() { | |
1536 | - return m_rawPlayInfo; | |
1537 | - } | |
1538 | - | |
1539 | - | |
1540 | - void setPlaylistTitle(LPCTSTR pTitle) { | |
1541 | - | |
1542 | - TRACE_PLUGIN(_T("DummyAmp::setPlayListTitle - %s"), pTitle); | |
1543 | - | |
1544 | - m_playlistTitle = pTitle; | |
1545 | - | |
1546 | - string_utf8_from_os playListTitle8(pTitle); | |
1547 | - | |
1548 | - if(cfg_disable_ansi_trans == 1) | |
1549 | - { | |
1550 | - | |
1551 | - m_playlistTitle8 = playListTitle8; | |
1552 | - } | |
1553 | - else | |
1554 | - { | |
1555 | - string_ansi_from_utf8 playListTitleAnsi(playListTitle8); | |
1556 | - | |
1557 | - m_playlistTitle8 = playListTitleAnsi; | |
1558 | - } | |
1559 | - } | |
1560 | - | |
1561 | - const tstring &getPlaylistTitle() const { | |
1562 | - return m_playlistTitle; | |
1563 | - } | |
1564 | - | |
1565 | - const string8 &getPlaylistTitle8() const { | |
1566 | - return m_playlistTitle8; | |
1567 | - } | |
1568 | - | |
1569 | - void setWinampTitle(LPCTSTR pTitle) { | |
1570 | - | |
1571 | - TRACE_PLUGIN(_T("DummyAmp::setWinampTitle - %s"), pTitle); | |
1572 | - | |
1573 | - m_winampTitle = pTitle; | |
1574 | - } | |
1575 | - | |
1576 | - const tstring &getWinampTitle() const { | |
1577 | - return m_winampTitle; | |
1578 | - } | |
1579 | - | |
1580 | - void setBaseWinampTitle(LPCTSTR pTitle) | |
1581 | - { | |
1582 | - TRACE_PLUGIN(_T("DummyAmp::setRawWinampTitle - %s"), pTitle); | |
1583 | - | |
1584 | - m_baseWinampTitle = pTitle; | |
1585 | - | |
1586 | - updateDummyAmpTitle(); | |
1587 | - } | |
1588 | - | |
1589 | - const tstring &getBaseWinampTitle() const { | |
1590 | - return m_baseWinampTitle; | |
1591 | - } | |
1592 | - | |
1593 | - const tstring &getDummyPlayInfoMp3Path() const { | |
1594 | - return m_dummyPlayInfoMp3Path; | |
1595 | - } | |
1596 | - | |
1597 | - bool isDummyPlayInfoMp3Available() const { | |
1598 | - return m_isDummyPlayInfoMp3Available; | |
1599 | - } | |
1600 | - | |
1601 | - bool isAnotherWinampWindowAvailable() const { | |
1602 | - return m_isAnotherWinampWindowAvailable; | |
1603 | - } | |
1604 | - | |
1605 | - void showDummyAmpWindow(bool bShow) { | |
1606 | - showDummyAmpWindow(getWnd(), bShow); | |
1607 | - } | |
1608 | - | |
1609 | - protected: | |
1610 | - | |
1611 | - void initGenMixi() | |
1612 | - { | |
1613 | - string_os_from_utf8 path(cfg_gen_mixi_path); | |
1614 | - tstring genMixiPath = path; | |
1615 | - genMixiPath += GEN_MIXI_FILE_NAME; | |
1616 | - | |
1617 | - setHInstance(::LoadLibrary(genMixiPath.c_str())); | |
1618 | - | |
1619 | - if(getHInstance() == NULL) | |
1620 | - { | |
1621 | - setHInstance((HINSTANCE)INVALID_HANDLE_VALUE); | |
1622 | - | |
1623 | - tstring msg; | |
1624 | - msg = GEN_MIXI_FILE_NAME _T(" が見つかりません。\n以下のパスにファイルが存在するか確認してください。\n"); | |
1625 | - msg += genMixiPath; | |
1626 | - | |
1627 | - string_utf8_from_os uMsg(msg.c_str()); | |
1628 | - | |
1629 | - uMessageBox(NULL, uMsg, PLUGIN_CAPTION, MB_ICONEXCLAMATION | MB_OK); | |
1630 | - } | |
1631 | - else | |
1632 | - { | |
1633 | - winampGeneralPurposePluginGetter funcWinampGetGeneralPurposePlugin = NULL; | |
1634 | - | |
1635 | - funcWinampGetGeneralPurposePlugin = (winampGeneralPurposePluginGetter) | |
1636 | - ::GetProcAddress(getHInstance(), GEN_MIXI_FUNC_NAME_GET_GENERAL_PURPOSE_PLUGIN); | |
1637 | - | |
1638 | - if(funcWinampGetGeneralPurposePlugin != NULL) | |
1639 | - { | |
1640 | - setGenMixi(funcWinampGetGeneralPurposePlugin()); | |
1641 | - // create window later. | |
1642 | - } | |
1643 | - else | |
1644 | - { | |
1645 | - tstring msg; | |
1646 | - msg = _T("関数 ") _T(GEN_MIXI_FUNC_NAME_GET_GENERAL_PURPOSE_PLUGIN) _T("() が見つかりません。\n") | |
1647 | - GEN_MIXI_FILE_NAME _T(" が壊れている可能性があります。"); | |
1648 | - | |
1649 | - string_utf8_from_os uMsg(msg.c_str()); | |
1650 | - | |
1651 | - uMessageBox(NULL, uMsg, PLUGIN_CAPTION, MB_ICONEXCLAMATION | MB_OK); | |
1652 | - } | |
1653 | - } | |
1654 | - } | |
1655 | - | |
1656 | - void initDummyMp3() | |
1657 | - { | |
1658 | - // if dummy mp3 file not exist | |
1659 | - tstring dummyPlayInfoMp3Path = PathInfo::getDummyPlayInfoMp3Path(); | |
1660 | - DWORD dwAttr = ::GetFileAttributes(dummyPlayInfoMp3Path.c_str()); | |
1661 | - | |
1662 | - if(dwAttr == -1) | |
1663 | - { | |
1664 | - // create dummy mp3 file | |
1665 | - HANDLE hMp3File = ::CreateFile( | |
1666 | - dummyPlayInfoMp3Path.c_str(), 0, 0, NULL, | |
1667 | - CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL | |
1668 | - ); | |
1669 | - | |
1670 | - if(hMp3File == INVALID_HANDLE_VALUE) | |
1671 | - { | |
1672 | - DWORD dwErrCode = ::GetLastError(); | |
1673 | - putLogError(_T("DummyAmp::initDummyMp3"), _T("ダミーMP3ファイルの作成中にエラーが発生しました"), dwErrCode); | |
1674 | - LOG_ERROR(_T("DummyAmp::initDummyMp3 - ファイルパス: %s"), dummyPlayInfoMp3Path.c_str()); | |
1675 | - | |
1676 | - LOG_ERROR(_T("DummyAmp::initDummyMp3 - ダミーMP3ファイルが使用できないため、送信機能は無効になります")); | |
1677 | - } | |
1678 | - else | |
1679 | - { | |
1680 | - DEBUG_DUMMYAMP_INIT(_T("DummyAmp::initDummyMp3 - ダミーMP3ファイルを [%s] に作成しました"), dummyPlayInfoMp3Path.c_str()); | |
1681 | - | |
1682 | - ::CloseHandle(hMp3File); | |
1683 | - | |
1684 | - setDummyPlayInfoMp3Path(dummyPlayInfoMp3Path); | |
1685 | - setDummyPlayInfoMp3Available(true); | |
1686 | - } | |
1687 | - } | |
1688 | - else if((dwAttr & FILE_ATTRIBUTE_READONLY) != 0) | |
1689 | - { | |
1690 | - LOG_ERROR(_T("DummyAmp::initDummyMp3 - ダミーMP3ファイルがパス [%s] 上に既に存在しますが、") | |
1691 | - _T("読み込み専用属性のため書き込みできません"), dummyPlayInfoMp3Path.c_str()); | |
1692 | - | |
1693 | - LOG_ERROR(_T("DummyAmp::initDummyMp3 - ダミーMP3ファイルが使用できないため、送信機能は無効になります")); | |
1694 | - } | |
1695 | - else | |
1696 | - { | |
1697 | - LOG_WARN(_T("DummyAmp::initDummyMp3 - ダミーMP3ファイルがパス [%s] 上に既に存在します"), dummyPlayInfoMp3Path.c_str()); | |
1698 | - LOG_WARN(_T("DummyAmp::initDummyMp3 - このMP3ファイルは逐次上書きされ、終了時に削除されます")); | |
1699 | - | |
1700 | - setDummyPlayInfoMp3Path(dummyPlayInfoMp3Path); | |
1701 | - setDummyPlayInfoMp3Available(true); | |
1702 | - } | |
1703 | - } | |
1704 | - | |
1705 | - void finalizeGenMixi() | |
1706 | - { | |
1707 | - if(getHInstance() != INVALID_HANDLE_VALUE) | |
1708 | - { | |
1709 | - if(getGenMixi() != NULL) | |
1710 | - { | |
1711 | - getGenMixi()->quit(); | |
1712 | - setGenMixi(NULL); | |
1713 | - } | |
1714 | - ::FreeLibrary(getHInstance()); | |
1715 | - setHInstance((HINSTANCE)INVALID_HANDLE_VALUE); | |
1716 | - } | |
1717 | - | |
1718 | - } | |
1719 | - | |
1720 | - void finalizeDummyMp3() | |
1721 | - { | |
1722 | - tstring dummyPlayInfoMp3Path = getDummyPlayInfoMp3Path(); | |
1723 | - | |
1724 | - if(::DeleteFile(dummyPlayInfoMp3Path.c_str()) == FALSE) | |
1725 | - { | |
1726 | - DWORD dwErrCode = ::GetLastError(); | |
1727 | - putLogError(_T("DummyAmp::finalizeDummyMp3"), _T("ダミーMP3ファイルの削除中にエラーが発生しました"), dwErrCode); | |
1728 | - LOG_ERROR(_T("DummyAmp::finalizeDummyMp3 - ファイルパス: %s"), dummyPlayInfoMp3Path.c_str()); | |
1729 | - } | |
1730 | - else | |
1731 | - { | |
1732 | - DEBUG_DUMMYAMP_INIT(_T("DummyAmp::finalizeDummyMp3 - ダミーMP3ファイル [%s] を削除しました"), dummyPlayInfoMp3Path.c_str()); | |
1733 | - setDummyPlayInfoMp3Available(false); | |
1734 | - } | |
1735 | - } | |
1736 | - | |
1737 | - void updateDummyAmpTitle() | |
1738 | - { | |
1739 | - bool bDisableDuplicatedSong = (cfg_disable_duplicate_song == 0); | |
1740 | - tstring winampTitle = makeDummyAmpTitle(getBaseWinampTitle(), bDisableDuplicatedSong); | |
1741 | - | |
1742 | - setWinampTitle(winampTitle.c_str()); | |
1743 | - | |
1744 | - if(isAnotherWinampWindowAvailable() == false) { | |
1745 | - ::SetWindowText(getWnd(), winampTitle.c_str()); | |
1746 | - } | |
1747 | - } | |
1748 | - | |
1749 | - protected: | |
1750 | - | |
1751 | - void setReady(bool bReady) { | |
1752 | - m_bReady = bReady; | |
1753 | - } | |
1754 | - | |
1755 | - void setWnd(HWND hWnd) { | |
1756 | - m_hWinampWnd = hWnd; | |
1757 | - } | |
1758 | - | |
1759 | - HINSTANCE getHInstance() const { | |
1760 | - return m_hInstGenMixi; | |
1761 | - } | |
1762 | - | |
1763 | - void setHInstance(HINSTANCE hInst) { | |
1764 | - m_hInstGenMixi = hInst; | |
1765 | - } | |
1766 | - | |
1767 | - winampGeneralPurposePlugin *getGenMixi() const { | |
1768 | - return m_pGenMixi; | |
1769 | - } | |
1770 | - | |
1771 | - void setGenMixi(winampGeneralPurposePlugin *pGenMixi) { | |
1772 | - m_pGenMixi = pGenMixi; | |
1773 | - } | |
1774 | - | |
1775 | - void setDummyPlayInfoMp3Path(const tstring &path) { | |
1776 | - m_dummyPlayInfoMp3Path = path; | |
1777 | - } | |
1778 | - | |
1779 | - void setDummyPlayInfoMp3Available(bool isAvailable) { | |
1780 | - m_isDummyPlayInfoMp3Available = isAvailable; | |
1781 | - } | |
1782 | - | |
1783 | - void setAnotherWinampWindowAvailable(bool isAvailable) { | |
1784 | - m_isAnotherWinampWindowAvailable = isAvailable; | |
1785 | - } | |
1786 | - | |
1787 | - int getGetPlayListFileTime() const { | |
1788 | - return m_GETPLAYLISTFILE_time; | |
1789 | - } | |
1790 | - | |
1791 | - void setGetPlayListFileTime(int time) { | |
1792 | - m_GETPLAYLISTFILE_time = time; | |
1793 | - } | |
1794 | - | |
1795 | - HANDLE getDirChangeNotifyHandle() const { | |
1796 | - return m_hDirChangeNotify; | |
1797 | - } | |
1798 | - | |
1799 | - void setDirChangeNotifyHandle(HANDLE handle) { | |
1800 | - m_hDirChangeNotify = handle; | |
1801 | - } | |
1802 | - | |
1803 | - protected: | |
1804 | - | |
1805 | - HWND createWinampWindow() | |
1806 | - { | |
1807 | - TRACE_PLUGIN(_T("DummyAmp::createWinampWindow - called.")); | |
1808 | - | |
1809 | - static bool isInited = false; | |
1810 | - | |
1811 | -#if IS_FB2K_VER08 | |
1812 | - static const char class_name[] = "Winamp v1.x"; | |
1813 | - if (!isInited) | |
1814 | - { | |
1815 | - isInited = true; | |
1816 | - uWNDCLASS wc; | |
1817 | - memset(&wc,0,sizeof(wc)); | |
1818 | - wc.style = 0; | |
1819 | - wc.lpfnWndProc = windowproc; | |
1820 | - wc.hInstance = core_api::get_my_instance(); | |
1821 | - wc.hCursor = NULL; //uLoadCursor(0, IDC_ARROW); | |
1822 | - wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); | |
1823 | - wc.lpszClassName = class_name; | |
1824 | - uRegisterClass(&wc); | |
1825 | - } | |
1826 | - HWND hWinampWnd = uCreateWindowEx( | |
1827 | - 0, class_name, DEFAULT_DUMMYAMP_TITLE, | |
1828 | - WS_OVERLAPPED|WS_CAPTION|WS_SIZEBOX, | |
1829 | - CW_USEDEFAULT, CW_USEDEFAULT, 300, 150, | |
1830 | -#if 1 | |
1831 | - core_api::get_main_window(), 0, core_api::get_my_instance(), NULL | |
1832 | -#else | |
1833 | - NULL, 0, core_api::get_my_instance(), NULL | |
1834 | -#endif | |
1835 | - ); | |
1836 | -#elif IS_FB2K_VER09 | |
1837 | - static const TCHAR class_name[] = _T("Winamp v1.x"); | |
1838 | - if (!isInited) | |
1839 | - { | |
1840 | - isInited = true; | |
1841 | - WNDCLASS wc; | |
1842 | - memset(&wc,0,sizeof(wc)); | |
1843 | - wc.style = 0; | |
1844 | - wc.lpfnWndProc = windowproc; | |
1845 | - wc.hInstance = core_api::get_my_instance(); | |
1846 | - wc.hCursor = NULL; //uLoadCursor(0, IDC_ARROW); | |
1847 | - wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); | |
1848 | - wc.lpszClassName = class_name; | |
1849 | - RegisterClass(&wc); | |
1850 | - } | |
1851 | - HWND hWinampWnd = CreateWindowEx( | |
1852 | - 0, class_name, _T(DEFAULT_DUMMYAMP_TITLE), | |
1853 | - WS_OVERLAPPED|WS_CAPTION|WS_SIZEBOX, | |
1854 | - CW_USEDEFAULT, CW_USEDEFAULT, 300, 150, | |
1855 | -#if 1 | |
1856 | - core_api::get_main_window(), 0, core_api::get_my_instance(), NULL | |
1857 | -#else | |
1858 | - NULL, 0, core_api::get_my_instance(), NULL | |
1859 | -#endif | |
1860 | - ); | |
1861 | -#endif | |
1862 | - if (!hWinampWnd) | |
1863 | - { | |
1864 | - DWORD dwErrCode = ::GetLastError(); | |
1865 | - putLogError(_T("DummyAmp::createWinampWindow"), _T("DummyAmp ウィンドウの生成に失敗しました"), dwErrCode); | |
1866 | - | |
1867 | - return NULL; | |
1868 | - } | |
1869 | - | |
1870 | - DEBUG_PLUGIN(_T("DummyAmp::createWinampWindow - DummyAmp ウィンドウを生成しました")); | |
1871 | - | |
1872 | - showDummyAmpWindow(hWinampWnd, cfg_show_dummyamp == 1); | |
1873 | - | |
1874 | - return hWinampWnd; | |
1875 | - } | |
1876 | - | |
1877 | - HWND subclassWinampWindow(HWND hAnotherWinampWnd) { | |
1878 | - // subclass another dummyamp window | |
1879 | - m_pfnOldAnotherWinampProc = | |
1880 | - SetWindowLongPtr(hAnotherWinampWnd, GWL_WNDPROC, WNDPROC_TO_LONG_PTR(hookWinampWindowProc)); | |
1881 | - | |
1882 | - if(hAnotherWinampWnd != NULL) | |
1883 | - { | |
1884 | - DEBUG_PLUGIN(_T("DummyAmp::subclassWinampWindow - API エミュレータと思われる Winamp ウィンドウのプロシージャをフックしました")); | |
1885 | - setAnotherWinampWindowAvailable(true); | |
1886 | - | |
1887 | - return hAnotherWinampWnd; | |
1888 | - } | |
1889 | - else | |
1890 | - { | |
1891 | - DWORD dwErrCode = ::GetLastError(); | |
1892 | - putLogError(_T("DummyAmp::subclassWinampWindow"), _T("Winamp ウィンドウのサブクラス化に失敗しました"), dwErrCode); | |
1893 | - | |
1894 | - LOG_ERROR(_T("DummyAmp::subclassWinampWindow - Winamp ウィンドウのプロシージャをフックできなかったため、送信機能は無効になります")); | |
1895 | - } | |
1896 | - | |
1897 | - return (HWND)INVALID_HANDLE_VALUE; | |
1898 | - } | |
1899 | - | |
1900 | - void unsubclassWinampWindow() { | |
1901 | - SetWindowLongPtr(getWnd(), GWL_WNDPROC, m_pfnOldAnotherWinampProc); | |
1902 | - } | |
1903 | - | |
1904 | - void showDummyAmpWindow(HWND hWinampWnd, bool bShow) | |
1905 | - { | |
1906 | - if(bShow) { | |
1907 | - ShowWindow(hWinampWnd, SW_SHOW); | |
1908 | - } else { | |
1909 | - ShowWindow(hWinampWnd, SW_HIDE); | |
1910 | - } | |
1911 | - } | |
1912 | - | |
1913 | - void destroyWindow() | |
1914 | - { | |
1915 | - TRACE_PLUGIN(_T("DummyAmp::destroyWindow - called.")); | |
1916 | - | |
1917 | - if(getWnd() != INVALID_HANDLE_VALUE) | |
1918 | - { | |
1919 | - if(isAnotherWinampWindowAvailable() == false) { | |
1920 | - uDestroyWindow(getWnd()); | |
1921 | - } else { | |
1922 | - unsubclassWinampWindow(); | |
1923 | - | |
1924 | - DEBUG_PLUGIN(_T("DummyAmp::destroyWindow - Winamp ウィンドウのサブクラス化を解除しました")); | |
1925 | - } | |
1926 | - | |
1927 | - setWnd((HWND)INVALID_HANDLE_VALUE); | |
1928 | - } | |
1929 | - } | |
1930 | - | |
1931 | - void closeDirChangeNotifyHandle() | |
1932 | - { | |
1933 | - TRACE_PLUGIN(_T("DummyAmp::closeDirChangeNotifyHandle - called.")); | |
1934 | - | |
1935 | - if(m_hDirChangeNotify != INVALID_HANDLE_VALUE) | |
1936 | - { | |
1937 | - ::FindCloseChangeNotification(m_hDirChangeNotify); | |
1938 | - TRACE_PLUGIN(_T("DummyAmp::closeDirChangeNotifyHandle - ディレクトリ変更通知イベントのハンドル (ID:%08x) を閉じました"), m_hDirChangeNotify); | |
1939 | - | |
1940 | - m_hDirChangeNotify = (HANDLE)INVALID_HANDLE_VALUE; | |
1941 | - } | |
1942 | - } | |
1943 | - | |
1944 | - tstring makeDummyAmpTitle(const tstring &rawTitle, bool bCounterReflection) | |
1945 | - { | |
1946 | - TRACE_PLUGIN(_T("DummyAmp::makeDummyAmpTitle - called.")); | |
1947 | - | |
1948 | - Str64K formatBuf; | |
1949 | - | |
1950 | - if(bCounterReflection) | |
1951 | - { | |
1952 | - _stprintf_s( | |
1953 | - formatBuf, sizeof(formatBuf) / sizeof(TCHAR), | |
1954 | - _T("%d. %s - ") _T(DEFAULT_WINAMP_TITLE), | |
1955 | - getPlayInfo().getPlayCount(), | |
1956 | - (LPCTSTR)rawTitle.c_str() | |
1957 | - ); | |
1958 | - } | |
1959 | - else | |
1960 | - { | |
1961 | - _stprintf_s( | |
1962 | - formatBuf, sizeof(formatBuf) / sizeof(TCHAR), | |
1963 | - _T("%d. %s - ") _T(DEFAULT_WINAMP_TITLE), | |
1964 | - m_trackInfo.getNumber(FORMAT_LISTINDEX), | |
1965 | - (LPCTSTR)rawTitle.c_str() | |
1966 | - ); | |
1967 | - } | |
1968 | - | |
1969 | - return formatBuf; | |
1970 | - } | |
1971 | - | |
1972 | - void refreshTitle() | |
1973 | - { | |
1974 | - // get formatted dynamic titles | |
1975 | - string8 dummyAmp_title8; | |
1976 | - string8 playlist_title8; | |
1977 | -#if IS_FB2K_VER08 | |
1978 | - metadb_handle *track = play_control::get()->get_now_playing(); | |
1979 | - if(track) | |
1980 | - { | |
1981 | - play_control::get()->playback_format_title_ex(track, dummyAmp_title8, cfg_dummyamp_title_format, NULL, false, true); | |
1982 | - play_control::get()->playback_format_title_ex(track, playlist_title8, cfg_dummyamp_playlist_format, NULL, false, true); | |
1983 | - track->handle_release(); | |
1984 | - } | |
1985 | -#elif IS_FB2K_VER09 | |
1986 | - metadb_handle_ptr track; | |
1987 | - static_api_ptr_t<playback_control>()->get_now_playing(track); | |
1988 | - | |
1989 | - service_ptr_t<titleformat_object> titleformat; | |
1990 | - | |
1991 | - static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, cfg_dummyamp_title_format); | |
1992 | - static_api_ptr_t<playback_control>()->playback_format_title_ex(track, NULL, dummyAmp_title8, titleformat, NULL, play_control::display_level_all); | |
1993 | - | |
1994 | - static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, cfg_dummyamp_playlist_format); | |
1995 | - static_api_ptr_t<playback_control>()->playback_format_title_ex(track, NULL, playlist_title8, titleformat, NULL, play_control::display_level_all); | |
1996 | -#endif | |
1997 | - // convert utf8 track informations to os charset | |
1998 | - string_os_from_utf8 dummyAmp_title(dummyAmp_title8); | |
1999 | - string_os_from_utf8 playlist_title(playlist_title8); | |
2000 | - | |
2001 | - // set base dummyamp title to dummyamp | |
2002 | - setBaseWinampTitle(dummyAmp_title); | |
2003 | - | |
2004 | - // set dummyamp playlist current item title to dummyamp | |
2005 | - setPlaylistTitle(playlist_title); | |
2006 | - } | |
2007 | - | |
2008 | -#if 0 | |
2009 | - private: | |
2010 | - | |
2011 | - ID3_Frame* AddArtist(ID3_Tag *tag, const wchar_t *text, bool replace) | |
2012 | - { | |
2013 | - ID3_Frame* frame = NULL; | |
2014 | - if (NULL != tag && NULL != text && lstrlen(text) > 0) | |
2015 | - { | |
2016 | - if (replace) | |
2017 | - { | |
2018 | - RemoveArtists(tag); | |
2019 | - } | |
2020 | - if (replace || | |
2021 | - (tag->Find(ID3FID_LEADARTIST) == NULL && | |
2022 | - tag->Find(ID3FID_BAND) == NULL && | |
2023 | - tag->Find(ID3FID_CONDUCTOR) == NULL && | |
2024 | - tag->Find(ID3FID_COMPOSER) == NULL)) | |
2025 | - { | |
2026 | - frame = new ID3_Frame(ID3FID_LEADARTIST); | |
2027 | - if (frame) | |
2028 | - { | |
2029 | - frame->GetField(ID3FN_TEXT)->SetEncoding(ID3TE_UNICODE); | |
2030 | - frame->GetField(ID3FN_TEXT)->Set(SwapByteOrder(text)); | |
2031 | - frame->GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE); | |
2032 | - tag->AttachFrame(frame); | |
2033 | - } | |
2034 | - } | |
2035 | - } | |
2036 | - return frame; | |
2037 | - } | |
2038 | - | |
2039 | - size_t RemoveArtists(ID3_Tag *tag) | |
2040 | - { | |
2041 | - size_t num_removed = 0; | |
2042 | - ID3_Frame *frame = NULL; | |
2043 | - | |
2044 | - if (NULL == tag) | |
2045 | - { | |
2046 | - return num_removed; | |
2047 | - } | |
2048 | - | |
2049 | - while ((frame = tag->Find(ID3FID_LEADARTIST)) != NULL) | |
2050 | - { | |
2051 | - frame = tag->RemoveFrame(frame); | |
2052 | - delete frame; | |
2053 | - num_removed++; | |
2054 | - } | |
2055 | - while ((frame = tag->Find(ID3FID_BAND)) != NULL) | |
2056 | - { | |
2057 | - frame = tag->RemoveFrame(frame); | |
2058 | - delete frame; | |
2059 | - num_removed++; | |
2060 | - } | |
2061 | - while ((frame = tag->Find(ID3FID_CONDUCTOR)) != NULL) | |
2062 | - { | |
2063 | - frame = tag->RemoveFrame(frame); | |
2064 | - delete frame; | |
2065 | - num_removed++; | |
2066 | - } | |
2067 | - while ((frame = tag->Find(ID3FID_COMPOSER)) != NULL) | |
2068 | - { | |
2069 | - frame = tag->RemoveFrame(frame); | |
2070 | - delete frame; | |
2071 | - num_removed++; | |
2072 | - } | |
2073 | - | |
2074 | - return num_removed; | |
2075 | - } | |
2076 | - | |
2077 | - ID3_Frame* AddAlbum(ID3_Tag *tag, const wchar_t *text, bool replace) | |
2078 | - { | |
2079 | - ID3_Frame* frame = NULL; | |
2080 | - if (NULL != tag && NULL != text && lstrlen(text) > 0) | |
2081 | - { | |
2082 | - if (replace) | |
2083 | - { | |
2084 | - RemoveAlbums(tag); | |
2085 | - } | |
2086 | - if (replace || tag->Find(ID3FID_ALBUM) == NULL) | |
2087 | - { | |
2088 | - frame = new ID3_Frame(ID3FID_ALBUM); | |
2089 | - if (frame) | |
2090 | - { | |
2091 | - frame->GetField(ID3FN_TEXT)->SetEncoding(ID3TE_UNICODE); | |
2092 | - frame->GetField(ID3FN_TEXT)->Set(SwapByteOrder(text)); | |
2093 | - frame->GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE); | |
2094 | - tag->AttachFrame(frame); | |
2095 | - } | |
2096 | - } | |
2097 | - } | |
2098 | - | |
2099 | - return frame; | |
2100 | - } | |
2101 | - | |
2102 | - size_t RemoveAlbums(ID3_Tag *tag) | |
2103 | - { | |
2104 | - size_t num_removed = 0; | |
2105 | - ID3_Frame *frame = NULL; | |
2106 | - | |
2107 | - if (NULL == tag) | |
2108 | - { | |
2109 | - return num_removed; | |
2110 | - } | |
2111 | - | |
2112 | - while ((frame = tag->Find(ID3FID_ALBUM)) != NULL) | |
2113 | - { | |
2114 | - frame = tag->RemoveFrame(frame); | |
2115 | - delete frame; | |
2116 | - num_removed++; | |
2117 | - } | |
2118 | - | |
2119 | - return num_removed; | |
2120 | - } | |
2121 | - | |
2122 | - ID3_Frame* AddTitle(ID3_Tag *tag, const wchar_t *text, bool replace) | |
2123 | - { | |
2124 | - ID3_Frame* frame = NULL; | |
2125 | - if (NULL != tag && NULL != text && lstrlen(text) > 0) | |
2126 | - { | |
2127 | - if (replace) | |
2128 | - { | |
2129 | - RemoveTitles(tag); | |
2130 | - } | |
2131 | - if (replace || tag->Find(ID3FID_TITLE) == NULL) | |
2132 | - { | |
2133 | - frame = new ID3_Frame(ID3FID_TITLE); | |
2134 | - if (frame) | |
2135 | - { | |
2136 | - frame->GetField(ID3FN_TEXT)->SetEncoding(ID3TE_UNICODE); | |
2137 | - frame->GetField(ID3FN_TEXT)->Set(SwapByteOrder(text)); | |
2138 | - frame->GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE); | |
2139 | - tag->AttachFrame(frame); | |
2140 | - } | |
2141 | - } | |
2142 | - } | |
2143 | - | |
2144 | - return frame; | |
2145 | - } | |
2146 | - | |
2147 | - size_t RemoveTitles(ID3_Tag *tag) | |
2148 | - { | |
2149 | - size_t num_removed = 0; | |
2150 | - ID3_Frame *frame = NULL; | |
2151 | - | |
2152 | - if (NULL == tag) | |
2153 | - { | |
2154 | - return num_removed; | |
2155 | - } | |
2156 | - | |
2157 | - while ((frame = tag->Find(ID3FID_TITLE)) != NULL) | |
2158 | - { | |
2159 | - frame = tag->RemoveFrame(frame); | |
2160 | - delete frame; | |
2161 | - num_removed++; | |
2162 | - } | |
2163 | - | |
2164 | - return num_removed; | |
2165 | - } | |
2166 | - | |
2167 | - //following routine courtesy of John George | |
2168 | - ID3_Frame* AddGenre(ID3_Tag* tag, const wchar_t *genre, bool replace) | |
2169 | - { | |
2170 | - ID3_Frame* frame = NULL; | |
2171 | - if (NULL != tag && NULL != genre && lstrlen(genre) > 0) | |
2172 | - { | |
2173 | - if (replace) | |
2174 | - { | |
2175 | - RemoveGenres(tag); | |
2176 | - } | |
2177 | - if (replace || NULL == tag->Find(ID3FID_CONTENTTYPE)) | |
2178 | - { | |
2179 | - frame = new ID3_Frame(ID3FID_CONTENTTYPE); | |
2180 | - if (NULL != frame) | |
2181 | - { | |
2182 | - frame->GetField(ID3FN_TEXT)->SetEncoding(ID3TE_UNICODE); | |
2183 | - frame->GetField(ID3FN_TEXT)->Set(SwapByteOrder(genre)); | |
2184 | - frame->GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE); | |
2185 | - tag->AttachFrame(frame); | |
2186 | - } | |
2187 | - } | |
2188 | - } | |
2189 | - | |
2190 | - return frame; | |
2191 | - } | |
2192 | - | |
2193 | - size_t RemoveGenres(ID3_Tag *tag) | |
2194 | - { | |
2195 | - size_t num_removed = 0; | |
2196 | - ID3_Frame *frame = NULL; | |
2197 | - | |
2198 | - if (NULL == tag) | |
2199 | - { | |
2200 | - return num_removed; | |
2201 | - } | |
2202 | - | |
2203 | - while ((frame = tag->Find(ID3FID_CONTENTTYPE)) != NULL) | |
2204 | - { | |
2205 | - frame = tag->RemoveFrame(frame); | |
2206 | - delete frame; | |
2207 | - num_removed++; | |
2208 | - } | |
2209 | - | |
2210 | - return num_removed; | |
2211 | - } | |
2212 | - | |
2213 | - const unicode_t *SwapByteOrder(const wchar_t *text) | |
2214 | - { | |
2215 | - static unicode_t resBuf[65536]; | |
2216 | - const wchar_t *pText; | |
2217 | - unicode_t *pBuf; | |
2218 | - | |
2219 | - for(pText = text, pBuf = resBuf; *pText != L'\0'; pText ++, pBuf ++) | |
2220 | - { | |
2221 | - wchar_t srcVal = *pText; | |
2222 | - //unicode_t dstVal = srcVal; | |
2223 | - unicode_t dstVal = (srcVal << 8) | (srcVal >> 8); | |
2224 | - *pBuf = dstVal; | |
2225 | - } | |
2226 | - | |
2227 | - *pBuf = L'\0'; | |
2228 | - | |
2229 | - return resBuf; | |
2230 | - } | |
2231 | -#endif | |
2232 | - | |
2233 | - protected: | |
2234 | - | |
2235 | - static LRESULT WINAPI hookWinampWindowProc(HWND wnd,UINT msg, WPARAM wp, LPARAM lp); | |
2236 | - static LRESULT WINAPI windowproc(HWND wnd,UINT msg, WPARAM wp, LPARAM lp); | |
2237 | - static std::pair<bool, LRESULT> WINAPI innerWinampWindowProc(HWND wnd,UINT msg, WPARAM wp, LPARAM lp); | |
2238 | - static std::pair<bool, LRESULT> WINAPI outerWinampWindowProc(HWND wnd,UINT msg, WPARAM wp, LPARAM lp); | |
2239 | - | |
2240 | - protected: | |
2241 | - | |
2242 | - static DummyAmp *m_pMe; | |
2243 | - | |
2244 | - bool m_bReady; | |
2245 | - | |
2246 | - HINSTANCE m_hInstGenMixi; | |
2247 | - winampGeneralPurposePlugin *m_pGenMixi; | |
2248 | - | |
2249 | - HWND m_hWinampWnd; | |
2250 | - bool m_isAnotherWinampWindowAvailable; | |
2251 | - | |
2252 | - static LONG_PTR m_pfnOldAnotherWinampProc; | |
2253 | - | |
2254 | - HANDLE m_hDirChangeNotify; | |
2255 | - | |
2256 | - PlayInfo m_playInfo; | |
2257 | - PlayInfo m_rawPlayInfo; | |
2258 | - | |
2259 | - TrackInfo m_trackInfo; | |
2260 | - int m_GETPLAYLISTFILE_time; | |
2261 | - | |
2262 | - tstring m_playlistTitle; | |
2263 | - string8 m_playlistTitle8; | |
2264 | - | |
2265 | - tstring m_winampTitle; | |
2266 | - tstring m_baseWinampTitle; | |
2267 | - | |
2268 | - tstring m_dummyPlayInfoMp3Path; | |
2269 | - bool m_isDummyPlayInfoMp3Available; | |
2270 | -}; | |
2271 | - | |
2272 | -DummyAmp *DummyAmp::m_pMe = NULL; | |
2273 | - | |
2274 | -LONG_PTR DummyAmp::m_pfnOldAnotherWinampProc = NULL; | |
2275 | - | |
2276 | -LRESULT CALLBACK DummyAmp::hookWinampWindowProc(HWND wnd,UINT msg, WPARAM wp, LPARAM lp) | |
2277 | -{ | |
2278 | - if(InSendMessage() || (msg != WM_WA_IPC)) | |
2279 | - { | |
2280 | - switch(msg) | |
2281 | - { | |
2282 | - case WM_CLOSE: | |
2283 | - DEBUG_DUMMYAMP_PROC(_T("DummyAmp::hookWinampWindowProc - WM_CLOSE %s"), | |
2284 | - InSendMessage() == TRUE ? _T("from other thread") : _T("")); | |
2285 | - | |
2286 | - DummyAmp::getInstance()->destroyWindow(); | |
2287 | - break; | |
2288 | - | |
2289 | - case WM_GETTEXT: | |
2290 | - { | |
2291 | - // message from same thread | |
2292 | - if((InSendMessage() == FALSE) && (DummyAmp::getInstance()->isAnotherWinampWindowAvailable() == true)) | |
2293 | - { | |
2294 | - LPCTSTR pWinampTitle = DummyAmp::getInstance()->getWinampTitle().c_str(); | |
2295 | - int nLen = ::lstrlen(pWinampTitle); | |
2296 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::hookWinampWindowProc - WM_GETTEXT / window title [%s]."), pWinampTitle); | |
2297 | - | |
2298 | - ::lstrcpyn(reinterpret_cast<LPTSTR>(lp), pWinampTitle, static_cast<int>(wp)); | |
2299 | - | |
2300 | - return (LRESULT)nLen; | |
2301 | - } | |
2302 | - } | |
2303 | - break; | |
2304 | - | |
2305 | - case WM_GETTEXTLENGTH: | |
2306 | - { | |
2307 | - // message from same thread | |
2308 | - if((InSendMessage() == FALSE) && (DummyAmp::getInstance()->isAnotherWinampWindowAvailable() == true)) | |
2309 | - { | |
2310 | - LPCTSTR pWinampTitle = DummyAmp::getInstance()->getWinampTitle().c_str(); | |
2311 | - int nLen = ::lstrlen(pWinampTitle); | |
2312 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::hookWinampWindowProc - WM_GETTEXTLENGTH / window title length %d."), nLen); | |
2313 | - | |
2314 | - return (LRESULT)nLen; | |
2315 | - } | |
2316 | - } | |
2317 | - break; | |
2318 | - | |
2319 | - case WM_SETTEXT: | |
2320 | - { | |
2321 | - // message from same thread | |
2322 | - if((InSendMessage() == FALSE) && (DummyAmp::getInstance()->isAnotherWinampWindowAvailable() == true)) | |
2323 | - { | |
2324 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::hookWinampWindowProc - WM_SETTEXT / window title [%s]."), reinterpret_cast<LPCTSTR>(lp)); | |
2325 | - } | |
2326 | - } | |
2327 | - break; | |
2328 | - | |
2329 | - default: | |
2330 | - | |
2331 | - if(InSendMessage()) | |
2332 | - { | |
2333 | - if(msg == WM_WA_IPC) { | |
2334 | - if(cfg_enable_ext_ipc_proc == 1) | |
2335 | - { | |
2336 | - std::pair<bool, LRESULT> res = outerWinampWindowProc(wnd, msg, wp, lp); | |
2337 | - if(res.first == true) { | |
2338 | - return res.second; | |
2339 | - } | |
2340 | - } | |
2341 | - | |
2342 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::hookWinampWindowProc - WM_WA_IPC from other thread / W:%08x, L:%08x"), wp, lp); | |
2343 | - | |
2344 | - } | |
2345 | - else | |
2346 | - { | |
2347 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::hookWinampWindowProc - ") | |
2348 | - _T("message from other thread / MSG:%04x, W:%08x, L:%08x"), msg, wp, lp); | |
2349 | - } | |
2350 | - } | |
2351 | - | |
2352 | - break; | |
2353 | - } | |
2354 | - | |
2355 | - return CallWindowProc(LONG_PTR_TO_WNDPROC(m_pfnOldAnotherWinampProc), wnd, msg, wp, lp); | |
2356 | - } | |
2357 | - else | |
2358 | - { | |
2359 | - return CallWindowProc(windowproc, wnd, msg, wp, lp); | |
2360 | - } | |
2361 | -} | |
2362 | - | |
2363 | -LRESULT CALLBACK DummyAmp::windowproc(HWND wnd,UINT msg, WPARAM wp, LPARAM lp) | |
2364 | -{ | |
2365 | - switch(msg) | |
2366 | - { | |
2367 | - case WM_CLOSE: | |
2368 | - DEBUG_DUMMYAMP_PROC(_T("DummyAmp::windowproc - WM_CLOSE")); | |
2369 | - DummyAmp::getInstance()->destroyWindow(); | |
2370 | - return 0; | |
2371 | - | |
2372 | - case WM_WA_IPC: | |
2373 | - // message from same thread | |
2374 | - if(InSendMessage() == FALSE) | |
2375 | - { | |
2376 | - std::pair<bool, LRESULT> res = innerWinampWindowProc(wnd, msg, wp, lp); | |
2377 | - if(res.first == true) { | |
2378 | - return res.second; | |
2379 | - } | |
2380 | - } | |
2381 | - // message from other thread | |
2382 | - else | |
2383 | - { | |
2384 | - std::pair<bool, LRESULT> res = outerWinampWindowProc(wnd, msg, wp, lp); | |
2385 | - if(res.first == true) { | |
2386 | - return res.second; | |
2387 | - } | |
2388 | - } | |
2389 | - break; | |
2390 | - default: | |
2391 | - if(InSendMessage()) { | |
2392 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::windowproc - Unknown MSG from other thread / MSG:%04x, W:%08x, L:%08x"), msg, wp, lp); | |
2393 | - } | |
2394 | - break; | |
2395 | - } | |
2396 | - | |
2397 | - return uDefWindowProc(wnd,msg,wp,lp); | |
2398 | -} | |
2399 | - | |
2400 | -std::pair<bool, LRESULT> WINAPI DummyAmp::innerWinampWindowProc(HWND wnd,UINT msg, WPARAM wp, LPARAM lp) | |
2401 | -{ | |
2402 | - switch(msg) | |
2403 | - { | |
2404 | - case WM_WA_IPC: | |
2405 | - { | |
2406 | - PlayInfo::EPlayStatus playStatus = DummyAmp::getInstance()->getPlayInfo().getPlayStatus(); | |
2407 | - int playPosition = DummyAmp::getInstance()->getPlayInfo().getPlayPosition(); | |
2408 | - int playLength = DummyAmp::getInstance()->getPlayInfo().getPlayLength(); | |
2409 | - int playCount = DummyAmp::getInstance()->getPlayInfo().getPlayCount(); | |
2410 | - int getPlayListFileTime = DummyAmp::getInstance()->getGetPlayListFileTime(); | |
2411 | - bool isPlayInfoMp3Available = DummyAmp::getInstance()->getPlayInfo().isPlayInfoMp3Available(); | |
2412 | - const string8 &playInfoMp3Path8 = DummyAmp::getInstance()->getPlayInfo().getPlayInfoMp3Path8(); | |
2413 | - | |
2414 | - switch(lp) | |
2415 | - { | |
2416 | - case IPC_ISPLAYING: | |
2417 | - if(cfg_use_plugin == 1) | |
2418 | - { | |
2419 | - HANDLE hDirChangeNotify = DummyAmp::getInstance()->getDirChangeNotifyHandle(); | |
2420 | - | |
2421 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::innerWinampWindowProc - IPC_ISPLAYING / status %d"), playStatus); | |
2422 | - | |
2423 | - if(playStatus != PlayInfo::PLAY_START) | |
2424 | - { | |
2425 | - if(DummyAmp::getInstance()->getPlayInfo().isResentMode()) { | |
2426 | - DummyAmp::getInstance()->getPlayInfo().clearResentMode(); | |
2427 | - } | |
2428 | - | |
2429 | - if(hDirChangeNotify != INVALID_HANDLE_VALUE) | |
2430 | - { | |
2431 | - LOG_WARN(_T("DummyAmp::innerWinampWindowProc - ディレクトリ変更通知イベントのハンドルが閉じられていません")); | |
2432 | - LOG_WARN(_T("DummyAmp::innerWinampWindowProc - 安全のため、ここで閉じます")); | |
2433 | - DummyAmp::getInstance()->closeDirChangeNotifyHandle(); | |
2434 | - } | |
2435 | - } | |
2436 | - else | |
2437 | - { | |
2438 | - if(hDirChangeNotify != INVALID_HANDLE_VALUE) | |
2439 | - { | |
2440 | - DWORD dwRes = ::WaitForMultipleObjects(1, &hDirChangeNotify, FALSE, 0); | |
2441 | - | |
2442 | - if(dwRes == WAIT_OBJECT_0) | |
2443 | - { | |
2444 | - LOG_INFO(_T("mixi station successfully updated.")); | |
2445 | - DummyAmp::getInstance()->closeDirChangeNotifyHandle(); | |
2446 | - DummyAmp::getInstance()->getPlayInfo().setPlayStatusStop(); | |
2447 | - } | |
2448 | - else if(playPosition >= getPlayListFileTime + RESENT_INTERVAL) | |
2449 | - { | |
2450 | - DummyAmp::getInstance()->closeDirChangeNotifyHandle(); | |
2451 | - LOG_WARN(_T("DummyAmp::innerWinampWindowProc - mixi station ディレクトリの変更通知イベントが待ち時間内に発生しませんでした")); | |
2452 | -#if !defined(DISABLE_KICK_GEN_MIXI_LOOP) | |
2453 | - LOG_WARN(_T("DummyAmp::innerWinampWindowProc - gen_mixi_for_winamp に曲情報取得要求を再送させます")); | |
2454 | - DummyAmp::getInstance()->getPlayInfo().setResentMode(); | |
2455 | - DummyAmp::getInstance()->updateDummyAmpTitle(); | |
2456 | -#else | |
2457 | - LOG_WARN(_T("DummyAmp::innerWinampWindowProc - 曲情報は破棄されました")); | |
2458 | -#endif | |
2459 | - } | |
2460 | - } | |
2461 | - } | |
2462 | - return std::make_pair(true, playStatus); | |
2463 | - } | |
2464 | - return std::make_pair(true, PlayInfo::PLAY_STOP); | |
2465 | - | |
2466 | - case IPC_GETOUTPUTTIME: | |
2467 | - if(cfg_use_plugin == 1) | |
2468 | - { | |
2469 | - if(playStatus == PlayInfo::PLAY_START) | |
2470 | - { | |
2471 | - if(wp == IPC_GETOUTPUTTIME_PositionMSec) | |
2472 | - { | |
2473 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::innerWinampWindowProc - IPC_GETOUTPUTTIME / position %d"), playPosition / 1000); | |
2474 | - | |
2475 | - return std::make_pair(true, playPosition); | |
2476 | - } | |
2477 | - else if(wp == IPC_GETOUTPUTTIME_TotalSec) | |
2478 | - { | |
2479 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::innerWinampWindowProc - IPC_GETOUTPUTTIME / length %d"), playLength); | |
2480 | - return std::make_pair(true, playLength); | |
2481 | - } | |
2482 | - } | |
2483 | - } | |
2484 | - return std::make_pair(true, -1); | |
2485 | - | |
2486 | - case IPC_GETLISTPOS: | |
2487 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::innerWinampWindowProc - IPC_GETLISTPOS / index %d returned."), playCount); | |
2488 | - return std::make_pair(true, playCount); | |
2489 | - | |
2490 | - case IPC_GETPLAYLISTFILE: | |
2491 | - if(cfg_use_plugin == 1) | |
2492 | - { | |
2493 | - if(isPlayInfoMp3Available == true) | |
2494 | - { | |
2495 | - DEBUG_DUMMYAMP_PROC8( | |
2496 | - "DummyAmp::innerWinampWindowProc - IPC_GETPLAYLISTFILE / #%d - path [%s] returned.", | |
2497 | - playCount, (LPCSTR)playInfoMp3Path8); | |
2498 | - | |
2499 | - DummyAmp::getInstance()->setGetPlayListFileTime(playPosition); | |
2500 | - | |
2501 | - tstring mixiAppDataPath = PathInfo::getMixiStationAppPath(); | |
2502 | - | |
2503 | - DummyAmp::getInstance()->setDirChangeNotifyHandle( | |
2504 | - ::FindFirstChangeNotification(mixiAppDataPath.c_str(), FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE) | |
2505 | - ); | |
2506 | - | |
2507 | - return std::make_pair(true, (LRESULT)(LPCSTR)playInfoMp3Path8); | |
2508 | - } | |
2509 | - else | |
2510 | - { | |
2511 | - if(cfg_disable_dummy_mp3 == 1) | |
2512 | - { | |
2513 | - DEBUG_DUMMYAMP_PROC(_T("DummyAm::innerWinampWindowProcp - IPC_GETPLAYLISTFILE / NULL (audio file codec type not supported.)")); | |
2514 | - } | |
2515 | - else | |
2516 | - { | |
2517 | - LOG_WARN(_T("DummyAmp::innerWinampWindowProc - IPC_GETPLAYLISTFILE / NULL (dummy mp3 file not enabled.)")); | |
2518 | - } | |
2519 | - } | |
2520 | - } | |
2521 | - return std::make_pair(true, NULL); | |
2522 | - | |
2523 | - case IPC_INTERNAL_REFRESHLISTINFO: // 0x4000 | |
2524 | - { | |
2525 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::innerWinampWindowProc - IPC_INTERNAL_REFRESHLISTINFO / refresh internal playlist informations.")); | |
2526 | - | |
2527 | - // make playlist info formats array | |
2528 | - Strings plNumKeys; | |
2529 | - | |
2530 | - plNumKeys.push_back(FORMAT_LISTINDEX); | |
2531 | - | |
2532 | - // set current track informations | |
2533 | - DummyAmp::getInstance()->getMutableTrackInfo().setPlaylistNumbers(plNumKeys); | |
2534 | - | |
2535 | - // refresh dummyamp title | |
2536 | - DummyAmp::getInstance()->refreshTitle(); | |
2537 | - | |
2538 | - return std::make_pair(true, 0); | |
2539 | - } | |
2540 | - | |
2541 | - case IPC_INTERNAL_REFRESHDYNINFO: // 0x4001 | |
2542 | - { | |
2543 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::innerWinampWindowProc - IPC_INTERNAL_REFRESHDYNINFO / refresh internal dynamic informations.")); | |
2544 | - | |
2545 | - // make dynamic info formats array | |
2546 | - Strings dynStrKeys; | |
2547 | - | |
2548 | - dynStrKeys.push_back(FORMAT_ARTIST); | |
2549 | - dynStrKeys.push_back(FORMAT_TRACKTITLE); | |
2550 | - dynStrKeys.push_back(FORMAT_ALBUMTITLE); | |
2551 | - dynStrKeys.push_back(FORMAT_GENRE); | |
2552 | - | |
2553 | - // set current track informations | |
2554 | - DummyAmp::getInstance()->getMutableTrackInfo().removeStrings(dynStrKeys); | |
2555 | - DummyAmp::getInstance()->getMutableTrackInfo().setDynamicStrings(dynStrKeys); | |
2556 | - | |
2557 | - // refresh dummyamp title | |
2558 | - DummyAmp::getInstance()->refreshTitle(); | |
2559 | - | |
2560 | - // when explicitly tagged file only mode and artist or track name not found, | |
2561 | - // then skip sending track informations | |
2562 | - string8 title_utf8 = DummyAmp::getInstance()->getTrackInfo().getString(FORMAT_TRACKTITLE, true).c_str(); | |
2563 | - string8 artist_utf8 = DummyAmp::getInstance()->getTrackInfo().getString(FORMAT_ARTIST, true).c_str(); | |
2564 | - string8 album_utf8 = DummyAmp::getInstance()->getTrackInfo().getString(FORMAT_ALBUMTITLE).c_str(); | |
2565 | - string8 genre_utf8 = DummyAmp::getInstance()->getTrackInfo().getString(FORMAT_GENRE).c_str(); | |
2566 | - | |
2567 | - if( (cfg_explicitly_tagged_file_only == 1) && (!lstrcmpA(title_utf8, "?") || !lstrcmpA(artist_utf8, "?")) ) | |
2568 | - { | |
2569 | - DEBUG_DUMMYAMP_PROC(_T("DummyAmp::innerWinampWindowProc - IPC_INTERNAL_REFRESHDYNINFO / SKIP this track. (artist or title not found)")); | |
2570 | - } | |
2571 | - else | |
2572 | - { | |
2573 | - if(!lstrcmpA(title_utf8, "?")) | |
2574 | - { | |
2575 | - DummyAmp::getInstance()->getMutableTrackInfo().removeString(FORMAT_TRACKTITLE); | |
2576 | - DummyAmp::getInstance()->getMutableTrackInfo().putString(FORMAT_TRACKTITLE, (LPCSTR)cfg_no_title_name); | |
2577 | - } | |
2578 | - | |
2579 | - if(!lstrcmpA(artist_utf8, "?")) | |
2580 | - { | |
2581 | - DummyAmp::getInstance()->getMutableTrackInfo().removeString(FORMAT_ARTIST); | |
2582 | - DummyAmp::getInstance()->getMutableTrackInfo().putString(FORMAT_ARTIST, (LPCSTR)cfg_no_artist_name); | |
2583 | - } | |
2584 | - | |
2585 | - if(!lstrcmpA(album_utf8, "?")) | |
2586 | - { | |
2587 | - DummyAmp::getInstance()->getMutableTrackInfo().removeString(FORMAT_ALBUMTITLE); | |
2588 | - DummyAmp::getInstance()->getMutableTrackInfo().putString(FORMAT_ALBUMTITLE,(LPCSTR) cfg_no_album_name); | |
2589 | - } | |
2590 | - | |
2591 | - if(!lstrcmpA(genre_utf8, "?")) | |
2592 | - { | |
2593 | - DummyAmp::getInstance()->getMutableTrackInfo().removeString(FORMAT_GENRE); | |
2594 | - DummyAmp::getInstance()->getMutableTrackInfo().putString(FORMAT_GENRE, (LPCSTR)cfg_no_genre_name); | |
2595 | - } | |
2596 | - | |
2597 | - // refresh dummyamp info | |
2598 | - DummyAmp::getInstance()->refreshAmpInfo(); | |
2599 | - } | |
2600 | - | |
2601 | - return std::make_pair(true, 0); | |
2602 | - } | |
2603 | - | |
2604 | - default: | |
2605 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::innerWinampWindowProc - WM_WA_IPC (Unknown IPC command) / W:%08x, L:%08x"), wp, lp); | |
2606 | - break; | |
2607 | - } | |
2608 | - | |
2609 | - } | |
2610 | - break; | |
2611 | - } | |
2612 | - | |
2613 | - return std::make_pair(false, 0); | |
2614 | -} | |
2615 | - | |
2616 | -std::pair<bool, LRESULT> WINAPI DummyAmp::outerWinampWindowProc(HWND wnd,UINT msg, WPARAM wp, LPARAM lp) | |
2617 | -{ | |
2618 | - switch(msg) | |
2619 | - { | |
2620 | - case WM_WA_IPC: | |
2621 | - { | |
2622 | - PlayInfo::EPlayStatus rawPlayStatus = DummyAmp::getInstance()->getRawPlayInfo().getPlayStatus(); | |
2623 | - int rawPlayPosition = DummyAmp::getInstance()->getRawPlayInfo().getPlayPosition(); | |
2624 | - int rawPlayLength = DummyAmp::getInstance()->getRawPlayInfo().getPlayLength(); | |
2625 | - int rawPlayCount = DummyAmp::getInstance()->getPlayInfo().getPlayCount(); | |
2626 | - const string8 &rawPlayInfoMp3Path8 = DummyAmp::getInstance()->getRawPlayInfo().getPlayInfoMp3Path8(); | |
2627 | - const tstring &playlistTitle = DummyAmp::getInstance()->getPlaylistTitle(); | |
2628 | - const string8 &playlistTitle8 = DummyAmp::getInstance()->getPlaylistTitle8(); | |
2629 | - | |
2630 | - switch(lp) | |
2631 | - { | |
2632 | - case IPC_ISPLAYING: | |
2633 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::outerWinampWindowProc - IPC_ISPLAYING / status %d"), rawPlayStatus); | |
2634 | - return std::make_pair(true, rawPlayStatus); | |
2635 | - | |
2636 | - case IPC_GETOUTPUTTIME: | |
2637 | - | |
2638 | - if(rawPlayStatus != PlayInfo::PLAY_START) | |
2639 | - { | |
2640 | - rawPlayPosition = -1; | |
2641 | - rawPlayLength = -1; | |
2642 | - } | |
2643 | - else if(true) | |
2644 | - { | |
2645 | -#if IS_FB2K_VER08 | |
2646 | - rawPlayPosition = static_cast<int>(play_control::get()->get_playback_time() * 1000.0); | |
2647 | -#else IS_FB2K_VER09 | |
2648 | - rawPlayPosition = static_cast<int>(static_api_ptr_t<playback_control>()->playback_get_position() * 1000.0); | |
2649 | -#endif | |
2650 | - } | |
2651 | - | |
2652 | - if(wp == IPC_GETOUTPUTTIME_PositionMSec) | |
2653 | - { | |
2654 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::outerWinampWindowProc - IPC_GETOUTPUTTIME / position %.3f"), rawPlayPosition / 1000.0); | |
2655 | - return std::make_pair(true, rawPlayPosition); | |
2656 | - } | |
2657 | - else if(wp == IPC_GETOUTPUTTIME_TotalSec) | |
2658 | - { | |
2659 | - TRACE_DUMMYAMP_PROC(_T("DummyAm::outerWinampWindowProcp - IPC_GETOUTPUTTIME / length %d"), rawPlayLength); | |
2660 | - return std::make_pair(true, rawPlayLength); | |
2661 | - } | |
2662 | - | |
2663 | - return std::make_pair(true, -1); | |
2664 | - | |
2665 | - case IPC_GETLISTPOS: | |
2666 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::outerWinampWindowProc - IPC_GETLISTPOS / index %d returned."), rawPlayCount); | |
2667 | - return std::make_pair(true, rawPlayCount); | |
2668 | - | |
2669 | - case IPC_GETPLAYLISTFILE: | |
2670 | - TRACE_DUMMYAMP_PROC8( | |
2671 | - "DummyAmp::outerWinampWindowProc - IPC_GETPLAYLISTFILE / path [%s] returned.", (LPCSTR)rawPlayInfoMp3Path8); | |
2672 | - return std::make_pair(true, (LRESULT)(LPCSTR)rawPlayInfoMp3Path8); | |
2673 | - | |
2674 | - case IPC_GETPLAYLISTTITLE: | |
2675 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::outerWinampWindowProc - IPC_GETPLAYLISTTITLE") | |
2676 | - _T(" / title [%s] returned."), (LPCTSTR)playlistTitle.c_str()); | |
2677 | - return std::make_pair(true, (LRESULT)(LPCSTR)playlistTitle8); | |
2678 | - | |
2679 | - case IPC_JUMPTOTIME: | |
2680 | - if(rawPlayStatus == PlayInfo::PLAY_START) | |
2681 | - { | |
2682 | - double jumpPos = wp / 1000.0; | |
2683 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::outerWinampWindowProc - IPC_JUMPTOTIME") | |
2684 | - _T(" / jump to %.3f[sec.]"), jumpPos); | |
2685 | - | |
2686 | - if(jumpPos > rawPlayLength) | |
2687 | - { | |
2688 | - // eof | |
2689 | - return std::make_pair(true, 1); | |
2690 | - } | |
2691 | - else | |
2692 | - { | |
2693 | -#if IS_FB2K_VER08 | |
2694 | - play_control::get()->playback_seek(jumpPos); | |
2695 | -#else IS_FB2K_VER09 | |
2696 | - static_api_ptr_t<playback_control>()->playback_seek(jumpPos); | |
2697 | -#endif | |
2698 | - return std::make_pair(true, 0); | |
2699 | - } | |
2700 | - | |
2701 | - } | |
2702 | - return std::make_pair(true, -1); | |
2703 | - | |
2704 | - default: | |
2705 | - TRACE_DUMMYAMP_PROC(_T("DummyAmp::outerWinampWindowProc - WM_WA_IPC (Unknown IPC command) / W:%08x, L:%08x"), wp, lp); | |
2706 | - break; | |
2707 | - } | |
2708 | - } | |
2709 | - break; | |
2710 | - } | |
2711 | - | |
2712 | - return std::make_pair(false, 0); | |
2713 | -} | |
2714 | - | |
2715 | -#if defined(ENABLE_MSN) | |
2716 | -class MSNSender | |
2717 | -{ | |
2718 | - public: | |
2719 | - | |
2720 | - static void SendTrackInfo(const TRACK_INFO_UTF8 &info) | |
2721 | - { | |
2722 | - string8 msg; | |
2723 | - msg += "\\0Music\\01\\0{0} - {1} - {2} - {3}\\0"; | |
2724 | - msg += info.m_title; | |
2725 | - msg += "\\0"; | |
2726 | - msg += info.m_artist; | |
2727 | - msg += "\\0"; | |
2728 | - msg += info.m_album; | |
2729 | - msg += "\\0"; | |
2730 | - msg += info.m_genre; | |
2731 | - msg += "\\0"; | |
2732 | - | |
2733 | - console::info(msg); | |
2734 | - | |
2735 | - string_wide_from_utf8 tmp(msg); | |
2736 | - SendMessage(tmp); | |
2737 | - } | |
2738 | - | |
2739 | - static void SendMessage(LPCWSTR buf) | |
2740 | - { | |
2741 | - COPYDATASTRUCT copydata; | |
2742 | - int nSendBufLen = (::lstrlenW(buf)*2)+2; | |
2743 | - | |
2744 | - copydata.dwData = 0x0547; | |
2745 | - copydata.lpData = (void*)buf; | |
2746 | - copydata.cbData = nSendBufLen; | |
2747 | - | |
2748 | - HWND hMsnUi = NULL; | |
2749 | - hMsnUi = FindWindowEx(NULL, hMsnUi, _T("MsnMsgrUIManager"), _T("MSN Messenger式再生通知を受信する窓")); | |
2750 | - if ( hMsnUi == NULL ) | |
2751 | - { | |
2752 | - ERROR(_T("MSNSender::SendMessage - M2M not found.")); | |
2753 | - return ; | |
2754 | - } | |
2755 | - | |
2756 | - ::SendMessage(hMsnUi, WM_COPYDATA, (WPARAM)NULL, (LPARAM)©data); | |
2757 | - LOG_INFO(_T("MSNSender::SendMessage - send track informations to M2M.")); | |
2758 | - } | |
2759 | -}; | |
2760 | -#endif | |
2761 | - | |
2762 | -#if IS_FB2K_VER08 | |
2763 | -class play_callback_mixi : public play_callback | |
2764 | -#elif IS_FB2K_VER09 | |
2765 | -class play_callback_mixi : public play_callback_static | |
2766 | -#endif | |
2767 | -{ | |
2768 | -#if IS_FB2K_VER09 | |
2769 | - virtual unsigned get_flags() { | |
2770 | - return flag_on_playback_all; | |
2771 | - } | |
2772 | -#endif | |
2773 | - | |
2774 | -#if IS_FB2K_VER08 | |
2775 | - virtual void on_playback_starting() | |
2776 | -#elif IS_FB2K_VER09 | |
2777 | - virtual void on_playback_starting(play_control::t_track_command command, bool paused) | |
2778 | -#endif | |
2779 | - { | |
2780 | - TRACE_CALLBACK(_T("play_callback_mixi::on_playback_starting - called.")); | |
2781 | - | |
2782 | - // create my dummyamp window | |
2783 | - DummyAmp::getInstance()->createWindow(); | |
2784 | - } | |
2785 | - | |
2786 | -#if IS_FB2K_VER08 | |
2787 | - virtual void on_playback_new_track(metadb_handle * track) | |
2788 | -#elif IS_FB2K_VER09 | |
2789 | - virtual void on_playback_new_track(metadb_handle_ptr track) | |
2790 | -#endif | |
2791 | - { | |
2792 | - TRACE_CALLBACK(_T("play_callback_mixi::on_playback_new_track - called.")); | |
2793 | - | |
2794 | - if(DummyAmp::getInstance()->isReady() == false) | |
2795 | - { | |
2796 | - LOG_ERROR(_T("play_callback_mixi::on_playback_new_track - mixi station への送信機能はエラーにより無効化されています")); | |
2797 | - LOG_ERROR(_T("play_callback_mixi::on_playback_new_track - エラーの原因を取り除いた上で、foobar2000 を再起動してください")); | |
2798 | - return; | |
2799 | - } | |
2800 | - | |
2801 | -#if IS_FB2K_VER08 | |
2802 | - bool isTrackInLibrary = track->handle_is_permcached() == 1; | |
2803 | -#elif IS_FB2K_VER09 | |
2804 | - bool isTrackInLibrary = static_api_ptr_t<library_manager>()->is_item_in_library(track); | |
2805 | -#endif | |
2806 | - if(cfg_media_library_registered_file_only == 1) | |
2807 | - { | |
2808 | - if(isTrackInLibrary) | |
2809 | - { | |
2810 | - DEBUG_CALLBACK(_T("play_callback_mixi::on_playback_new_track - new track found on media library.")); | |
2811 | - } | |
2812 | - else | |
2813 | - { | |
2814 | - DEBUG_CALLBACK(_T("play_callback_mixi::on_playback_new_track - new track NOT IN media library.")); | |
2815 | - } | |
2816 | - } | |
2817 | - | |
2818 | - // get currently playbacked track informations | |
2819 | - string8 winamp_title_utf8; | |
2820 | - string8 playlist_title_utf8; | |
2821 | - | |
2822 | - // make currently playbacked track information keys | |
2823 | - Strings strKeys; | |
2824 | - | |
2825 | - strKeys.push_back(FORMAT_FILEPATH); | |
2826 | - strKeys.push_back(FORMAT_FILEPATHRAW); | |
2827 | - strKeys.push_back(FORMAT_ARTIST); | |
2828 | - strKeys.push_back(FORMAT_TRACKTITLE); | |
2829 | - strKeys.push_back(FORMAT_ALBUMTITLE); | |
2830 | - strKeys.push_back(FORMAT_GENRE); | |
2831 | - strKeys.push_back(FORMAT_CODEC); | |
2832 | - | |
2833 | - // set current track informations | |
2834 | - TrackInfo &trackInfo(DummyAmp::getInstance()->getMutableTrackInfo()); | |
2835 | - trackInfo.clear(); | |
2836 | - trackInfo.setStrings(strKeys, track); | |
2837 | - | |
2838 | - // set trackinfo to dummyAmp | |
2839 | - //DummyAmp::getInstance()->setTrackInfo(trackInfo); | |
2840 | - | |
2841 | - // set dynamic flag | |
2842 | - setDynamic(trackInfo.getString(FORMAT_FILEPATHRAW)); | |
2843 | - | |
2844 | - if(isDynamic()) | |
2845 | - { | |
2846 | - setFirstDynamicCallback(true); | |
2847 | - | |
2848 | - // set song total length | |
2849 | - m_song_total_sec = pfc_string_to_float(cfg_send_interval3) / pfc_string_to_float(cfg_send_interval2) * 100.0; | |
2850 | - } | |
2851 | - else | |
2852 | - { | |
2853 | -#if defined(CONTROL_SEND_TIMING) | |
2854 | - // reset send timing | |
2855 | - resetSendTiming(); | |
2856 | -#endif | |
2857 | - | |
2858 | -#if IS_FB2K_VER08 | |
2859 | - // get song total length | |
2860 | - m_song_total_sec = track->handle_get_length(); | |
2861 | - | |
2862 | - // get formatted dummyamp title | |
2863 | - track->handle_format_title(winamp_title_utf8, cfg_dummyamp_title_format, 0); | |
2864 | - | |
2865 | - // get formatted playlist title | |
2866 | - track->handle_format_title(playlist_title_utf8, cfg_dummyamp_playlist_format, 0); | |
2867 | - | |
2868 | -#elif IS_FB2K_VER09 | |
2869 | - // get song total length | |
2870 | - m_song_total_sec = track->get_length(); | |
2871 | - | |
2872 | - service_ptr_t<titleformat_object> titleformat; | |
2873 | - | |
2874 | - // get formatted dummyamp title | |
2875 | - static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, cfg_dummyamp_title_format); | |
2876 | - track->format_title(NULL, winamp_title_utf8, titleformat, 0); | |
2877 | - | |
2878 | - // get formatted playlist title | |
2879 | - static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, cfg_dummyamp_playlist_format); | |
2880 | - track->format_title(NULL, playlist_title_utf8, titleformat, 0); | |
2881 | - | |
2882 | -#endif | |
2883 | - string_os_from_utf8 winamp_title(winamp_title_utf8); | |
2884 | - string_os_from_utf8 playlist_title(playlist_title_utf8); | |
2885 | - | |
2886 | - // set base winamp title to dummyamp | |
2887 | - DummyAmp::getInstance()->setBaseWinampTitle(winamp_title); | |
2888 | - | |
2889 | - // set winamp playlist current item title to dummyamp | |
2890 | - DummyAmp::getInstance()->setPlaylistTitle(playlist_title); | |
2891 | - | |
2892 | - // clear raw playinfo on dummyamp (no resent mode) | |
2893 | - DummyAmp::getInstance()->getRawPlayInfo().clearPlayInfo(false); | |
2894 | - | |
2895 | - // set playinfo raw mp3 file path to dummyAmp | |
2896 | - DummyAmp::getInstance()->getRawPlayInfo().setPlayInfoMp3Path(trackInfo.getString(FORMAT_FILEPATH).c_str()); | |
2897 | - | |
2898 | - // set dummyamp raw status PLAY_START | |
2899 | - DummyAmp::getInstance()->getRawPlayInfo().setPlayStatusStart(); | |
2900 | - | |
2901 | - // set raw song total length | |
2902 | - DummyAmp::getInstance()->getRawPlayInfo().setPlayLength(static_cast<int>(m_song_total_sec)); | |
2903 | - | |
2904 | - // increment play counter | |
2905 | - DummyAmp::getInstance()->getRawPlayInfo().incrementPlayCount(); | |
2906 | - | |
2907 | - // clear playinfo on dummyamp | |
2908 | - DummyAmp::getInstance()->getPlayInfo().clearPlayInfo(); | |
2909 | - | |
2910 | - // set song total length | |
2911 | - DummyAmp::getInstance()->getPlayInfo().setPlayLength(static_cast<int>(m_song_total_sec)); | |
2912 | - | |
2913 | - // increment play counter on dummyamp | |
2914 | - DummyAmp::getInstance()->getPlayInfo().incrementPlayCount(); | |
2915 | - } | |
2916 | - | |
2917 | - if(isDynamic()) | |
2918 | - { | |
2919 | - // post IPC_INTERNAL_REFRESHLISTINFO | |
2920 | - ::PostMessage(DummyAmp::getInstance()->getWnd(), WM_WA_IPC, 0, IPC_INTERNAL_REFRESHLISTINFO); | |
2921 | - DEBUG_CALLBACK(_T("play_callback_mixi::on_playback_new_track - IPC_INTERNAL_REFRESHLISTINFO posted.")); | |
2922 | - } | |
2923 | - else | |
2924 | - { | |
2925 | - bool bSkip = false; | |
2926 | - | |
2927 | - string8 title_utf8 = trackInfo.getString(FORMAT_TRACKTITLE).c_str(); | |
2928 | - string8 artist_utf8 = trackInfo.getString(FORMAT_ARTIST).c_str(); | |
2929 | - string8 album_utf8 = trackInfo.getString(FORMAT_ALBUMTITLE).c_str(); | |
2930 | - string8 genre_utf8 = trackInfo.getString(FORMAT_GENRE).c_str(); | |
2931 | - | |
2932 | - // when media library only mode and track not found on media library, | |
2933 | - // then skip sending track informations | |
2934 | - if((cfg_media_library_registered_file_only == 1) && (isTrackInLibrary == false)) | |
2935 | - { | |
2936 | - DEBUG_CALLBACK(_T("play_callback_mixi::on_playback_new_track - SKIP this track. (not in media library)")); | |
2937 | - bSkip = true; | |
2938 | - } | |
2939 | - | |
2940 | - // when explicitly tagged file only mode and artist or track name not found, | |
2941 | - // then skip sending track informations | |
2942 | - if( (cfg_explicitly_tagged_file_only == 1) && (!lstrcmpA(title_utf8, "?") || !lstrcmpA(artist_utf8, "?")) ) | |
2943 | - { | |
2944 | - DEBUG_CALLBACK(_T("play_callback_mixi::on_playback_new_track - SKIP this track. (artist or title not found)")); | |
2945 | - bSkip = true; | |
2946 | - } | |
2947 | - | |
2948 | - if(!lstrcmpA(title_utf8, "?")) | |
2949 | - { | |
2950 | - trackInfo.removeString(FORMAT_TRACKTITLE); | |
2951 | - trackInfo.putString(FORMAT_TRACKTITLE, (LPCSTR)cfg_no_title_name); | |
2952 | - } | |
2953 | - | |
2954 | - if(!lstrcmpA(artist_utf8, "?")) | |
2955 | - { | |
2956 | - trackInfo.removeString(FORMAT_ARTIST); | |
2957 | - trackInfo.putString(FORMAT_ARTIST, (LPCSTR)cfg_no_artist_name); | |
2958 | - } | |
2959 | - | |
2960 | - if(!lstrcmpA(album_utf8, "?")) | |
2961 | - { | |
2962 | - trackInfo.removeString(FORMAT_ALBUMTITLE); | |
2963 | - trackInfo.putString(FORMAT_ALBUMTITLE, (LPCSTR)cfg_no_album_name); | |
2964 | - } | |
2965 | - | |
2966 | - if(!lstrcmpA(genre_utf8, "?")) | |
2967 | - { | |
2968 | - trackInfo.removeString(FORMAT_GENRE); | |
2969 | - trackInfo.putString(FORMAT_GENRE, (LPCSTR)cfg_no_genre_name); | |
2970 | - } | |
2971 | - | |
2972 | - // refresh dummy amp informations when skip flag not set | |
2973 | - if(!bSkip) { | |
2974 | - DummyAmp::getInstance()->refreshAmpInfo(); | |
2975 | - | |
2976 | - // post IPC_INTERNAL_REFRESHLISTINFO | |
2977 | - ::PostMessage(DummyAmp::getInstance()->getWnd(), WM_WA_IPC, 0, IPC_INTERNAL_REFRESHLISTINFO); | |
2978 | - DEBUG_CALLBACK(_T("play_callback_mixi::on_playback_new_track - IPC_INTERNAL_REFRESHLISTINFO posted.")); | |
2979 | - } | |
2980 | - } | |
2981 | - } | |
2982 | - | |
2983 | -#if IS_FB2K_VER08 | |
2984 | - virtual void on_playback_stop(play_control::stop_reason reason) | |
2985 | -#elif IS_FB2K_VER09 | |
2986 | - virtual void on_playback_stop(play_control::t_stop_reason reason) | |
2987 | -#endif | |
2988 | - { | |
2989 | - TRACE_CALLBACK(_T("play_callback_mixi::on_playback_stop - called.")); | |
2990 | - | |
2991 | - // set dummyamp status PLAY_STOP | |
2992 | - DummyAmp::getInstance()->getPlayInfo().setPlayStatusStop(); | |
2993 | - | |
2994 | - // set dummyamp raw status PLAY_STOP | |
2995 | - DummyAmp::getInstance()->getRawPlayInfo().setPlayStatusStop(); | |
2996 | - | |
2997 | - // clear dummyamp title | |
2998 | - DummyAmp::getInstance()->clearDummyAmpTitle(); | |
2999 | - } | |
3000 | - | |
3001 | - virtual void on_playback_seek(double time) // time is second. | |
3002 | - { | |
3003 | - TRACE_CALLBACK(_T("play_callback_mixi::on_playback_seek - called.")); | |
3004 | - | |
3005 | -#if !defined(CONTROL_SEND_TIMING) | |
3006 | - // update current position on dummyamp | |
3007 | - DummyAmp::getInstance()->getPlayInfo().setPlayPosition((int)(time * 1000)); | |
3008 | -#else | |
3009 | - // update raw current position on dummyamp | |
3010 | - DummyAmp::getInstance()->getRawPlayInfo().setPlayPosition((int)(time * 1000)); | |
3011 | - | |
3012 | - // reset send timing | |
3013 | - resetSendTiming(); | |
3014 | -#endif | |
3015 | - } | |
3016 | - | |
3017 | -#if IS_FB2K_VER08 | |
3018 | - virtual void on_playback_pause(int state) | |
3019 | -#elif IS_FB2K_VER09 | |
3020 | - virtual void on_playback_pause(bool state) | |
3021 | -#endif | |
3022 | - { | |
3023 | - TRACE_CALLBACK(_T("play_callback_mixi::on_playback_pause - called.")); | |
3024 | - | |
3025 | -#if IS_FB2K_VER08 | |
3026 | - if(state == 1) | |
3027 | -#elif IS_FB2K_VER09 | |
3028 | - if(state == true) | |
3029 | -#endif | |
3030 | - { | |
3031 | - // set dummyamp status PLAY_PAUSE | |
3032 | - DummyAmp::getInstance()->getPlayInfo().setPlayStatusPause(); | |
3033 | - | |
3034 | - // set dummyamp raw status PLAY_PAUSE | |
3035 | - DummyAmp::getInstance()->getRawPlayInfo().setPlayStatusPause(); | |
3036 | - | |
3037 | - DEBUG_CALLBACK(_T("play_callback_mixi::on_playback_pause - fb2k paused.")); | |
3038 | - } | |
3039 | - else | |
3040 | - { | |
3041 | -#if !defined(CONTROL_SEND_TIMING) | |
3042 | - // set dummyamp status PLAY_START | |
3043 | - DummyAmp::getInstance()->getPlayInfo().setPlayStatusStart(); | |
3044 | -#else | |
3045 | - // set dummyamp status PLAY_STOP | |
3046 | - DummyAmp::getInstance()->getPlayInfo().setPlayStatusStop(); | |
3047 | -#endif | |
3048 | - | |
3049 | - // set dummyamp rawa status PLAY_START | |
3050 | - DummyAmp::getInstance()->getRawPlayInfo().setPlayStatusStart(); | |
3051 | - | |
3052 | - DEBUG_CALLBACK(_T("play_callback_mixi::on_playback_pause - fb2k unpaused.")); | |
3053 | - } | |
3054 | - } | |
3055 | - | |
3056 | -#if IS_FB2K_VER08 | |
3057 | - virtual void on_playback_edited(metadb_handle * track){}//currently played file got edited | |
3058 | -#elif IS_FB2K_VER09 | |
3059 | - virtual void on_playback_edited(metadb_handle_ptr track){}//currently played file got edited | |
3060 | -#endif | |
3061 | - | |
3062 | -#if IS_FB2K_VER08 | |
3063 | - virtual void on_playback_dynamic_info(const file_info * info,bool b_track_change) | |
3064 | -#elif IS_FB2K_VER09 | |
3065 | - virtual void on_playback_dynamic_info(const file_info & info) | |
3066 | -#endif | |
3067 | - { | |
3068 | -#if IS_FB2K_VER08 | |
3069 | - TRACE_CALLBACK(_T("play_callback_mixi::on_playback_dynamic_info - called.")); | |
3070 | - | |
3071 | - if(isDynamic() && b_track_change) | |
3072 | - { | |
3073 | - refreshDynamicInfo(); | |
3074 | - } | |
3075 | -#endif | |
3076 | - } | |
3077 | - | |
3078 | -#if IS_FB2K_VER09 | |
3079 | - virtual void on_playback_dynamic_info_track(const file_info & p_info) { | |
3080 | - | |
3081 | - TRACE_CALLBACK(_T("play_callback_mixi::on_playback_dynamic_info_track - called.")); | |
3082 | - | |
3083 | - if(isDynamic()) | |
3084 | - { | |
3085 | - refreshDynamicInfo(); | |
3086 | - } | |
3087 | - }; | |
3088 | -#endif | |
3089 | - | |
3090 | -#if IS_FB2K_VER08 | |
3091 | - virtual void on_playback_time(metadb_handle * track, double time)//called every second | |
3092 | -#elif IS_FB2K_VER09 | |
3093 | - virtual void on_playback_time(double time)//called every second | |
3094 | -#endif | |
3095 | - { | |
3096 | - TRACE_CALLBACK(_T("play_callback_mixi::on_playback_time - called.")); | |
3097 | - | |
3098 | - // update current raw position on dummyamp | |
3099 | - DummyAmp::getInstance()->getRawPlayInfo().setPlayPosition((int)(time * 1000)); | |
3100 | - | |
3101 | - if(DummyAmp::getInstance()->getPlayInfo().isPlayInfoMp3Available() == true) | |
3102 | - { | |
3103 | -#if !defined(CONTROL_SEND_TIMING) | |
3104 | - // update current position on dummyamp | |
3105 | - DummyAmp::getInstance()->getPlayInfo().setPlayPosition((int)(time * 1000)); | |
3106 | -#else | |
3107 | -#if !defined(ENABLE_MSN) | |
3108 | - if(m_bPassThesholdTime == true) { | |
3109 | - // update current position on dummyamp | |
3110 | - DummyAmp::getInstance()->getPlayInfo().setPlayPosition((int)(time * 1000)); | |
3111 | - } | |
3112 | -#endif | |
3113 | - if(checkSendTiming(time) == true) | |
3114 | - { | |
3115 | - DEBUG_CALLBACK(_T("play_callback_mixi::on_playback_time - send track informations ...")); | |
3116 | - | |
3117 | -#if !defined(ENABLE_MSN) | |
3118 | - //dummyamp resent mode | |
3119 | - DummyAmp::getInstance()->getPlayInfo().setPlayPosition((int)(time * 1000)); | |
3120 | - DummyAmp::getInstance()->getPlayInfo().setResentMode(false); | |
3121 | - | |
3122 | -// // update dummyamp title | |
3123 | -// DummyAmp::getInstance()->updateDummyAmpTitle(); | |
3124 | - | |
3125 | - // set dummyamp status PLAY_START | |
3126 | - DummyAmp::getInstance()->getPlayInfo().setPlayStatusStart(); | |
3127 | -#else | |
3128 | - // send track informations to M2M | |
3129 | - MSNSender::SendTrackInfo(m_trackInfoUtf8); | |
3130 | -#endif | |
3131 | - } | |
3132 | -#endif | |
3133 | - } | |
3134 | - } | |
3135 | - | |
3136 | -protected: | |
3137 | - | |
3138 | -#if defined(CONTROL_SEND_TIMING) | |
3139 | - void resetSendTiming() | |
3140 | - { | |
3141 | - TRACE_CALLBACK(_T("play_callback_mixi::resetSendTiming - called.")); | |
3142 | - | |
3143 | - m_previous_sec = -1.0; | |
3144 | - m_bPassLowerBoundTime = false; | |
3145 | - m_bPassThesholdTime = false; | |
3146 | - } | |
3147 | - | |
3148 | - bool checkSendTiming(double sec) | |
3149 | - { | |
3150 | - TRACE_CALLBACK(_T("play_callback_mixi::checkSendTiming - called.")); | |
3151 | - | |
3152 | - if(m_bPassThesholdTime == true) return false; | |
3153 | - | |
3154 | - if(m_previous_sec < 0.0) { | |
3155 | - m_previous_sec = sec - 1.0; | |
3156 | - } | |
3157 | - | |
3158 | - double elapsedTime = sec - m_previous_sec; | |
3159 | - | |
3160 | - double lowerBoundTime = pfc_string_to_float(cfg_send_interval1); | |
3161 | - double thresholdTime1 = m_song_total_sec * pfc_string_to_float(cfg_send_interval2) / 100.0; | |
3162 | - double thresholdTime2 = pfc_string_to_float(cfg_send_interval3); | |
3163 | - double thresholdTime = min(thresholdTime1, thresholdTime2); | |
3164 | - | |
3165 | -#if 0 | |
3166 | - if(lowerBoundTime < 10.0) lowerBoundTime = 10.0; | |
3167 | - | |
3168 | - if(thresholdTime < 10.0) thresholdTime = 10.0; | |
3169 | -#endif | |
3170 | - if(thresholdTime < lowerBoundTime) thresholdTime = lowerBoundTime; | |
3171 | - | |
3172 | - if(m_bPassLowerBoundTime == false) | |
3173 | - { | |
3174 | - TRACE_CALLBACK(_T("play_callback_mixi::checkSendTiming - pos: %5.1f, lowerBound:%5.1f, elapse:%5.1f"), | |
3175 | - sec, lowerBoundTime, elapsedTime); | |
3176 | - | |
3177 | - if(lowerBoundTime <= elapsedTime + 3) // add gen_mixi response time | |
3178 | - { | |
3179 | - m_bPassLowerBoundTime = true; | |
3180 | - } | |
3181 | - } | |
3182 | - | |
3183 | - if((m_bPassLowerBoundTime == true) && (m_bPassThesholdTime == false)) | |
3184 | - { | |
3185 | - TRACE_CALLBACK(_T("play_callback_mixi::checkSendTiming - pos: %5.1f, threshold:%5.1f, elapse:%5.1f"), | |
3186 | - sec, thresholdTime, elapsedTime); | |
3187 | - | |
3188 | - if(thresholdTime <= elapsedTime + 3) // add gen_mixi response time | |
3189 | - { | |
3190 | - m_bPassThesholdTime = true; | |
3191 | - return true; | |
3192 | - } | |
3193 | - } | |
3194 | - | |
3195 | - return false; | |
3196 | - } | |
3197 | -#endif | |
3198 | - | |
3199 | - void refreshDynamicInfo() | |
3200 | - { | |
3201 | - if(cfg_enable_streaming_file == 0) | |
3202 | - { | |
3203 | - DEBUG_CALLBACK(_T("play_callback_mixi::refreshDynamicInfo - SKIP this track. (ストリーミング情報の送信が許可されていません)")); | |
3204 | - setFirstDynamicCallback(false); | |
3205 | - return ; | |
3206 | - } | |
3207 | - | |
3208 | - if(cfg_disable_dummy_mp3 == 1) | |
3209 | - { | |
3210 | - DEBUG_CALLBACK(_T("play_callback_mixi::refreshDynamicInfo - SKIP this track. (ストリーミング情報を送信するには、ダミーMP3ファイルが有効にしてください)")); | |
3211 | - setFirstDynamicCallback(false); | |
3212 | - return ; | |
3213 | - } | |
3214 | - | |
3215 | - // reset send timing | |
3216 | - resetSendTiming(); | |
3217 | - | |
3218 | - // clear raw playinfo on dummyamp (no resent mode) | |
3219 | - DummyAmp::getInstance()->getRawPlayInfo().clearPlayInfo(false); | |
3220 | - | |
3221 | - // set playinfo raw mp3 file path to dummyAmp | |
3222 | - DummyAmp::getInstance()->getRawPlayInfo().setPlayInfoMp3Path(DummyAmp::getInstance()->getTrackInfo().getString(FORMAT_FILEPATH).c_str()); | |
3223 | - | |
3224 | - // set dummyamp raw status PLAY_START | |
3225 | - DummyAmp::getInstance()->getRawPlayInfo().setPlayStatusStart(); | |
3226 | - | |
3227 | - // set raw song total length | |
3228 | - DummyAmp::getInstance()->getRawPlayInfo().setPlayLength(static_cast<int>(m_song_total_sec)); | |
3229 | - | |
3230 | - // increment play counter | |
3231 | - DummyAmp::getInstance()->getRawPlayInfo().incrementPlayCount(); | |
3232 | - | |
3233 | - // clear playinfo on dummyamp | |
3234 | - DummyAmp::getInstance()->getPlayInfo().clearPlayInfo(); | |
3235 | - | |
3236 | - // set song total length | |
3237 | - DummyAmp::getInstance()->getPlayInfo().setPlayLength(static_cast<int>(m_song_total_sec)); | |
3238 | - | |
3239 | - // increment play counter on dummyamp | |
3240 | - DummyAmp::getInstance()->getPlayInfo().incrementPlayCount(); | |
3241 | - | |
3242 | - DEBUG_CALLBACK(_T("play_callback_mixi::on_playback_dynamic_info_track - IPC_INTERNAL_REFRESHDYNINFO posted.")); | |
3243 | - ::PostMessage(DummyAmp::getInstance()->getWnd(), WM_WA_IPC, 0, IPC_INTERNAL_REFRESHDYNINFO); | |
3244 | - setFirstDynamicCallback(false); | |
3245 | - } | |
3246 | - | |
3247 | -#if IS_FB2K_VER09 | |
3248 | - // User changed volume settings. Possibly called when not playing. | |
3249 | - virtual void on_volume_change(float new_val) {} | |
3250 | -#endif | |
3251 | - | |
3252 | - void setFirstDynamicCallback(bool isFirst) { | |
3253 | - m_isFirstDynamicCallback = isFirst; | |
3254 | - } | |
3255 | - | |
3256 | - bool isFirstDynamicCallback() const { | |
3257 | - return m_isFirstDynamicCallback; | |
3258 | - } | |
3259 | - | |
3260 | - void setDynamic(const std::string &rawFilePath) | |
3261 | - { | |
3262 | - bool isFileProtocol = rawFilePath.find("file://") != std::string::npos; | |
3263 | - bool isCddaProtocol = rawFilePath.find("cdda://") != std::string::npos; | |
3264 | - bool isDriveName = false; | |
3265 | - | |
3266 | - if(rawFilePath.length() >= 3) { | |
3267 | - LPCSTR pRawFilePath = rawFilePath.c_str(); | |
3268 | - isDriveName = ::isalpha(pRawFilePath[0]) && (pRawFilePath[1] == ':') && (pRawFilePath[2] == '\\'); | |
3269 | - } | |
3270 | - | |
3271 | - m_isDynamic = !(isFileProtocol || isCddaProtocol || isDriveName); | |
3272 | - } | |
3273 | - | |
3274 | - bool isDynamic() const { | |
3275 | - return m_isDynamic; | |
3276 | - } | |
3277 | - | |
3278 | -protected: | |
3279 | - | |
3280 | -// TrackInfo m_trackInfo; | |
3281 | - | |
3282 | - double m_previous_sec; | |
3283 | - double m_song_total_sec; | |
3284 | - | |
3285 | - bool m_bPassLowerBoundTime; | |
3286 | - bool m_bPassThesholdTime; | |
3287 | - | |
3288 | - bool m_isDynamic; | |
3289 | - bool m_isFirstDynamicCallback; | |
3290 | -}; | |
3291 | - | |
3292 | - | |
3293 | -class initquit_mixi : public initquit | |
3294 | -{ | |
3295 | - typedef std::auto_ptr<DummyAmp> DummyAmpAutoPtr; | |
3296 | - DummyAmpAutoPtr m_apDummyAmp; | |
3297 | - | |
3298 | - virtual void on_init() | |
3299 | - { | |
3300 | - m_apDummyAmp = DummyAmpAutoPtr(DummyAmp::getInstance()); | |
3301 | - m_apDummyAmp->load(); | |
3302 | - } | |
3303 | - | |
3304 | - virtual void on_quit() | |
3305 | - { | |
3306 | - m_apDummyAmp->release(); | |
3307 | - { | |
3308 | - DummyAmpAutoPtr sink(m_apDummyAmp); | |
3309 | - } | |
3310 | - } | |
3311 | - | |
3312 | - virtual void on_system_shutdown() | |
3313 | - { | |
3314 | - on_quit(); | |
3315 | - } | |
3316 | -}; | |
3317 | - | |
3318 | -#if IS_FB2K_VER08 | |
3319 | -class menu_item_mixi : public menu_item_main | |
3320 | -#elif IS_FB2K_VER09 | |
3321 | -// {E8BF1F91-9262-4c0b-AD39-00C0B24B4210} | |
3322 | -static const GUID menu_item_mixi_guid = { 0xe8bf1f91, 0x9262, 0x4c0b, { 0xad, 0x39, 0x0, 0xc0, 0xb2, 0x4b, 0x42, 0x10 } }; | |
3323 | -class menu_item_mixi : public mainmenu_commands | |
3324 | -#endif | |
3325 | -{ | |
3326 | -#if IS_FB2K_VER08 | |
3327 | - virtual unsigned get_num_items() { | |
3328 | -#elif IS_FB2K_VER09 | |
3329 | - virtual t_uint32 get_command_count() { | |
3330 | -#endif | |
3331 | - return 1; | |
3332 | - } | |
3333 | - | |
3334 | -#if IS_FB2K_VER08 | |
3335 | - virtual void enum_item(unsigned n, string_base & out) { | |
3336 | - out = (n==0 ? g_menu_item : ""); | |
3337 | - } | |
3338 | -#elif IS_FB2K_VER09 | |
3339 | - virtual GUID get_command(t_uint32 p_index) | |
3340 | - { | |
3341 | - if (p_index == 0) { | |
3342 | - return menu_item_mixi_guid; | |
3343 | - } | |
3344 | - | |
3345 | - return pfc::guid_null; | |
3346 | - } | |
3347 | - | |
3348 | - virtual void get_name(t_uint32 p_index, string_base & p_out) | |
3349 | - { | |
3350 | - if (p_index == 0) | |
3351 | - { | |
3352 | - p_out = g_menu_item_title; | |
3353 | - } | |
3354 | - } | |
3355 | - | |
3356 | - virtual bool get_description(t_uint32 p_index, string_base & p_out) | |
3357 | - { | |
3358 | - if (p_index == 0) | |
3359 | - { | |
3360 | - p_out = g_menu_item_description; | |
3361 | - } | |
3362 | - else | |
3363 | - { | |
3364 | - return false; | |
3365 | - } | |
3366 | - | |
3367 | - return true; | |
3368 | - } | |
3369 | - | |
3370 | - virtual GUID get_parent() { | |
3371 | - return mainmenu_groups::playback_etc; | |
3372 | - } | |
3373 | - | |
3374 | -#endif | |
3375 | - | |
3376 | -#if IS_FB2K_VER08 | |
3377 | - virtual bool is_checked(int index) | |
3378 | - { | |
3379 | - bool flags = false; | |
3380 | - static const bool flag_checked = TRUE; | |
3381 | -#elif IS_FB2K_VER09 | |
3382 | - virtual bool get_display(t_uint32 index, pfc::string_base & text, t_uint32 & flags) | |
3383 | - { | |
3384 | - flags = 0; | |
3385 | -#endif | |
3386 | - switch (index) | |
3387 | - { | |
3388 | - case 0: | |
3389 | - if (cfg_use_plugin == 1) flags = flag_checked; | |
3390 | - break; | |
3391 | - } | |
3392 | - | |
3393 | -#if IS_FB2K_VER08 | |
3394 | - return flags; | |
3395 | -#elif IS_FB2K_VER09 | |
3396 | - get_name(index, text); | |
3397 | - return true; | |
3398 | -#endif | |
3399 | - } | |
3400 | - | |
3401 | -#if IS_FB2K_VER08 | |
3402 | - virtual void perform_command(unsigned index) | |
3403 | - { | |
3404 | -#elif IS_FB2K_VER09 | |
3405 | - virtual void execute(t_uint32 index, service_ptr_t<service_base> /* reserved for future use */) | |
3406 | - { | |
3407 | -#endif | |
3408 | - if ((index == 0) && core_api::assert_main_thread()) | |
3409 | - { | |
3410 | - cfg_use_plugin = 1 - cfg_use_plugin; | |
3411 | - | |
3412 | - if(cfg_use_plugin > 1) | |
3413 | - { | |
3414 | - cfg_use_plugin = 1; | |
3415 | - } | |
3416 | - else if(cfg_use_plugin < 0) | |
3417 | - { | |
3418 | - cfg_use_plugin = 0; | |
3419 | - } | |
3420 | - | |
3421 | - if (cfg_use_plugin == 1) | |
3422 | - { | |
3423 | - DEBUG_PLUGIN(_T("menu_item_mixi::execute - mixiミュージック連携を有効にしました")); | |
3424 | - } | |
3425 | - else | |
3426 | - { | |
3427 | - DEBUG_PLUGIN(_T("menu_item_mixi::execute - mixiミュージック連携を無効にしました")); | |
3428 | - } | |
3429 | - } | |
3430 | - } | |
3431 | -}; | |
3432 | - | |
3433 | -#define CLEARTYPE_QUALITY 5 | |
3434 | - | |
3435 | -#if IS_FB2K_VER08 | |
3436 | -class config_page_mixi : public config | |
3437 | -#elif IS_FB2K_VER09 | |
3438 | -// {976D6C46-31E4-4ab4-8BFF-5FB2E9BFD599} | |
3439 | -static const GUID config_page_mixi_guid = { 0x976d6c46, 0x31e4, 0x4ab4, { 0x8b, 0xff, 0x5f, 0xb2, 0xe9, 0xbf, 0xd5, 0x99 } }; | |
3440 | -class config_page_mixi : public preferences_page | |
3441 | -#endif | |
3442 | -{ | |
3443 | - static HFONT hIntervalFont; | |
3444 | - | |
3445 | - static BOOL CALLBACK ConfigProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp) | |
3446 | - { | |
3447 | - HWND hSendInterval1 = uGetDlgItem(wnd, IDC_SEND_INTERVAL_SLIDER_1ST); | |
3448 | - HWND hSendInterval2 = uGetDlgItem(wnd, IDC_SEND_INTERVAL_SLIDER_2ND); | |
3449 | - HWND hSendInterval3 = uGetDlgItem(wnd, IDC_SEND_INTERVAL_SLIDER_3RD); | |
3450 | - | |
3451 | - HWND hSendInterval1Text = uGetDlgItem(wnd, IDC_SEND_INTERVAL_1ST); | |
3452 | - HWND hSendInterval2Text = uGetDlgItem(wnd, IDC_SEND_INTERVAL_2ND); | |
3453 | - HWND hSendInterval3Text = uGetDlgItem(wnd, IDC_SEND_INTERVAL_3RD); | |
3454 | - | |
3455 | - switch(msg) | |
3456 | - { | |
3457 | - case WM_INITDIALOG: | |
3458 | - { | |
3459 | - HDC hWndDC = ::GetWindowDC(wnd); | |
3460 | - hIntervalFont = ::CreateFont( | |
3461 | - -MulDiv(20, GetDeviceCaps(hWndDC, LOGPIXELSY), 72), 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, | |
3462 | - ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, FIXED_PITCH, _T("Arial") | |
3463 | - ); | |
3464 | - ::ReleaseDC(wnd, hWndDC); | |
3465 | - | |
3466 | - uSendMessage(hSendInterval1Text, WM_SETFONT, (WPARAM)hIntervalFont, (LPARAM)FALSE); | |
3467 | - uSendMessage(hSendInterval2Text, WM_SETFONT, (WPARAM)hIntervalFont, (LPARAM)FALSE); | |
3468 | - uSendMessage(hSendInterval3Text, WM_SETFONT, (WPARAM)hIntervalFont, (LPARAM)FALSE); | |
3469 | - | |
3470 | - uButton_SetCheck(wnd, IDC_USE_PLUGIN, (cfg_use_plugin == 1) ? true : false); | |
3471 | - | |
3472 | - uButton_SetCheck(wnd, IDC_DISABLE_DUPLICATE_SONG, (cfg_disable_duplicate_song == 1) ? true : false); | |
3473 | - uButton_SetCheck(wnd, IDC_DISABLE_DUMMY_MP3, (cfg_disable_dummy_mp3 == 1) ? true : false); | |
3474 | - uButton_SetCheck(wnd, IDC_MEDIA_LIBRARY_REGISTERED_FILE_ONLY, (cfg_media_library_registered_file_only == 1) ? true : false); | |
3475 | - uButton_SetCheck(wnd, IDC_EXPLICITLY_TAGGED_FILE_ONLY, (cfg_explicitly_tagged_file_only == 1) ? true : false); | |
3476 | - | |
3477 | - uSetDlgItemText(wnd, IDC_NO_ARTIST_NAME, cfg_no_artist_name); | |
3478 | - uSetDlgItemText(wnd, IDC_NO_TITLE_NAME, cfg_no_title_name); | |
3479 | - uSetDlgItemText(wnd, IDC_NO_ALBUM_NAME, cfg_no_album_name); | |
3480 | - uSetDlgItemText(wnd, IDC_NO_GENRE_NAME, cfg_no_genre_name); | |
3481 | - | |
3482 | - EnableNoNames(wnd, (cfg_explicitly_tagged_file_only == 0) ? true : false); | |
3483 | - | |
3484 | - uButton_SetCheck(wnd, IDC_ENABLE_STREAMING_FILE, (cfg_enable_streaming_file == 1) ? true : false); | |
3485 | - | |
3486 | - uSetDlgItemText(wnd, IDC_SEND_INTERVAL_1ST, cfg_send_interval1); | |
3487 | - uSetDlgItemText(wnd, IDC_SEND_INTERVAL_2ND, cfg_send_interval2); | |
3488 | - uSetDlgItemText(wnd, IDC_SEND_INTERVAL_3RD, cfg_send_interval3); | |
3489 | - | |
3490 | - uSendMessage(hSendInterval1, TBM_SETRANGE, (WPARAM)FALSE, (LPARAM)MAKELONG(REQUIRED_MINIMUM_TIME, 300)); | |
3491 | - uSendMessage(hSendInterval1, TBM_SETLINESIZE, (WPARAM)0, (LPARAM)1); | |
3492 | - uSendMessage(hSendInterval1, TBM_SETPAGESIZE, (WPARAM)0, (LPARAM)20); | |
3493 | - uSendMessage(hSendInterval1, TBM_SETTICFREQ, (WPARAM)20, (LPARAM)0); | |
3494 | - | |
3495 | - double pos1 = pfc_string_to_float(cfg_send_interval1); | |
3496 | - uSendMessage(hSendInterval1, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos1); | |
3497 | - | |
3498 | - uSendMessage(hSendInterval2, TBM_SETRANGE, (WPARAM)FALSE, (LPARAM)MAKELONG(SEND_TIME_RATE_LOWERBOUND, 100)); | |
3499 | - uSendMessage(hSendInterval2, TBM_SETLINESIZE, (WPARAM)0, (LPARAM)1); | |
3500 | - uSendMessage(hSendInterval2, TBM_SETPAGESIZE, (WPARAM)0, (LPARAM)5); | |
3501 | - uSendMessage(hSendInterval2, TBM_SETTICFREQ, (WPARAM)5, (LPARAM)0); | |
3502 | - | |
3503 | - double pos2 = pfc_string_to_float(cfg_send_interval2); | |
3504 | - uSendMessage(hSendInterval2, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos2); | |
3505 | - | |
3506 | - uSendMessage(hSendInterval3, TBM_SETRANGE, (WPARAM)FALSE, (LPARAM)MAKELONG(REQUIRED_MAXIMUM_TIME, 9999)); | |
3507 | - uSendMessage(hSendInterval3, TBM_SETLINESIZE, (WPARAM)0, (LPARAM)10); | |
3508 | - uSendMessage(hSendInterval3, TBM_SETPAGESIZE, (WPARAM)0, (LPARAM)100); | |
3509 | - uSendMessage(hSendInterval3, TBM_SETTICFREQ, (WPARAM)1000, (LPARAM)0); | |
3510 | - | |
3511 | - double pos3 = pfc_string_to_float(cfg_send_interval3); | |
3512 | - uSendMessage(hSendInterval3, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos3); | |
3513 | - | |
3514 | - uSetDlgItemText(wnd, IDC_VERSION, PLUGIN_CAPTION " " PLUGIN_VERSION); | |
3515 | - uSetDlgItemText(wnd, IDC_BUILD, "build on " __DATE__ ", " __TIME__); | |
3516 | - } | |
3517 | - break; | |
3518 | - | |
3519 | - case WM_COMMAND: | |
3520 | - switch(wp) | |
3521 | - { | |
3522 | - case (BN_CLICKED<<16)|IDC_USE_PLUGIN: | |
3523 | - cfg_use_plugin = uButton_GetCheck(wnd, IDC_USE_PLUGIN) ? 1 : 0; | |
3524 | - break; | |
3525 | - | |
3526 | - case (EN_UPDATE<<16)|IDC_NO_ARTIST_NAME: | |
3527 | - { | |
3528 | - string8 name; | |
3529 | - uGetWindowText(reinterpret_cast<HWND>(lp), name); | |
3530 | - cfg_no_artist_name = name; | |
3531 | - } | |
3532 | - break; | |
3533 | - | |
3534 | - case (EN_UPDATE<<16)|IDC_NO_TITLE_NAME: | |
3535 | - { | |
3536 | - string8 name; | |
3537 | - uGetWindowText(reinterpret_cast<HWND>(lp), name); | |
3538 | - cfg_no_title_name = name; | |
3539 | - } | |
3540 | - break; | |
3541 | - | |
3542 | - case (EN_UPDATE<<16)|IDC_NO_ALBUM_NAME: | |
3543 | - { | |
3544 | - string8 name; | |
3545 | - uGetWindowText(reinterpret_cast<HWND>(lp), name); | |
3546 | - cfg_no_album_name = name; | |
3547 | - } | |
3548 | - break; | |
3549 | - | |
3550 | - case (EN_UPDATE<<16)|IDC_NO_GENRE_NAME: | |
3551 | - { | |
3552 | - string8 name; | |
3553 | - uGetWindowText(reinterpret_cast<HWND>(lp), name); | |
3554 | - cfg_no_genre_name = name; | |
3555 | - } | |
3556 | - break; | |
3557 | - | |
3558 | - case (BN_CLICKED<<16)|IDC_DISABLE_DUPLICATE_SONG: | |
3559 | - cfg_disable_duplicate_song = uButton_GetCheck(wnd, IDC_DISABLE_DUPLICATE_SONG) ? 1 : 0; | |
3560 | - break; | |
3561 | - | |
3562 | - case (BN_CLICKED<<16)|IDC_DISABLE_DUMMY_MP3: | |
3563 | - cfg_disable_dummy_mp3 = uButton_GetCheck(wnd, IDC_DISABLE_DUMMY_MP3) ? 1 : 0; | |
3564 | - break; | |
3565 | - | |
3566 | - case (BN_CLICKED<<16)|IDC_MEDIA_LIBRARY_REGISTERED_FILE_ONLY: | |
3567 | - cfg_media_library_registered_file_only = uButton_GetCheck(wnd, IDC_MEDIA_LIBRARY_REGISTERED_FILE_ONLY) ? 1 : 0; | |
3568 | - break; | |
3569 | - | |
3570 | - case (BN_CLICKED<<16)|IDC_EXPLICITLY_TAGGED_FILE_ONLY: | |
3571 | - cfg_explicitly_tagged_file_only = uButton_GetCheck(wnd, IDC_EXPLICITLY_TAGGED_FILE_ONLY) ? 1 : 0; | |
3572 | - EnableNoNames(wnd, (cfg_explicitly_tagged_file_only == 0) ? true : false); | |
3573 | - break; | |
3574 | - | |
3575 | - case (BN_CLICKED<<16)|IDC_ENABLE_STREAMING_FILE: | |
3576 | - cfg_enable_streaming_file = uButton_GetCheck(wnd, IDC_ENABLE_STREAMING_FILE) ? 1 : 0; | |
3577 | - break; | |
3578 | - | |
3579 | - case (BN_CLICKED<<16)|IDC_CONFIGURE: | |
3580 | - DummyAmp::getInstance()->config(); | |
3581 | - break; | |
3582 | - } | |
3583 | - break; | |
3584 | - | |
3585 | - case WM_HSCROLL: | |
3586 | - { | |
3587 | - HWND hTrackBar = (HWND)lp; | |
3588 | - | |
3589 | - if((hTrackBar == hSendInterval1) | |
3590 | - || (hTrackBar == hSendInterval2) | |
3591 | - || (hTrackBar == hSendInterval3)) | |
3592 | - { | |
3593 | - switch(LOWORD(wp)) | |
3594 | - { | |
3595 | - case TB_THUMBPOSITION: | |
3596 | - case TB_THUMBTRACK: | |
3597 | - case TB_TOP: | |
3598 | - case TB_BOTTOM: | |
3599 | - case TB_PAGEUP: | |
3600 | - case TB_PAGEDOWN: | |
3601 | - case TB_LINEUP: | |
3602 | - case TB_LINEDOWN: | |
3603 | - case TB_ENDTRACK: | |
3604 | - { | |
3605 | - LRESULT lPos = 0; | |
3606 | - | |
3607 | - switch(LOWORD(wp)) | |
3608 | - { | |
3609 | - case TB_THUMBPOSITION: | |
3610 | - case TB_THUMBTRACK: | |
3611 | - lPos = HIWORD(wp); | |
3612 | - break; | |
3613 | - default: | |
3614 | - lPos = uSendMessage(hTrackBar, TBM_GETPOS, 0, 0); | |
3615 | - break; | |
3616 | - } | |
3617 | - | |
3618 | - uSendMessage(hTrackBar, TBM_SETPOS, (WPARAM)TRUE, lPos); | |
3619 | - | |
3620 | - if(hTrackBar == hSendInterval1) | |
3621 | - { | |
3622 | - setDlgItemFloat(wnd, IDC_SEND_INTERVAL_1ST, (double)lPos); | |
3623 | - string8 pos; | |
3624 | - float2String(pos, (double)lPos); | |
3625 | - cfg_send_interval1 = pos; | |
3626 | - } | |
3627 | - else if(hTrackBar == hSendInterval2) | |
3628 | - { | |
3629 | - setDlgItemFloat(wnd, IDC_SEND_INTERVAL_2ND, (double)lPos); | |
3630 | - string8 pos; | |
3631 | - float2String(pos, (double)lPos); | |
3632 | - cfg_send_interval2 = pos; | |
3633 | - } | |
3634 | - else if(hTrackBar == hSendInterval3) | |
3635 | - { | |
3636 | - setDlgItemFloat(wnd, IDC_SEND_INTERVAL_3RD, (double)lPos); | |
3637 | - string8 pos; | |
3638 | - float2String(pos, (double)lPos); | |
3639 | - cfg_send_interval3 = pos; | |
3640 | - } | |
3641 | - } | |
3642 | - break; | |
3643 | - | |
3644 | - default: | |
3645 | - break; | |
3646 | - } | |
3647 | - } | |
3648 | - } | |
3649 | - break; | |
3650 | - case WM_DESTROY: | |
3651 | - if(hIntervalFont != INVALID_HANDLE_VALUE) { | |
3652 | - ::DeleteObject(hIntervalFont); | |
3653 | - } | |
3654 | - break; | |
3655 | - } | |
3656 | - | |
3657 | - return 0; | |
3658 | - } | |
3659 | - | |
3660 | - static void setDlgItemFloat(HWND wnd, UINT id, double val) | |
3661 | - { | |
3662 | - string8 pos; | |
3663 | - float2String(pos, val); | |
3664 | - | |
3665 | - uSetDlgItemText(wnd, id, pos); | |
3666 | - } | |
3667 | - | |
3668 | - static void float2String(string8 &str, double val) | |
3669 | - { | |
3670 | -#if IS_FB2K_VER08 | |
3671 | - char *pStr = str.buffer_get(1024); | |
3672 | - pfc_float_to_string(pStr, val, 0); | |
3673 | - str.buffer_done(); | |
3674 | -#elif IS_FB2K_VER09 | |
3675 | - char *pStr = str.lock_buffer(1024); | |
3676 | - float_to_string(pStr, 1024, val, 0); | |
3677 | - str.unlock_buffer(); | |
3678 | -#endif | |
3679 | - } | |
3680 | - | |
3681 | - static void EnableNoNames(HWND wnd, bool bNoNameEnabled) { | |
3682 | - EnableNoName(wnd, IDC_NO_ARTIST_NAME, bNoNameEnabled); | |
3683 | - EnableNoName(wnd, IDC_NO_TITLE_NAME, bNoNameEnabled); | |
3684 | - EnableNoName(wnd, IDC_NO_ALBUM_NAME, bNoNameEnabled); | |
3685 | - EnableNoName(wnd, IDC_NO_GENRE_NAME, bNoNameEnabled); | |
3686 | - } | |
3687 | - | |
3688 | - static void EnableNoName(HWND wnd, UINT id, bool bEnable) { | |
3689 | - HWND hControlWnd = uGetDlgItem(wnd, id); | |
3690 | - uEnableWindow(hControlWnd, bEnable); | |
3691 | - } | |
3692 | - | |
3693 | -public: | |
3694 | - virtual HWND create(HWND parent) | |
3695 | - { | |
3696 | - return uCreateDialog(IDD_PREFERENCE, parent, ConfigProc); | |
3697 | - } | |
3698 | - | |
3699 | - virtual const char * get_name() { | |
3700 | - return g_pluginCaption8; | |
3701 | - } | |
3702 | - | |
3703 | - virtual const char * get_parent_name() { | |
3704 | - return "Components"; | |
3705 | - } | |
3706 | - | |
3707 | -#if IS_FB2K_VER09 | |
3708 | - virtual GUID get_guid() { | |
3709 | - return config_page_mixi_guid; | |
3710 | - } | |
3711 | - | |
3712 | - virtual GUID get_parent_guid() { | |
3713 | - return guid_tools; | |
3714 | - } | |
3715 | - | |
3716 | - virtual bool reset_query() { | |
3717 | - return true; | |
3718 | - } | |
3719 | - | |
3720 | - virtual void reset() | |
3721 | - { | |
3722 | - cfg_use_plugin = 1; | |
3723 | - cfg_disable_duplicate_song = 0; | |
3724 | - cfg_media_library_registered_file_only = 0; | |
3725 | - cfg_send_interval1 = "20"; | |
3726 | - cfg_send_interval2 = "66"; | |
3727 | - cfg_send_interval3 = "300"; | |
3728 | - } | |
3729 | - | |
3730 | - virtual bool get_help_url(pfc::string_base & p_out) | |
3731 | - { | |
3732 | - p_out = URL_FOO_MIXI_HOME; | |
3733 | - return true; | |
3734 | - } | |
3735 | -#endif | |
3736 | -}; | |
3737 | - | |
3738 | -HFONT config_page_mixi::hIntervalFont = (HFONT)INVALID_HANDLE_VALUE; | |
3739 | - | |
3740 | -#if IS_FB2K_VER08 | |
3741 | -class config_page_mixi_advanced : public config | |
3742 | -#elif IS_FB2K_VER09 | |
3743 | -// {E01262F2-E6BF-4f3e-B0F2-5B8C08E2C2E3} | |
3744 | -static const GUID config_page_mixi_advanced_guid = { 0xe01262f2, 0xe6bf, 0x4f3e, { 0xb0, 0xf2, 0x5b, 0x8c, 0x8, 0xe2, 0xc2, 0xe3 } }; | |
3745 | -class config_page_mixi_advanced : public preferences_page_v2 | |
3746 | -#endif | |
3747 | -{ | |
3748 | - static int nOldDummyMp3Location; | |
3749 | - static string8 oldGenMixiPath; | |
3750 | - | |
3751 | - static BOOL CALLBACK ConfigProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp) | |
3752 | - { | |
3753 | - switch(msg) | |
3754 | - { | |
3755 | - case WM_INITDIALOG: | |
3756 | - { | |
3757 | - uSetDlgItemText(wnd, IDC_CAPTION_ADVANCED, g_advancedSettingsCaption8); | |
3758 | - | |
3759 | - uButton_SetCheck(wnd, IDC_DISABLE_DUMMY_MP3, (cfg_disable_dummy_mp3 == 1) ? true : false); | |
3760 | - | |
3761 | - uSendDlgItemMessage(wnd, IDC_DUMMY_MP3_LOCATION, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("ダミーMP3ファイルをユーザプロファイルに作成する"))); | |
3762 | - uSendDlgItemMessage(wnd, IDC_DUMMY_MP3_LOCATION, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("ダミーMP3ファイルを一時フォルダに作成する"))); | |
3763 | - uSendDlgItemMessage(wnd, IDC_DUMMY_MP3_LOCATION, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("ダミーMP3ファイルを Components フォルダに作成する"))); | |
3764 | - | |
3765 | - uEnableWindow(uGetDlgItem(wnd, IDC_DUMMY_MP3_LOCATION), (cfg_disable_dummy_mp3 == 0) ? true : false); | |
3766 | - | |
3767 | - uSendDlgItemMessage(wnd, IDC_DUMMY_MP3_LOCATION, CB_SETCURSEL, (int)cfg_dummy_mp3_location, 0); | |
3768 | - nOldDummyMp3Location = (int)cfg_dummy_mp3_location; | |
3769 | - | |
3770 | - uSetDlgItemText(wnd, IDC_GEN_MIXI_PATH, cfg_gen_mixi_path); | |
3771 | - oldGenMixiPath = cfg_gen_mixi_path; | |
3772 | - | |
3773 | - Str64K dummyAmpFrameCaptionBuf; | |
3774 | - | |
3775 | - _stprintf_s( | |
3776 | - dummyAmpFrameCaptionBuf, sizeof(dummyAmpFrameCaptionBuf) / sizeof(TCHAR), | |
3777 | - DUMMYAMP_FRAME_CAPTION, | |
3778 | - DummyAmp::getInstance()->getWnd() == INVALID_HANDLE_VALUE ? DUMMYAMP_BEFORE_INIT_MODE : | |
3779 | - DummyAmp::getInstance()->isAnotherWinampWindowAvailable() ? DUMMYAMP_HOOK_MODE : DUMMYAMP_STANDALONE_MODE | |
3780 | - ); | |
3781 | - | |
3782 | - ::SetDlgItemText(wnd, IDC_DUMMYAMP_FRAME, dummyAmpFrameCaptionBuf); | |
3783 | - | |
3784 | - uButton_SetCheck(wnd, IDC_SHOW_DUMMYAMP, (cfg_show_dummyamp == 1) ? true : false); | |
3785 | - if(DummyAmp::getInstance()->getWnd() == INVALID_HANDLE_VALUE) { | |
3786 | - HWND hControlWnd = uGetDlgItem(wnd, IDC_SHOW_DUMMYAMP); | |
3787 | - uEnableWindow(hControlWnd, false); | |
3788 | - } | |
3789 | - | |
3790 | - uSetDlgItemText(wnd, IDC_DUMMYAMP_TITLE_FORMAT, cfg_dummyamp_title_format); | |
3791 | - uSetDlgItemText(wnd, IDC_DUMMYAMP_PLAYLIST_FORMAT, cfg_dummyamp_playlist_format); | |
3792 | - | |
3793 | - uButton_SetCheck(wnd, IDC_DISABLE_ANSI_TRANS, (cfg_disable_ansi_trans == 1) ? true : false); | |
3794 | - uButton_SetCheck(wnd, IDC_ENABLE_EXT_IPC_PROC, (cfg_enable_ext_ipc_proc == 1) ? true : false); | |
3795 | - if(DummyAmp::getInstance()->isAnotherWinampWindowAvailable() == false) { | |
3796 | - HWND hControlWnd = uGetDlgItem(wnd, IDC_ENABLE_EXT_IPC_PROC); | |
3797 | - uEnableWindow(hControlWnd, false); | |
3798 | - } | |
3799 | - | |
3800 | - uSetDlgItemText(wnd, IDC_VERSION_ADVANCED, PLUGIN_CAPTION " " PLUGIN_VERSION); | |
3801 | - uSetDlgItemText(wnd, IDC_BUILD_ADVANCED, "build on " __DATE__ ", " __TIME__); | |
3802 | - } | |
3803 | - break; | |
3804 | - | |
3805 | - case WM_COMMAND: | |
3806 | - switch(wp) | |
3807 | - { | |
3808 | - case (BN_CLICKED<<16)|IDC_DISABLE_DUMMY_MP3: | |
3809 | - { | |
3810 | - cfg_disable_dummy_mp3 = uButton_GetCheck(wnd, IDC_DISABLE_DUMMY_MP3) ? 1 : 0; | |
3811 | - uEnableWindow(uGetDlgItem(wnd, IDC_DUMMY_MP3_LOCATION), (cfg_disable_dummy_mp3 == 0) ? true : false); | |
3812 | - } | |
3813 | - break; | |
3814 | - | |
3815 | - case (CBN_SELCHANGE<<16)|IDC_DUMMY_MP3_LOCATION: | |
3816 | - { | |
3817 | - int sel = static_cast<int>(uSendMessage(reinterpret_cast<HWND>(lp), CB_GETCURSEL, 0, 0)); | |
3818 | - cfg_dummy_mp3_location = sel; | |
3819 | - } | |
3820 | - break; | |
3821 | - | |
3822 | - case (EN_UPDATE<<16)|IDC_GEN_MIXI_PATH: | |
3823 | - { | |
3824 | - string8 path; | |
3825 | - uGetWindowText(reinterpret_cast<HWND>(lp), path); | |
3826 | - cfg_gen_mixi_path = path; | |
3827 | - } | |
3828 | - break; | |
3829 | - | |
3830 | - case (BN_CLICKED<<16)|IDC_GEN_MIXI_PATH_REF: | |
3831 | - { | |
3832 | - string8 path(cfg_gen_mixi_path); | |
3833 | - | |
3834 | - OPENFILENAME ofn; | |
3835 | - TCHAR strFile[MAX_PATH]; | |
3836 | - | |
3837 | - ::ZeroMemory(&ofn, sizeof(OPENFILENAME)); | |
3838 | - strFile[0] = _T('\0'); | |
3839 | - | |
3840 | - ofn.lStructSize = sizeof(OPENFILENAME); | |
3841 | - ofn.hwndOwner = wnd; | |
3842 | - ofn.lpstrFilter = _T("gen_mixi_for_winamp.dll\0gen_mixi_for_winamp.dll\0\0"); | |
3843 | - ofn.nFilterIndex = 0; | |
3844 | - ofn.lpstrInitialDir = PathInfo::splitPath(path).c_str(); | |
3845 | - ofn.lpstrFile = strFile; | |
3846 | - ofn.nMaxFile = MAX_PATH; | |
3847 | - ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; | |
3848 | - | |
3849 | - if(::GetOpenFileName(&ofn) == TRUE) | |
3850 | - { | |
3851 | - tstring genMixiPath(PathInfo::splitPath(strFile)); | |
3852 | - string_utf8_from_os genMixiPath8(genMixiPath.c_str()); | |
3853 | - | |
3854 | - cfg_gen_mixi_path = genMixiPath8; | |
3855 | - ::uSetDlgItemText(wnd, IDC_GEN_MIXI_PATH, genMixiPath8); | |
3856 | - } | |
3857 | - } | |
3858 | - | |
3859 | - case (BN_CLICKED<<16)|IDC_SHOW_DUMMYAMP: | |
3860 | - { | |
3861 | - bool bShowDummyAmp = uButton_GetCheck(wnd, IDC_SHOW_DUMMYAMP); | |
3862 | - cfg_show_dummyamp = bShowDummyAmp ? 1 : 0; | |
3863 | - | |
3864 | - DummyAmp::getInstance()->showDummyAmpWindow(bShowDummyAmp); | |
3865 | - } | |
3866 | - break; | |
3867 | - | |
3868 | - case (EN_UPDATE<<16)|IDC_DUMMYAMP_TITLE_FORMAT: | |
3869 | - { | |
3870 | - string8 format; | |
3871 | - uGetWindowText(reinterpret_cast<HWND>(lp), format); | |
3872 | - cfg_dummyamp_title_format = format; | |
3873 | - } | |
3874 | - break; | |
3875 | - | |
3876 | - case (EN_UPDATE<<16)|IDC_DUMMYAMP_PLAYLIST_FORMAT: | |
3877 | - { | |
3878 | - string8 format; | |
3879 | - uGetWindowText(reinterpret_cast<HWND>(lp), format); | |
3880 | - cfg_dummyamp_playlist_format = format; | |
3881 | - } | |
3882 | - break; | |
3883 | - | |
3884 | - case (BN_CLICKED<<16)|IDC_DISABLE_ANSI_TRANS: | |
3885 | - { | |
3886 | - cfg_disable_ansi_trans = uButton_GetCheck(wnd, IDC_DISABLE_ANSI_TRANS) ? 1 : 0; | |
3887 | - } | |
3888 | - break; | |
3889 | - | |
3890 | - case (BN_CLICKED<<16)|IDC_ENABLE_EXT_IPC_PROC: | |
3891 | - { | |
3892 | - cfg_enable_ext_ipc_proc = uButton_GetCheck(wnd, IDC_ENABLE_EXT_IPC_PROC) ? 1 : 0; | |
3893 | - } | |
3894 | - break; | |
3895 | - | |
3896 | - default: | |
3897 | - break; | |
3898 | - } | |
3899 | - break; | |
3900 | - case WM_DESTROY: | |
3901 | - { | |
3902 | - bool rebootNeeded = false; | |
3903 | - | |
3904 | - if(nOldDummyMp3Location != -1) | |
3905 | - { | |
3906 | - if(nOldDummyMp3Location != cfg_dummy_mp3_location) | |
3907 | - { | |
3908 | - int nRes = ::MessageBox( | |
3909 | - NULL, _T("ダミーMP3ファイルの生成場所の変更は、foobar2000本体の再起動後に有効になります。\n\n") | |
3910 | - _T("今すぐ、foobar2000をシャットダウンしますか?"), | |
3911 | - _T(PLUGIN_CAPTION), MB_YESNO | MB_ICONEXCLAMATION); | |
3912 | - | |
3913 | - if(nRes == IDYES) { | |
3914 | - rebootNeeded = true; | |
3915 | - } else { | |
3916 | - rebootNeeded = false; | |
3917 | - } | |
3918 | - } | |
3919 | - } | |
3920 | - | |
3921 | - if(::strcmp(oldGenMixiPath, cfg_gen_mixi_path) != 0) | |
3922 | - { | |
3923 | - int nRes = ::MessageBox( | |
3924 | - NULL, GEN_MIXI_FILE_NAME _T(" の配置場所の変更は、foobar2000本体の再起動後に有効になります。\n\n") | |
3925 | - _T("今すぐ、foobar2000をシャットダウンしますか?"), | |
3926 | - _T(PLUGIN_CAPTION), MB_YESNO | MB_ICONEXCLAMATION); | |
3927 | - | |
3928 | - if(nRes == IDYES) { | |
3929 | - rebootNeeded = true; | |
3930 | - } else { | |
3931 | - rebootNeeded = false; | |
3932 | - } | |
3933 | - } | |
3934 | - | |
3935 | - nOldDummyMp3Location = (int)cfg_dummy_mp3_location; | |
3936 | - oldGenMixiPath = cfg_gen_mixi_path; | |
3937 | - | |
3938 | - if(rebootNeeded) { | |
3939 | - ::PostQuitMessage(0); | |
3940 | - } | |
3941 | - } | |
3942 | - break; | |
3943 | - } | |
3944 | - | |
3945 | - return 0; | |
3946 | - } | |
3947 | - | |
3948 | -public: | |
3949 | - | |
3950 | - virtual HWND create(HWND parent) | |
3951 | - { | |
3952 | - return uCreateDialog(IDD_ADVANCED_SETTINGS, parent, ConfigProc); | |
3953 | - } | |
3954 | - | |
3955 | - virtual const char * get_name() { | |
3956 | - return g_advancedSettingsCaption8; | |
3957 | - } | |
3958 | - virtual const char * get_parent_name() { | |
3959 | - return g_pluginCaption8; | |
3960 | - } | |
3961 | - | |
3962 | -#if IS_FB2K_VER09 | |
3963 | - virtual GUID get_guid() { | |
3964 | - return config_page_mixi_advanced_guid; | |
3965 | - } | |
3966 | - | |
3967 | - virtual GUID get_parent_guid() { | |
3968 | - return config_page_mixi_guid; | |
3969 | - } | |
3970 | - | |
3971 | - virtual double get_sort_priority() { | |
3972 | - return 1.0; | |
3973 | - } | |
3974 | - | |
3975 | - virtual bool reset_query() { | |
3976 | - return true; | |
3977 | - } | |
3978 | - | |
3979 | - virtual void reset() { | |
3980 | - cfg_disable_dummy_mp3 = 0; | |
3981 | - cfg_dummy_mp3_location = 0; | |
3982 | - cfg_gen_mixi_path = PathInfo::getGenMixiDefaultPath().c_str(); | |
3983 | - | |
3984 | - cfg_show_dummyamp = 0; | |
3985 | - cfg_dummyamp_title_format = DEFAULT_DUMMYAMP_TITLE; | |
3986 | - cfg_dummyamp_playlist_format = DEFAULT_DUMMYAMP_TITLE; | |
3987 | - } | |
3988 | - | |
3989 | - virtual bool get_help_url(pfc::string_base & p_out) { | |
3990 | - p_out = URL_FOO_MIXI_HOME; | |
3991 | - return true; | |
3992 | - } | |
3993 | -#endif | |
3994 | -}; | |
3995 | - | |
3996 | -int config_page_mixi_advanced::nOldDummyMp3Location = -1; | |
3997 | -string8 config_page_mixi_advanced::oldGenMixiPath; | |
3998 | - | |
3999 | -#if IS_FB2K_VER08 | |
4000 | -class config_page_mixi_debug : public config | |
4001 | -#elif IS_FB2K_VER09 | |
4002 | -// {ADD3AC74-B1A7-4d04-BADB-6BEB7D132669} | |
4003 | -static const GUID config_page_mixi_debug_guid = { 0xadd3ac74, 0xb1a7, 0x4d04, { 0xba, 0xdb, 0x6b, 0xeb, 0x7d, 0x13, 0x26, 0x69 } }; | |
4004 | -class config_page_mixi_debug : public preferences_page_v2 | |
4005 | -#endif | |
4006 | -{ | |
4007 | - static BOOL CALLBACK ConfigProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp) | |
4008 | - { | |
4009 | - switch(msg) | |
4010 | - { | |
4011 | - case WM_INITDIALOG: | |
4012 | - { | |
4013 | - uSetDlgItemText(wnd, IDC_CAPTION_DEBUG, g_debugSettingsCaption8); | |
4014 | - | |
4015 | - bool bDebugLogEnabled = (cfg_enable_debug_log == 1) ? true : false; | |
4016 | - uButton_SetCheck(wnd, IDC_ENABLE_DEBUG_LOG, bDebugLogEnabled); | |
4017 | - | |
4018 | - InitDebugLevelList(wnd, IDC_DEBUG_DUMMYAMP_INIT); | |
4019 | - InitDebugLevelList(wnd, IDC_DEBUG_DUMMYAMP_PROC); | |
4020 | - InitDebugLevelList(wnd, IDC_DEBUG_TRACK_INFO); | |
4021 | - InitDebugLevelList(wnd, IDC_DEBUG_PLUGIN); | |
4022 | - InitDebugLevelList(wnd, IDC_DEBUG_CALLBACK); | |
4023 | - | |
4024 | - EnableDebugLevelLists(wnd, bDebugLogEnabled); | |
4025 | - | |
4026 | - uSendDlgItemMessage(wnd, IDC_DEBUG_DUMMYAMP_INIT, CB_SETCURSEL, (int)cfg_debug_dummyamp_init, 0); | |
4027 | - uSendDlgItemMessage(wnd, IDC_DEBUG_DUMMYAMP_PROC, CB_SETCURSEL, (int)cfg_debug_dummyamp_proc, 0); | |
4028 | - uSendDlgItemMessage(wnd, IDC_DEBUG_TRACK_INFO, CB_SETCURSEL, (int)cfg_debug_track_info, 0); | |
4029 | - uSendDlgItemMessage(wnd, IDC_DEBUG_PLUGIN, CB_SETCURSEL, (int)cfg_debug_plugin, 0); | |
4030 | - uSendDlgItemMessage(wnd, IDC_DEBUG_CALLBACK, CB_SETCURSEL, (int)cfg_debug_callback, 0); | |
4031 | - | |
4032 | - uSetDlgItemText(wnd, IDC_VERSION_DEBUG, PLUGIN_CAPTION " " PLUGIN_VERSION); | |
4033 | - uSetDlgItemText(wnd, IDC_BUILD_DEBUG, "build on " __DATE__ ", " __TIME__); | |
4034 | - } | |
4035 | - break; | |
4036 | - | |
4037 | - case WM_COMMAND: | |
4038 | - switch(wp) | |
4039 | - { | |
4040 | - case (BN_CLICKED<<16)|IDC_ENABLE_DEBUG_LOG: | |
4041 | - { | |
4042 | - bool bDebugLogEnabled = uButton_GetCheck(wnd, IDC_ENABLE_DEBUG_LOG); | |
4043 | - cfg_enable_debug_log = bDebugLogEnabled ? 1 : 0; | |
4044 | - | |
4045 | - EnableDebugLevelLists(wnd, bDebugLogEnabled); | |
4046 | - } | |
4047 | - break; | |
4048 | - | |
4049 | - case (CBN_SELCHANGE<<16)|IDC_DEBUG_DUMMYAMP_INIT: | |
4050 | - { | |
4051 | - int sel = static_cast<int>(uSendMessage(reinterpret_cast<HWND>(lp), CB_GETCURSEL, 0, 0)); | |
4052 | - cfg_debug_dummyamp_init = sel; | |
4053 | - } | |
4054 | - break; | |
4055 | - | |
4056 | - case (CBN_SELCHANGE<<16)|IDC_DEBUG_DUMMYAMP_PROC: | |
4057 | - { | |
4058 | - int sel = static_cast<int>(uSendMessage(reinterpret_cast<HWND>(lp), CB_GETCURSEL, 0, 0)); | |
4059 | - cfg_debug_dummyamp_proc = sel; | |
4060 | - } | |
4061 | - break; | |
4062 | - | |
4063 | - case (CBN_SELCHANGE<<16)|IDC_DEBUG_TRACK_INFO: | |
4064 | - { | |
4065 | - int sel = static_cast<int>(uSendMessage(reinterpret_cast<HWND>(lp), CB_GETCURSEL, 0, 0)); | |
4066 | - cfg_debug_track_info = sel; | |
4067 | - } | |
4068 | - break; | |
4069 | - | |
4070 | - case (CBN_SELCHANGE<<16)|IDC_DEBUG_PLUGIN: | |
4071 | - { | |
4072 | - int sel = static_cast<int>(uSendMessage(reinterpret_cast<HWND>(lp), CB_GETCURSEL, 0, 0)); | |
4073 | - cfg_debug_plugin = sel; | |
4074 | - } | |
4075 | - break; | |
4076 | - | |
4077 | - case (CBN_SELCHANGE<<16)|IDC_DEBUG_CALLBACK: | |
4078 | - { | |
4079 | - int sel = static_cast<int>(uSendMessage(reinterpret_cast<HWND>(lp), CB_GETCURSEL, 0, 0)); | |
4080 | - cfg_debug_callback = sel; | |
4081 | - } | |
4082 | - break; | |
4083 | - | |
4084 | - default: | |
4085 | - break; | |
4086 | - } | |
4087 | - break; | |
4088 | - | |
4089 | - case WM_DESTROY: | |
4090 | - break; | |
4091 | - } | |
4092 | - | |
4093 | - return 0; | |
4094 | - } | |
4095 | - | |
4096 | -protected: | |
4097 | - | |
4098 | - static void InitDebugLevelList(HWND wnd, UINT id) { | |
4099 | - uSendDlgItemMessage(wnd, id, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("なし"))); | |
4100 | - uSendDlgItemMessage(wnd, id, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("簡易レベル"))); | |
4101 | - uSendDlgItemMessage(wnd, id, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(_T("詳細レベル"))); | |
4102 | - } | |
4103 | - | |
4104 | - static void EnableDebugLevelLists(HWND wnd, bool bDebugLogEnabled) { | |
4105 | - EnableDebugLevelList(wnd, IDC_DEBUG_DUMMYAMP_INIT, bDebugLogEnabled); | |
4106 | - EnableDebugLevelList(wnd, IDC_DEBUG_DUMMYAMP_PROC, bDebugLogEnabled); | |
4107 | - EnableDebugLevelList(wnd, IDC_DEBUG_TRACK_INFO, bDebugLogEnabled); | |
4108 | - EnableDebugLevelList(wnd, IDC_DEBUG_PLUGIN, bDebugLogEnabled); | |
4109 | - EnableDebugLevelList(wnd, IDC_DEBUG_CALLBACK, bDebugLogEnabled); | |
4110 | - } | |
4111 | - | |
4112 | - static void EnableDebugLevelList(HWND wnd, UINT id, bool bEnable) { | |
4113 | - HWND hControlWnd = uGetDlgItem(wnd, id); | |
4114 | - uEnableWindow(hControlWnd, bEnable); | |
4115 | - } | |
4116 | - | |
4117 | -public: | |
4118 | - | |
4119 | - virtual HWND create(HWND parent) | |
4120 | - { | |
4121 | - return uCreateDialog(IDD_DEBUG_SETTINGS, parent, ConfigProc); | |
4122 | - } | |
4123 | - | |
4124 | - virtual const char * get_name() { | |
4125 | - return g_debugSettingsCaption8; | |
4126 | - } | |
4127 | - virtual const char * get_parent_name() { | |
4128 | - return g_pluginCaption8; | |
4129 | - } | |
4130 | - | |
4131 | -#if IS_FB2K_VER09 | |
4132 | - virtual GUID get_guid() { | |
4133 | - return config_page_mixi_debug_guid; | |
4134 | - } | |
4135 | - | |
4136 | - virtual GUID get_parent_guid() { | |
4137 | - return config_page_mixi_guid; | |
4138 | - } | |
4139 | - | |
4140 | - virtual bool reset_query() { | |
4141 | - return true; | |
4142 | - } | |
4143 | - | |
4144 | - virtual double get_sort_priority() { | |
4145 | - return 2.0; | |
4146 | - } | |
4147 | - | |
4148 | - virtual void reset() { | |
4149 | - cfg_enable_debug_log = 1; | |
4150 | - cfg_debug_dummyamp_init = 1; | |
4151 | - cfg_debug_dummyamp_proc = 1; | |
4152 | - cfg_debug_track_info = 1; | |
4153 | - cfg_debug_plugin = 1; | |
4154 | - cfg_debug_callback = 1; | |
4155 | - } | |
4156 | - | |
4157 | - virtual bool get_help_url(pfc::string_base & p_out) { | |
4158 | - p_out = URL_FOO_MIXI_HOME; | |
4159 | - return true; | |
4160 | - } | |
4161 | -#endif | |
4162 | -}; | |
4163 | - | |
4164 | -#if IS_FB2K_VER08 | |
4165 | -static service_factory_single_t<play_callback, play_callback_mixi> foo1; | |
4166 | -static service_factory_single_t<initquit, initquit_mixi> foo2; | |
4167 | -static menu_item_factory<menu_item_mixi> foo3; | |
4168 | -static service_factory_single_t<config, config_page_mixi> foo4; | |
4169 | -static service_factory_single_t<config, config_page_mixi_advanced> foo5; | |
4170 | -static service_factory_single_t<config, config_page_mixi_debug> foo6; | |
4171 | -#elif IS_FB2K_VER09 | |
4172 | -static service_factory_single_t<play_callback_mixi> foo1; | |
4173 | -static initquit_factory_t<initquit_mixi> foo2; | |
4174 | -static mainmenu_commands_factory_t<menu_item_mixi> foo3; | |
4175 | -static preferences_page_factory_t<config_page_mixi> foo4; | |
4176 | -static preferences_page_factory_t<config_page_mixi_advanced> foo5; | |
4177 | -static preferences_page_factory_t<config_page_mixi_debug> foo6; | |
4178 | -#endif | |
4179 | - | |
4180 | -tstring GetErrorMessage(DWORD errCode) | |
4181 | -{ | |
4182 | - | |
4183 | - LPVOID lpMsgBuf; | |
4184 | - | |
4185 | - FormatMessage( | |
4186 | - FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
4187 | - FORMAT_MESSAGE_FROM_SYSTEM | | |
4188 | - FORMAT_MESSAGE_IGNORE_INSERTS, | |
4189 | - NULL, | |
4190 | - errCode, | |
4191 | - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // デフォルト言語 | |
4192 | - (LPTSTR) &lpMsgBuf, | |
4193 | - 0, | |
4194 | - NULL | |
4195 | - ); | |
4196 | - | |
4197 | - tstring msg = (LPCTSTR)lpMsgBuf; | |
4198 | - | |
4199 | - GlobalFree(lpMsgBuf); | |
4200 | - | |
4201 | - return msg; | |
4202 | -} | |
4203 | - | |
4204 | -void putLogError(LPCTSTR pMethod, LPCTSTR pErrMsg, DWORD dwErrCode) | |
4205 | -{ | |
4206 | - tstring errMsg = GetErrorMessage(dwErrCode); | |
4207 | - | |
4208 | - LOG_ERROR(_T("%s - %s"), pMethod, pErrMsg); | |
4209 | - LOG_ERROR(_T("%s - コード: %08x, 理由: %s"), pMethod, dwErrCode, errMsg.c_str()); | |
4210 | -} | |
4211 | - | |
4212 | -void DebugPrint(int severity, LPCTSTR lpszFormat, ...) | |
4213 | -{ | |
4214 | - static Str64K buf; | |
4215 | - va_list marker; | |
4216 | - | |
4217 | - va_start(marker, lpszFormat); | |
4218 | - _vstprintf_s(buf, sizeof(Str64K), lpszFormat, marker); | |
4219 | - va_end(marker); | |
4220 | - | |
4221 | - OutputDebugString(buf); | |
4222 | - OutputDebugString(_T("\n")); | |
4223 | - | |
4224 | - string_utf8_from_os tmp(buf); | |
4225 | - | |
4226 | -#if IS_FB2K_VER08 | |
4227 | - console::output(severity, tmp); | |
4228 | -#else | |
4229 | - switch(severity) | |
4230 | - { | |
4231 | - case console::SEVERITY_INFO: | |
4232 | - console::info(tmp); | |
4233 | - break; | |
4234 | - case console::SEVERITY_WARNING: | |
4235 | - console::warning(tmp); | |
4236 | - break; | |
4237 | - case console::SEVERITY_CRITICAL: | |
4238 | - console::error(tmp); | |
4239 | - break; | |
4240 | - } | |
4241 | -#endif | |
4242 | -} | |
4243 | - | |
4244 | -void DebugPrint8(int severity, LPCSTR lpszFormat, ...) | |
4245 | -{ | |
4246 | - static StrDBCS64K buf; | |
4247 | - | |
4248 | - va_list marker; | |
4249 | - | |
4250 | - va_start(marker, lpszFormat); | |
4251 | - vsprintf_s(buf, sizeof(StrDBCS64K), lpszFormat, marker); | |
4252 | - va_end(marker); | |
4253 | - | |
4254 | -#if IS_FB2K_VER08 | |
4255 | - console::output(severity, buf); | |
4256 | -#else | |
4257 | - switch(severity) | |
4258 | - { | |
4259 | - case console::SEVERITY_INFO: | |
4260 | - console::info(buf); | |
4261 | - break; | |
4262 | - case console::SEVERITY_WARNING: | |
4263 | - console::warning(buf); | |
4264 | - break; | |
4265 | - case console::SEVERITY_CRITICAL: | |
4266 | - console::error(buf); | |
4267 | - break; | |
4268 | - } | |
4269 | -#endif | |
4270 | - | |
4271 | - string_os_from_utf8 tmp(buf); | |
4272 | - | |
4273 | - OutputDebugString(tmp); | |
4274 | - OutputDebugString(_T("\n")); | |
4275 | -} | |
4276 | - | |
4277 | -#if defined(BUILD_UNICODE) | |
4278 | -void DebugPrintDBCS(int severity, LPCSTR lpszFormat, ...) | |
4279 | -{ | |
4280 | - static StrDBCS64K buf; | |
4281 | - va_list marker; | |
4282 | - | |
4283 | - va_start(marker, lpszFormat); | |
4284 | - vsprintf_s(buf, sizeof(StrDBCS64K), lpszFormat, marker); | |
4285 | - va_end(marker); | |
4286 | - | |
4287 | - string_wide_from_ansi tmp(buf); | |
4288 | - | |
4289 | - OutputDebugString(tmp); | |
4290 | - OutputDebugString(L"\n"); | |
4291 | - | |
4292 | -#if IS_FB2K_VER08 | |
4293 | - console::output(severity, buf); | |
4294 | -#else | |
4295 | - switch(severity) | |
4296 | - { | |
4297 | - case console::SEVERITY_INFO: | |
4298 | - console::info(buf); | |
4299 | - break; | |
4300 | - case console::SEVERITY_WARNING: | |
4301 | - console::warning(buf); | |
4302 | - break; | |
4303 | - case console::SEVERITY_CRITICAL: | |
4304 | - console::error(buf); | |
4305 | - break; | |
4306 | - } | |
4307 | -#endif | |
4308 | -} | |
4309 | -#endif | |
\ No newline at end of file |
@@ -1,674 +0,0 @@ | ||
1 | - GNU GENERAL PUBLIC LICENSE | |
2 | - Version 3, 29 June 2007 | |
3 | - | |
4 | - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> | |
5 | - Everyone is permitted to copy and distribute verbatim copies | |
6 | - of this license document, but changing it is not allowed. | |
7 | - | |
8 | - Preamble | |
9 | - | |
10 | - The GNU General Public License is a free, copyleft license for | |
11 | -software and other kinds of works. | |
12 | - | |
13 | - The licenses for most software and other practical works are designed | |
14 | -to take away your freedom to share and change the works. By contrast, | |
15 | -the GNU General Public License is intended to guarantee your freedom to | |
16 | -share and change all versions of a program--to make sure it remains free | |
17 | -software for all its users. We, the Free Software Foundation, use the | |
18 | -GNU General Public License for most of our software; it applies also to | |
19 | -any other work released this way by its authors. You can apply it to | |
20 | -your programs, too. | |
21 | - | |
22 | - When we speak of free software, we are referring to freedom, not | |
23 | -price. Our General Public Licenses are designed to make sure that you | |
24 | -have the freedom to distribute copies of free software (and charge for | |
25 | -them if you wish), that you receive source code or can get it if you | |
26 | -want it, that you can change the software or use pieces of it in new | |
27 | -free programs, and that you know you can do these things. | |
28 | - | |
29 | - To protect your rights, we need to prevent others from denying you | |
30 | -these rights or asking you to surrender the rights. Therefore, you have | |
31 | -certain responsibilities if you distribute copies of the software, or if | |
32 | -you modify it: responsibilities to respect the freedom of others. | |
33 | - | |
34 | - For example, if you distribute copies of such a program, whether | |
35 | -gratis or for a fee, you must pass on to the recipients the same | |
36 | -freedoms that you received. You must make sure that they, too, receive | |
37 | -or can get the source code. And you must show them these terms so they | |
38 | -know their rights. | |
39 | - | |
40 | - Developers that use the GNU GPL protect your rights with two steps: | |
41 | -(1) assert copyright on the software, and (2) offer you this License | |
42 | -giving you legal permission to copy, distribute and/or modify it. | |
43 | - | |
44 | - For the developers' and authors' protection, the GPL clearly explains | |
45 | -that there is no warranty for this free software. For both users' and | |
46 | -authors' sake, the GPL requires that modified versions be marked as | |
47 | -changed, so that their problems will not be attributed erroneously to | |
48 | -authors of previous versions. | |
49 | - | |
50 | - Some devices are designed to deny users access to install or run | |
51 | -modified versions of the software inside them, although the manufacturer | |
52 | -can do so. This is fundamentally incompatible with the aim of | |
53 | -protecting users' freedom to change the software. The systematic | |
54 | -pattern of such abuse occurs in the area of products for individuals to | |
55 | -use, which is precisely where it is most unacceptable. Therefore, we | |
56 | -have designed this version of the GPL to prohibit the practice for those | |
57 | -products. If such problems arise substantially in other domains, we | |
58 | -stand ready to extend this provision to those domains in future versions | |
59 | -of the GPL, as needed to protect the freedom of users. | |
60 | - | |
61 | - Finally, every program is threatened constantly by software patents. | |
62 | -States should not allow patents to restrict development and use of | |
63 | -software on general-purpose computers, but in those that do, we wish to | |
64 | -avoid the special danger that patents applied to a free program could | |
65 | -make it effectively proprietary. To prevent this, the GPL assures that | |
66 | -patents cannot be used to render the program non-free. | |
67 | - | |
68 | - The precise terms and conditions for copying, distribution and | |
69 | -modification follow. | |
70 | - | |
71 | - TERMS AND CONDITIONS | |
72 | - | |
73 | - 0. Definitions. | |
74 | - | |
75 | - "This License" refers to version 3 of the GNU General Public License. | |
76 | - | |
77 | - "Copyright" also means copyright-like laws that apply to other kinds of | |
78 | -works, such as semiconductor masks. | |
79 | - | |
80 | - "The Program" refers to any copyrightable work licensed under this | |
81 | -License. Each licensee is addressed as "you". "Licensees" and | |
82 | -"recipients" may be individuals or organizations. | |
83 | - | |
84 | - To "modify" a work means to copy from or adapt all or part of the work | |
85 | -in a fashion requiring copyright permission, other than the making of an | |
86 | -exact copy. The resulting work is called a "modified version" of the | |
87 | -earlier work or a work "based on" the earlier work. | |
88 | - | |
89 | - A "covered work" means either the unmodified Program or a work based | |
90 | -on the Program. | |
91 | - | |
92 | - To "propagate" a work means to do anything with it that, without | |
93 | -permission, would make you directly or secondarily liable for | |
94 | -infringement under applicable copyright law, except executing it on a | |
95 | -computer or modifying a private copy. Propagation includes copying, | |
96 | -distribution (with or without modification), making available to the | |
97 | -public, and in some countries other activities as well. | |
98 | - | |
99 | - To "convey" a work means any kind of propagation that enables other | |
100 | -parties to make or receive copies. Mere interaction with a user through | |
101 | -a computer network, with no transfer of a copy, is not conveying. | |
102 | - | |
103 | - An interactive user interface displays "Appropriate Legal Notices" | |
104 | -to the extent that it includes a convenient and prominently visible | |
105 | -feature that (1) displays an appropriate copyright notice, and (2) | |
106 | -tells the user that there is no warranty for the work (except to the | |
107 | -extent that warranties are provided), that licensees may convey the | |
108 | -work under this License, and how to view a copy of this License. If | |
109 | -the interface presents a list of user commands or options, such as a | |
110 | -menu, a prominent item in the list meets this criterion. | |
111 | - | |
112 | - 1. Source Code. | |
113 | - | |
114 | - The "source code" for a work means the preferred form of the work | |
115 | -for making modifications to it. "Object code" means any non-source | |
116 | -form of a work. | |
117 | - | |
118 | - A "Standard Interface" means an interface that either is an official | |
119 | -standard defined by a recognized standards body, or, in the case of | |
120 | -interfaces specified for a particular programming language, one that | |
121 | -is widely used among developers working in that language. | |
122 | - | |
123 | - The "System Libraries" of an executable work include anything, other | |
124 | -than the work as a whole, that (a) is included in the normal form of | |
125 | -packaging a Major Component, but which is not part of that Major | |
126 | -Component, and (b) serves only to enable use of the work with that | |
127 | -Major Component, or to implement a Standard Interface for which an | |
128 | -implementation is available to the public in source code form. A | |
129 | -"Major Component", in this context, means a major essential component | |
130 | -(kernel, window system, and so on) of the specific operating system | |
131 | -(if any) on which the executable work runs, or a compiler used to | |
132 | -produce the work, or an object code interpreter used to run it. | |
133 | - | |
134 | - The "Corresponding Source" for a work in object code form means all | |
135 | -the source code needed to generate, install, and (for an executable | |
136 | -work) run the object code and to modify the work, including scripts to | |
137 | -control those activities. However, it does not include the work's | |
138 | -System Libraries, or general-purpose tools or generally available free | |
139 | -programs which are used unmodified in performing those activities but | |
140 | -which are not part of the work. For example, Corresponding Source | |
141 | -includes interface definition files associated with source files for | |
142 | -the work, and the source code for shared libraries and dynamically | |
143 | -linked subprograms that the work is specifically designed to require, | |
144 | -such as by intimate data communication or control flow between those | |
145 | -subprograms and other parts of the work. | |
146 | - | |
147 | - The Corresponding Source need not include anything that users | |
148 | -can regenerate automatically from other parts of the Corresponding | |
149 | -Source. | |
150 | - | |
151 | - The Corresponding Source for a work in source code form is that | |
152 | -same work. | |
153 | - | |
154 | - 2. Basic Permissions. | |
155 | - | |
156 | - All rights granted under this License are granted for the term of | |
157 | -copyright on the Program, and are irrevocable provided the stated | |
158 | -conditions are met. This License explicitly affirms your unlimited | |
159 | -permission to run the unmodified Program. The output from running a | |
160 | -covered work is covered by this License only if the output, given its | |
161 | -content, constitutes a covered work. This License acknowledges your | |
162 | -rights of fair use or other equivalent, as provided by copyright law. | |
163 | - | |
164 | - You may make, run and propagate covered works that you do not | |
165 | -convey, without conditions so long as your license otherwise remains | |
166 | -in force. You may convey covered works to others for the sole purpose | |
167 | -of having them make modifications exclusively for you, or provide you | |
168 | -with facilities for running those works, provided that you comply with | |
169 | -the terms of this License in conveying all material for which you do | |
170 | -not control copyright. Those thus making or running the covered works | |
171 | -for you must do so exclusively on your behalf, under your direction | |
172 | -and control, on terms that prohibit them from making any copies of | |
173 | -your copyrighted material outside their relationship with you. | |
174 | - | |
175 | - Conveying under any other circumstances is permitted solely under | |
176 | -the conditions stated below. Sublicensing is not allowed; section 10 | |
177 | -makes it unnecessary. | |
178 | - | |
179 | - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. | |
180 | - | |
181 | - No covered work shall be deemed part of an effective technological | |
182 | -measure under any applicable law fulfilling obligations under article | |
183 | -11 of the WIPO copyright treaty adopted on 20 December 1996, or | |
184 | -similar laws prohibiting or restricting circumvention of such | |
185 | -measures. | |
186 | - | |
187 | - When you convey a covered work, you waive any legal power to forbid | |
188 | -circumvention of technological measures to the extent such circumvention | |
189 | -is effected by exercising rights under this License with respect to | |
190 | -the covered work, and you disclaim any intention to limit operation or | |
191 | -modification of the work as a means of enforcing, against the work's | |
192 | -users, your or third parties' legal rights to forbid circumvention of | |
193 | -technological measures. | |
194 | - | |
195 | - 4. Conveying Verbatim Copies. | |
196 | - | |
197 | - You may convey verbatim copies of the Program's source code as you | |
198 | -receive it, in any medium, provided that you conspicuously and | |
199 | -appropriately publish on each copy an appropriate copyright notice; | |
200 | -keep intact all notices stating that this License and any | |
201 | -non-permissive terms added in accord with section 7 apply to the code; | |
202 | -keep intact all notices of the absence of any warranty; and give all | |
203 | -recipients a copy of this License along with the Program. | |
204 | - | |
205 | - You may charge any price or no price for each copy that you convey, | |
206 | -and you may offer support or warranty protection for a fee. | |
207 | - | |
208 | - 5. Conveying Modified Source Versions. | |
209 | - | |
210 | - You may convey a work based on the Program, or the modifications to | |
211 | -produce it from the Program, in the form of source code under the | |
212 | -terms of section 4, provided that you also meet all of these conditions: | |
213 | - | |
214 | - a) The work must carry prominent notices stating that you modified | |
215 | - it, and giving a relevant date. | |
216 | - | |
217 | - b) The work must carry prominent notices stating that it is | |
218 | - released under this License and any conditions added under section | |
219 | - 7. This requirement modifies the requirement in section 4 to | |
220 | - "keep intact all notices". | |
221 | - | |
222 | - c) You must license the entire work, as a whole, under this | |
223 | - License to anyone who comes into possession of a copy. This | |
224 | - License will therefore apply, along with any applicable section 7 | |
225 | - additional terms, to the whole of the work, and all its parts, | |
226 | - regardless of how they are packaged. This License gives no | |
227 | - permission to license the work in any other way, but it does not | |
228 | - invalidate such permission if you have separately received it. | |
229 | - | |
230 | - d) If the work has interactive user interfaces, each must display | |
231 | - Appropriate Legal Notices; however, if the Program has interactive | |
232 | - interfaces that do not display Appropriate Legal Notices, your | |
233 | - work need not make them do so. | |
234 | - | |
235 | - A compilation of a covered work with other separate and independent | |
236 | -works, which are not by their nature extensions of the covered work, | |
237 | -and which are not combined with it such as to form a larger program, | |
238 | -in or on a volume of a storage or distribution medium, is called an | |
239 | -"aggregate" if the compilation and its resulting copyright are not | |
240 | -used to limit the access or legal rights of the compilation's users | |
241 | -beyond what the individual works permit. Inclusion of a covered work | |
242 | -in an aggregate does not cause this License to apply to the other | |
243 | -parts of the aggregate. | |
244 | - | |
245 | - 6. Conveying Non-Source Forms. | |
246 | - | |
247 | - You may convey a covered work in object code form under the terms | |
248 | -of sections 4 and 5, provided that you also convey the | |
249 | -machine-readable Corresponding Source under the terms of this License, | |
250 | -in one of these ways: | |
251 | - | |
252 | - a) Convey the object code in, or embodied in, a physical product | |
253 | - (including a physical distribution medium), accompanied by the | |
254 | - Corresponding Source fixed on a durable physical medium | |
255 | - customarily used for software interchange. | |
256 | - | |
257 | - b) Convey the object code in, or embodied in, a physical product | |
258 | - (including a physical distribution medium), accompanied by a | |
259 | - written offer, valid for at least three years and valid for as | |
260 | - long as you offer spare parts or customer support for that product | |
261 | - model, to give anyone who possesses the object code either (1) a | |
262 | - copy of the Corresponding Source for all the software in the | |
263 | - product that is covered by this License, on a durable physical | |
264 | - medium customarily used for software interchange, for a price no | |
265 | - more than your reasonable cost of physically performing this | |
266 | - conveying of source, or (2) access to copy the | |
267 | - Corresponding Source from a network server at no charge. | |
268 | - | |
269 | - c) Convey individual copies of the object code with a copy of the | |
270 | - written offer to provide the Corresponding Source. This | |
271 | - alternative is allowed only occasionally and noncommercially, and | |
272 | - only if you received the object code with such an offer, in accord | |
273 | - with subsection 6b. | |
274 | - | |
275 | - d) Convey the object code by offering access from a designated | |
276 | - place (gratis or for a charge), and offer equivalent access to the | |
277 | - Corresponding Source in the same way through the same place at no | |
278 | - further charge. You need not require recipients to copy the | |
279 | - Corresponding Source along with the object code. If the place to | |
280 | - copy the object code is a network server, the Corresponding Source | |
281 | - may be on a different server (operated by you or a third party) | |
282 | - that supports equivalent copying facilities, provided you maintain | |
283 | - clear directions next to the object code saying where to find the | |
284 | - Corresponding Source. Regardless of what server hosts the | |
285 | - Corresponding Source, you remain obligated to ensure that it is | |
286 | - available for as long as needed to satisfy these requirements. | |
287 | - | |
288 | - e) Convey the object code using peer-to-peer transmission, provided | |
289 | - you inform other peers where the object code and Corresponding | |
290 | - Source of the work are being offered to the general public at no | |
291 | - charge under subsection 6d. | |
292 | - | |
293 | - A separable portion of the object code, whose source code is excluded | |
294 | -from the Corresponding Source as a System Library, need not be | |
295 | -included in conveying the object code work. | |
296 | - | |
297 | - A "User Product" is either (1) a "consumer product", which means any | |
298 | -tangible personal property which is normally used for personal, family, | |
299 | -or household purposes, or (2) anything designed or sold for incorporation | |
300 | -into a dwelling. In determining whether a product is a consumer product, | |
301 | -doubtful cases shall be resolved in favor of coverage. For a particular | |
302 | -product received by a particular user, "normally used" refers to a | |
303 | -typical or common use of that class of product, regardless of the status | |
304 | -of the particular user or of the way in which the particular user | |
305 | -actually uses, or expects or is expected to use, the product. A product | |
306 | -is a consumer product regardless of whether the product has substantial | |
307 | -commercial, industrial or non-consumer uses, unless such uses represent | |
308 | -the only significant mode of use of the product. | |
309 | - | |
310 | - "Installation Information" for a User Product means any methods, | |
311 | -procedures, authorization keys, or other information required to install | |
312 | -and execute modified versions of a covered work in that User Product from | |
313 | -a modified version of its Corresponding Source. The information must | |
314 | -suffice to ensure that the continued functioning of the modified object | |
315 | -code is in no case prevented or interfered with solely because | |
316 | -modification has been made. | |
317 | - | |
318 | - If you convey an object code work under this section in, or with, or | |
319 | -specifically for use in, a User Product, and the conveying occurs as | |
320 | -part of a transaction in which the right of possession and use of the | |
321 | -User Product is transferred to the recipient in perpetuity or for a | |
322 | -fixed term (regardless of how the transaction is characterized), the | |
323 | -Corresponding Source conveyed under this section must be accompanied | |
324 | -by the Installation Information. But this requirement does not apply | |
325 | -if neither you nor any third party retains the ability to install | |
326 | -modified object code on the User Product (for example, the work has | |
327 | -been installed in ROM). | |
328 | - | |
329 | - The requirement to provide Installation Information does not include a | |
330 | -requirement to continue to provide support service, warranty, or updates | |
331 | -for a work that has been modified or installed by the recipient, or for | |
332 | -the User Product in which it has been modified or installed. Access to a | |
333 | -network may be denied when the modification itself materially and | |
334 | -adversely affects the operation of the network or violates the rules and | |
335 | -protocols for communication across the network. | |
336 | - | |
337 | - Corresponding Source conveyed, and Installation Information provided, | |
338 | -in accord with this section must be in a format that is publicly | |
339 | -documented (and with an implementation available to the public in | |
340 | -source code form), and must require no special password or key for | |
341 | -unpacking, reading or copying. | |
342 | - | |
343 | - 7. Additional Terms. | |
344 | - | |
345 | - "Additional permissions" are terms that supplement the terms of this | |
346 | -License by making exceptions from one or more of its conditions. | |
347 | -Additional permissions that are applicable to the entire Program shall | |
348 | -be treated as though they were included in this License, to the extent | |
349 | -that they are valid under applicable law. If additional permissions | |
350 | -apply only to part of the Program, that part may be used separately | |
351 | -under those permissions, but the entire Program remains governed by | |
352 | -this License without regard to the additional permissions. | |
353 | - | |
354 | - When you convey a copy of a covered work, you may at your option | |
355 | -remove any additional permissions from that copy, or from any part of | |
356 | -it. (Additional permissions may be written to require their own | |
357 | -removal in certain cases when you modify the work.) You may place | |
358 | -additional permissions on material, added by you to a covered work, | |
359 | -for which you have or can give appropriate copyright permission. | |
360 | - | |
361 | - Notwithstanding any other provision of this License, for material you | |
362 | -add to a covered work, you may (if authorized by the copyright holders of | |
363 | -that material) supplement the terms of this License with terms: | |
364 | - | |
365 | - a) Disclaiming warranty or limiting liability differently from the | |
366 | - terms of sections 15 and 16 of this License; or | |
367 | - | |
368 | - b) Requiring preservation of specified reasonable legal notices or | |
369 | - author attributions in that material or in the Appropriate Legal | |
370 | - Notices displayed by works containing it; or | |
371 | - | |
372 | - c) Prohibiting misrepresentation of the origin of that material, or | |
373 | - requiring that modified versions of such material be marked in | |
374 | - reasonable ways as different from the original version; or | |
375 | - | |
376 | - d) Limiting the use for publicity purposes of names of licensors or | |
377 | - authors of the material; or | |
378 | - | |
379 | - e) Declining to grant rights under trademark law for use of some | |
380 | - trade names, trademarks, or service marks; or | |
381 | - | |
382 | - f) Requiring indemnification of licensors and authors of that | |
383 | - material by anyone who conveys the material (or modified versions of | |
384 | - it) with contractual assumptions of liability to the recipient, for | |
385 | - any liability that these contractual assumptions directly impose on | |
386 | - those licensors and authors. | |
387 | - | |
388 | - All other non-permissive additional terms are considered "further | |
389 | -restrictions" within the meaning of section 10. If the Program as you | |
390 | -received it, or any part of it, contains a notice stating that it is | |
391 | -governed by this License along with a term that is a further | |
392 | -restriction, you may remove that term. If a license document contains | |
393 | -a further restriction but permits relicensing or conveying under this | |
394 | -License, you may add to a covered work material governed by the terms | |
395 | -of that license document, provided that the further restriction does | |
396 | -not survive such relicensing or conveying. | |
397 | - | |
398 | - If you add terms to a covered work in accord with this section, you | |
399 | -must place, in the relevant source files, a statement of the | |
400 | -additional terms that apply to those files, or a notice indicating | |
401 | -where to find the applicable terms. | |
402 | - | |
403 | - Additional terms, permissive or non-permissive, may be stated in the | |
404 | -form of a separately written license, or stated as exceptions; | |
405 | -the above requirements apply either way. | |
406 | - | |
407 | - 8. Termination. | |
408 | - | |
409 | - You may not propagate or modify a covered work except as expressly | |
410 | -provided under this License. Any attempt otherwise to propagate or | |
411 | -modify it is void, and will automatically terminate your rights under | |
412 | -this License (including any patent licenses granted under the third | |
413 | -paragraph of section 11). | |
414 | - | |
415 | - However, if you cease all violation of this License, then your | |
416 | -license from a particular copyright holder is reinstated (a) | |
417 | -provisionally, unless and until the copyright holder explicitly and | |
418 | -finally terminates your license, and (b) permanently, if the copyright | |
419 | -holder fails to notify you of the violation by some reasonable means | |
420 | -prior to 60 days after the cessation. | |
421 | - | |
422 | - Moreover, your license from a particular copyright holder is | |
423 | -reinstated permanently if the copyright holder notifies you of the | |
424 | -violation by some reasonable means, this is the first time you have | |
425 | -received notice of violation of this License (for any work) from that | |
426 | -copyright holder, and you cure the violation prior to 30 days after | |
427 | -your receipt of the notice. | |
428 | - | |
429 | - Termination of your rights under this section does not terminate the | |
430 | -licenses of parties who have received copies or rights from you under | |
431 | -this License. If your rights have been terminated and not permanently | |
432 | -reinstated, you do not qualify to receive new licenses for the same | |
433 | -material under section 10. | |
434 | - | |
435 | - 9. Acceptance Not Required for Having Copies. | |
436 | - | |
437 | - You are not required to accept this License in order to receive or | |
438 | -run a copy of the Program. Ancillary propagation of a covered work | |
439 | -occurring solely as a consequence of using peer-to-peer transmission | |
440 | -to receive a copy likewise does not require acceptance. However, | |
441 | -nothing other than this License grants you permission to propagate or | |
442 | -modify any covered work. These actions infringe copyright if you do | |
443 | -not accept this License. Therefore, by modifying or propagating a | |
444 | -covered work, you indicate your acceptance of this License to do so. | |
445 | - | |
446 | - 10. Automatic Licensing of Downstream Recipients. | |
447 | - | |
448 | - Each time you convey a covered work, the recipient automatically | |
449 | -receives a license from the original licensors, to run, modify and | |
450 | -propagate that work, subject to this License. You are not responsible | |
451 | -for enforcing compliance by third parties with this License. | |
452 | - | |
453 | - An "entity transaction" is a transaction transferring control of an | |
454 | -organization, or substantially all assets of one, or subdividing an | |
455 | -organization, or merging organizations. If propagation of a covered | |
456 | -work results from an entity transaction, each party to that | |
457 | -transaction who receives a copy of the work also receives whatever | |
458 | -licenses to the work the party's predecessor in interest had or could | |
459 | -give under the previous paragraph, plus a right to possession of the | |
460 | -Corresponding Source of the work from the predecessor in interest, if | |
461 | -the predecessor has it or can get it with reasonable efforts. | |
462 | - | |
463 | - You may not impose any further restrictions on the exercise of the | |
464 | -rights granted or affirmed under this License. For example, you may | |
465 | -not impose a license fee, royalty, or other charge for exercise of | |
466 | -rights granted under this License, and you may not initiate litigation | |
467 | -(including a cross-claim or counterclaim in a lawsuit) alleging that | |
468 | -any patent claim is infringed by making, using, selling, offering for | |
469 | -sale, or importing the Program or any portion of it. | |
470 | - | |
471 | - 11. Patents. | |
472 | - | |
473 | - A "contributor" is a copyright holder who authorizes use under this | |
474 | -License of the Program or a work on which the Program is based. The | |
475 | -work thus licensed is called the contributor's "contributor version". | |
476 | - | |
477 | - A contributor's "essential patent claims" are all patent claims | |
478 | -owned or controlled by the contributor, whether already acquired or | |
479 | -hereafter acquired, that would be infringed by some manner, permitted | |
480 | -by this License, of making, using, or selling its contributor version, | |
481 | -but do not include claims that would be infringed only as a | |
482 | -consequence of further modification of the contributor version. For | |
483 | -purposes of this definition, "control" includes the right to grant | |
484 | -patent sublicenses in a manner consistent with the requirements of | |
485 | -this License. | |
486 | - | |
487 | - Each contributor grants you a non-exclusive, worldwide, royalty-free | |
488 | -patent license under the contributor's essential patent claims, to | |
489 | -make, use, sell, offer for sale, import and otherwise run, modify and | |
490 | -propagate the contents of its contributor version. | |
491 | - | |
492 | - In the following three paragraphs, a "patent license" is any express | |
493 | -agreement or commitment, however denominated, not to enforce a patent | |
494 | -(such as an express permission to practice a patent or covenant not to | |
495 | -sue for patent infringement). To "grant" such a patent license to a | |
496 | -party means to make such an agreement or commitment not to enforce a | |
497 | -patent against the party. | |
498 | - | |
499 | - If you convey a covered work, knowingly relying on a patent license, | |
500 | -and the Corresponding Source of the work is not available for anyone | |
501 | -to copy, free of charge and under the terms of this License, through a | |
502 | -publicly available network server or other readily accessible means, | |
503 | -then you must either (1) cause the Corresponding Source to be so | |
504 | -available, or (2) arrange to deprive yourself of the benefit of the | |
505 | -patent license for this particular work, or (3) arrange, in a manner | |
506 | -consistent with the requirements of this License, to extend the patent | |
507 | -license to downstream recipients. "Knowingly relying" means you have | |
508 | -actual knowledge that, but for the patent license, your conveying the | |
509 | -covered work in a country, or your recipient's use of the covered work | |
510 | -in a country, would infringe one or more identifiable patents in that | |
511 | -country that you have reason to believe are valid. | |
512 | - | |
513 | - If, pursuant to or in connection with a single transaction or | |
514 | -arrangement, you convey, or propagate by procuring conveyance of, a | |
515 | -covered work, and grant a patent license to some of the parties | |
516 | -receiving the covered work authorizing them to use, propagate, modify | |
517 | -or convey a specific copy of the covered work, then the patent license | |
518 | -you grant is automatically extended to all recipients of the covered | |
519 | -work and works based on it. | |
520 | - | |
521 | - A patent license is "discriminatory" if it does not include within | |
522 | -the scope of its coverage, prohibits the exercise of, or is | |
523 | -conditioned on the non-exercise of one or more of the rights that are | |
524 | -specifically granted under this License. You may not convey a covered | |
525 | -work if you are a party to an arrangement with a third party that is | |
526 | -in the business of distributing software, under which you make payment | |
527 | -to the third party based on the extent of your activity of conveying | |
528 | -the work, and under which the third party grants, to any of the | |
529 | -parties who would receive the covered work from you, a discriminatory | |
530 | -patent license (a) in connection with copies of the covered work | |
531 | -conveyed by you (or copies made from those copies), or (b) primarily | |
532 | -for and in connection with specific products or compilations that | |
533 | -contain the covered work, unless you entered into that arrangement, | |
534 | -or that patent license was granted, prior to 28 March 2007. | |
535 | - | |
536 | - Nothing in this License shall be construed as excluding or limiting | |
537 | -any implied license or other defenses to infringement that may | |
538 | -otherwise be available to you under applicable patent law. | |
539 | - | |
540 | - 12. No Surrender of Others' Freedom. | |
541 | - | |
542 | - If conditions are imposed on you (whether by court order, agreement or | |
543 | -otherwise) that contradict the conditions of this License, they do not | |
544 | -excuse you from the conditions of this License. If you cannot convey a | |
545 | -covered work so as to satisfy simultaneously your obligations under this | |
546 | -License and any other pertinent obligations, then as a consequence you may | |
547 | -not convey it at all. For example, if you agree to terms that obligate you | |
548 | -to collect a royalty for further conveying from those to whom you convey | |
549 | -the Program, the only way you could satisfy both those terms and this | |
550 | -License would be to refrain entirely from conveying the Program. | |
551 | - | |
552 | - 13. Use with the GNU Affero General Public License. | |
553 | - | |
554 | - Notwithstanding any other provision of this License, you have | |
555 | -permission to link or combine any covered work with a work licensed | |
556 | -under version 3 of the GNU Affero General Public License into a single | |
557 | -combined work, and to convey the resulting work. The terms of this | |
558 | -License will continue to apply to the part which is the covered work, | |
559 | -but the special requirements of the GNU Affero General Public License, | |
560 | -section 13, concerning interaction through a network will apply to the | |
561 | -combination as such. | |
562 | - | |
563 | - 14. Revised Versions of this License. | |
564 | - | |
565 | - The Free Software Foundation may publish revised and/or new versions of | |
566 | -the GNU General Public License from time to time. Such new versions will | |
567 | -be similar in spirit to the present version, but may differ in detail to | |
568 | -address new problems or concerns. | |
569 | - | |
570 | - Each version is given a distinguishing version number. If the | |
571 | -Program specifies that a certain numbered version of the GNU General | |
572 | -Public License "or any later version" applies to it, you have the | |
573 | -option of following the terms and conditions either of that numbered | |
574 | -version or of any later version published by the Free Software | |
575 | -Foundation. If the Program does not specify a version number of the | |
576 | -GNU General Public License, you may choose any version ever published | |
577 | -by the Free Software Foundation. | |
578 | - | |
579 | - If the Program specifies that a proxy can decide which future | |
580 | -versions of the GNU General Public License can be used, that proxy's | |
581 | -public statement of acceptance of a version permanently authorizes you | |
582 | -to choose that version for the Program. | |
583 | - | |
584 | - Later license versions may give you additional or different | |
585 | -permissions. However, no additional obligations are imposed on any | |
586 | -author or copyright holder as a result of your choosing to follow a | |
587 | -later version. | |
588 | - | |
589 | - 15. Disclaimer of Warranty. | |
590 | - | |
591 | - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY | |
592 | -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT | |
593 | -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY | |
594 | -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, | |
595 | -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
596 | -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM | |
597 | -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF | |
598 | -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | |
599 | - | |
600 | - 16. Limitation of Liability. | |
601 | - | |
602 | - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |
603 | -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS | |
604 | -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY | |
605 | -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE | |
606 | -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF | |
607 | -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD | |
608 | -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), | |
609 | -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF | |
610 | -SUCH DAMAGES. | |
611 | - | |
612 | - 17. Interpretation of Sections 15 and 16. | |
613 | - | |
614 | - If the disclaimer of warranty and limitation of liability provided | |
615 | -above cannot be given local legal effect according to their terms, | |
616 | -reviewing courts shall apply local law that most closely approximates | |
617 | -an absolute waiver of all civil liability in connection with the | |
618 | -Program, unless a warranty or assumption of liability accompanies a | |
619 | -copy of the Program in return for a fee. | |
620 | - | |
621 | - END OF TERMS AND CONDITIONS | |
622 | - | |
623 | - How to Apply These Terms to Your New Programs | |
624 | - | |
625 | - If you develop a new program, and you want it to be of the greatest | |
626 | -possible use to the public, the best way to achieve this is to make it | |
627 | -free software which everyone can redistribute and change under these terms. | |
628 | - | |
629 | - To do so, attach the following notices to the program. It is safest | |
630 | -to attach them to the start of each source file to most effectively | |
631 | -state the exclusion of warranty; and each file should have at least | |
632 | -the "copyright" line and a pointer to where the full notice is found. | |
633 | - | |
634 | - <one line to give the program's name and a brief idea of what it does.> | |
635 | - Copyright (C) <year> <name of author> | |
636 | - | |
637 | - This program is free software: you can redistribute it and/or modify | |
638 | - it under the terms of the GNU General Public License as published by | |
639 | - the Free Software Foundation, either version 3 of the License, or | |
640 | - (at your option) any later version. | |
641 | - | |
642 | - This program is distributed in the hope that it will be useful, | |
643 | - but WITHOUT ANY WARRANTY; without even the implied warranty of | |
644 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
645 | - GNU General Public License for more details. | |
646 | - | |
647 | - You should have received a copy of the GNU General Public License | |
648 | - along with this program. If not, see <http://www.gnu.org/licenses/>. | |
649 | - | |
650 | -Also add information on how to contact you by electronic and paper mail. | |
651 | - | |
652 | - If the program does terminal interaction, make it output a short | |
653 | -notice like this when it starts in an interactive mode: | |
654 | - | |
655 | - <program> Copyright (C) <year> <name of author> | |
656 | - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |
657 | - This is free software, and you are welcome to redistribute it | |
658 | - under certain conditions; type `show c' for details. | |
659 | - | |
660 | -The hypothetical commands `show w' and `show c' should show the appropriate | |
661 | -parts of the General Public License. Of course, your program's commands | |
662 | -might be different; for a GUI interface, you would use an "about box". | |
663 | - | |
664 | - You should also get your employer (if you work as a programmer) or school, | |
665 | -if any, to sign a "copyright disclaimer" for the program, if necessary. | |
666 | -For more information on this, and how to apply and follow the GNU GPL, see | |
667 | -<http://www.gnu.org/licenses/>. | |
668 | - | |
669 | - The GNU General Public License does not permit incorporating your program | |
670 | -into proprietary programs. If your program is a subroutine library, you | |
671 | -may consider it more useful to permit linking proprietary applications with | |
672 | -the library. If this is what you want to do, use the GNU Lesser General | |
673 | -Public License instead of this License. But first, please read | |
674 | -<http://www.gnu.org/philosophy/why-not-lgpl.html>. |
@@ -1,1022 +0,0 @@ | ||
1 | -/* | |
2 | -** Copyright (C) 2003 Nullsoft, Inc. | |
3 | -** | |
4 | -** This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held | |
5 | -** liable for any damages arising from the use of this software. | |
6 | -** | |
7 | -** Permission is granted to anyone to use this software for any purpose, including commercial applications, and to | |
8 | -** alter it and redistribute it freely, subject to the following restrictions: | |
9 | -** | |
10 | -** 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. | |
11 | -** If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. | |
12 | -** | |
13 | -** 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | |
14 | -** | |
15 | -** 3. This notice may not be removed or altered from any source distribution. | |
16 | -** | |
17 | -*/ | |
18 | - | |
19 | -#ifndef _WA_IPC_H_ | |
20 | -#define _WA_IPC_H_ | |
21 | - | |
22 | -/* | |
23 | -** This is the modern replacement for the classic 'frontend.h'. Most of these | |
24 | -** updates are designed for in-process use, i.e. from a plugin. | |
25 | -** | |
26 | -*/ | |
27 | - | |
28 | -/* message used to sent many messages to winamp's main window. | |
29 | -** most all of the IPC_* messages involve sending the message in the form of: | |
30 | -** result = SendMessage(hwnd_winamp,WM_WA_IPC,(parameter),IPC_*); | |
31 | -*/ | |
32 | -#define WM_WA_IPC WM_USER | |
33 | -/* but some of them use WM_COPYDATA. be afraid. | |
34 | -*/ | |
35 | - | |
36 | -#define IPC_GETVERSION 0 | |
37 | -/* int version = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVERSION); | |
38 | -** | |
39 | -** Version will be 0x20yx for winamp 2.yx. versions previous to Winamp 2.0 | |
40 | -** typically (but not always) use 0x1zyx for 1.zx versions. Weird, I know. | |
41 | -*/ | |
42 | - | |
43 | -#define IPC_GETREGISTEREDVERSION 770 | |
44 | - | |
45 | - | |
46 | -typedef struct { | |
47 | - char *filename; | |
48 | - char *title; | |
49 | - int length; | |
50 | -} enqueueFileWithMetaStruct; // send this to a IPC_PLAYFILE in a non WM_COPYDATA, | |
51 | -// and you get the nice desired result. if title is NULL, it is treated as a "thing", | |
52 | -// otherwise it's assumed to be a file (for speed) | |
53 | - | |
54 | -#define IPC_PLAYFILE 100 // dont be fooled, this is really the same as enqueufile | |
55 | -#define IPC_ENQUEUEFILE 100 | |
56 | -/* sent as a WM_COPYDATA, with IPC_PLAYFILE as the dwData, and the string to play | |
57 | -** as the lpData. Just enqueues, does not clear the playlist or change the playback | |
58 | -** state. | |
59 | -*/ | |
60 | - | |
61 | - | |
62 | -#define IPC_DELETE 101 | |
63 | -#define IPC_DELETE_INT 1101 // don't use this, it's used internally by winamp when | |
64 | - // dealing with some lame explorer issues. | |
65 | -/* SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_DELETE); | |
66 | -** Use IPC_DELETE to clear Winamp's internal playlist. | |
67 | -*/ | |
68 | - | |
69 | - | |
70 | -#define IPC_STARTPLAY 102 // starts playback. almost like hitting play in Winamp. | |
71 | -#define IPC_STARTPLAY_INT 1102 // used internally, don't bother using it (won't be any fun) | |
72 | - | |
73 | - | |
74 | -#define IPC_CHDIR 103 | |
75 | -/* sent as a WM_COPYDATA, with IPC_CHDIR as the dwData, and the directory to change to | |
76 | -** as the lpData. | |
77 | -*/ | |
78 | - | |
79 | - | |
80 | -#define IPC_ISPLAYING 104 | |
81 | -/* int res = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING); | |
82 | -** If it returns 1, it is playing. if it returns 3, it is paused, | |
83 | -** if it returns 0, it is not playing. | |
84 | -*/ | |
85 | - | |
86 | - | |
87 | -#define IPC_GETOUTPUTTIME 105 | |
88 | -/* int res = SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETOUTPUTTIME); | |
89 | -** returns the position in milliseconds of the current track (mode = 0), | |
90 | -** or the track length, in seconds (mode = 1). Returns -1 if not playing or error. | |
91 | -*/ | |
92 | - | |
93 | - | |
94 | -#define IPC_JUMPTOTIME 106 | |
95 | -/* (requires Winamp 1.60+) | |
96 | -** SendMessage(hwnd_winamp,WM_WA_IPC,ms,IPC_JUMPTOTIME); | |
97 | -** IPC_JUMPTOTIME sets the position in milliseconds of the | |
98 | -** current song (approximately). | |
99 | -** Returns -1 if not playing, 1 on eof, or 0 if successful | |
100 | -*/ | |
101 | - | |
102 | -#define IPC_GETMODULENAME 109 | |
103 | -#define IPC_EX_ISRIGHTEXE 666 | |
104 | -/* usually shouldnt bother using these, but here goes: | |
105 | -** send a WM_COPYDATA with IPC_GETMODULENAME, and an internal | |
106 | -** flag gets set, which if you send a normal WM_WA_IPC message with | |
107 | -** IPC_EX_ISRIGHTEXE, it returns whether or not that filename | |
108 | -** matches. lame, I know. | |
109 | -*/ | |
110 | - | |
111 | -#define IPC_WRITEPLAYLIST 120 | |
112 | -/* (requires Winamp 1.666+) | |
113 | -** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_WRITEPLAYLIST); | |
114 | -** | |
115 | -** IPC_WRITEPLAYLIST writes the current playlist to <winampdir>\\Winamp.m3u, | |
116 | -** and returns the current playlist position. | |
117 | -** Kinda obsoleted by some of the 2.x new stuff, but still good for when | |
118 | -** using a front-end (instead of a plug-in) | |
119 | -*/ | |
120 | - | |
121 | - | |
122 | -#define IPC_SETPLAYLISTPOS 121 | |
123 | -/* (requires Winamp 2.0+) | |
124 | -** SendMessage(hwnd_winamp,WM_WA_IPC,position,IPC_SETPLAYLISTPOS) | |
125 | -** IPC_SETPLAYLISTPOS sets the playlist position to 'position'. It | |
126 | -** does not change playback or anything, it just sets position, and | |
127 | -** updates the view if necessary | |
128 | -*/ | |
129 | - | |
130 | - | |
131 | -#define IPC_SETVOLUME 122 | |
132 | -/* (requires Winamp 2.0+) | |
133 | -** SendMessage(hwnd_winamp,WM_WA_IPC,volume,IPC_SETVOLUME); | |
134 | -** IPC_SETVOLUME sets the volume of Winamp (from 0-255). | |
135 | -*/ | |
136 | - | |
137 | - | |
138 | -#define IPC_SETPANNING 123 | |
139 | -/* (requires Winamp 2.0+) | |
140 | -** SendMessage(hwnd_winamp,WM_WA_IPC,panning,IPC_SETPANNING); | |
141 | -** IPC_SETPANNING sets the panning of Winamp (from 0 (left) to 255 (right)). | |
142 | -*/ | |
143 | - | |
144 | - | |
145 | -#define IPC_GETLISTLENGTH 124 | |
146 | -/* (requires Winamp 2.0+) | |
147 | -** int length = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTLENGTH); | |
148 | -** IPC_GETLISTLENGTH returns the length of the current playlist, in | |
149 | -** tracks. | |
150 | -*/ | |
151 | - | |
152 | - | |
153 | -#define IPC_GETLISTPOS 125 | |
154 | -/* (requires Winamp 2.05+) | |
155 | -** int pos=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS); | |
156 | -** IPC_GETLISTPOS returns the playlist position. A lot like IPC_WRITEPLAYLIST | |
157 | -** only faster since it doesn't have to write out the list. Heh, silly me. | |
158 | -*/ | |
159 | - | |
160 | - | |
161 | -#define IPC_GETINFO 126 | |
162 | -/* (requires Winamp 2.05+) | |
163 | -** int inf=SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETINFO); | |
164 | -** IPC_GETINFO returns info about the current playing song. The value | |
165 | -** it returns depends on the value of 'mode'. | |
166 | -** Mode Meaning | |
167 | -** ------------------ | |
168 | -** 0 Samplerate (i.e. 44100) | |
169 | -** 1 Bitrate (i.e. 128) | |
170 | -** 2 Channels (i.e. 2) | |
171 | -** 3 (5+) Video LOWORD=w HIWORD=h | |
172 | -** 4 (5+) > 65536, string (video description) | |
173 | -*/ | |
174 | - | |
175 | - | |
176 | -#define IPC_GETEQDATA 127 | |
177 | -/* (requires Winamp 2.05+) | |
178 | -** int data=SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA); | |
179 | -** IPC_GETEQDATA queries the status of the EQ. | |
180 | -** The value returned depends on what 'pos' is set to: | |
181 | -** Value Meaning | |
182 | -** ------------------ | |
183 | -** 0-9 The 10 bands of EQ data. 0-63 (+20db - -20db) | |
184 | -** 10 The preamp value. 0-63 (+20db - -20db) | |
185 | -** 11 Enabled. zero if disabled, nonzero if enabled. | |
186 | -** 12 Autoload. zero if disabled, nonzero if enabled. | |
187 | -*/ | |
188 | - | |
189 | - | |
190 | -#define IPC_SETEQDATA 128 | |
191 | -/* (requires Winamp 2.05+) | |
192 | -** SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA); | |
193 | -** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SETEQDATA); | |
194 | -** IPC_SETEQDATA sets the value of the last position retrieved | |
195 | -** by IPC_GETEQDATA. This is pretty lame, and we should provide | |
196 | -** an extended version that lets you do a MAKELPARAM(pos,value). | |
197 | -** someday... | |
198 | - | |
199 | - new (2.92+): | |
200 | - if the high byte is set to 0xDB, then the third byte specifies | |
201 | - which band, and the bottom word specifies the value. | |
202 | -*/ | |
203 | - | |
204 | -#define IPC_ADDBOOKMARK 129 | |
205 | -/* (requires Winamp 2.4+) | |
206 | -** Sent as a WM_COPYDATA, using IPC_ADDBOOKMARK, adds the specified | |
207 | -** file/url to the Winamp bookmark list. | |
208 | -*/ | |
209 | -/* | |
210 | -In winamp 5+, we use this as a normal WM_WA_IPC and the string: | |
211 | - | |
212 | - "filename\0title\0" | |
213 | - | |
214 | - to notify the library/bookmark editor that a bookmark | |
215 | -was added. Note that using this message in this context does not | |
216 | -actually add the bookmark. | |
217 | -do not use :) | |
218 | -*/ | |
219 | - | |
220 | - | |
221 | -#define IPC_INSTALLPLUGIN 130 | |
222 | -/* not implemented, but if it was you could do a WM_COPYDATA with | |
223 | -** a path to a .wpz, and it would install it. | |
224 | -*/ | |
225 | - | |
226 | - | |
227 | -#define IPC_RESTARTWINAMP 135 | |
228 | -/* (requires Winamp 2.2+) | |
229 | -** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_RESTARTWINAMP); | |
230 | -** IPC_RESTARTWINAMP will restart Winamp (isn't that obvious ? :) | |
231 | -*/ | |
232 | - | |
233 | - | |
234 | -#define IPC_ISFULLSTOP 400 | |
235 | -/* (requires winamp 2.7+ I think) | |
236 | -** ret=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISFULLSTOP); | |
237 | -** useful for when you're an output plugin, and you want to see | |
238 | -** if the stop/close is a full stop, or just between tracks. | |
239 | -** returns nonzero if it's full, zero if it's just a new track. | |
240 | -*/ | |
241 | - | |
242 | - | |
243 | -#define IPC_INETAVAILABLE 242 | |
244 | -/* (requires Winamp 2.05+) | |
245 | -** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_INETAVAILABLE); | |
246 | -** IPC_INETAVAILABLE will return 1 if the Internet connection is available for Winamp. | |
247 | -*/ | |
248 | - | |
249 | - | |
250 | -#define IPC_UPDTITLE 243 | |
251 | -/* (requires Winamp 2.2+) | |
252 | -** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_UPDTITLE); | |
253 | -** IPC_UPDTITLE will ask Winamp to update the informations about the current title. | |
254 | -*/ | |
255 | - | |
256 | - | |
257 | -#define IPC_REFRESHPLCACHE 247 | |
258 | -/* (requires Winamp 2.2+) | |
259 | -** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_REFRESHPLCACHE); | |
260 | -** IPC_REFRESHPLCACHE will flush the playlist cache buffer. | |
261 | -** (send this if you want it to go refetch titles for tracks) | |
262 | -*/ | |
263 | - | |
264 | - | |
265 | -#define IPC_GET_SHUFFLE 250 | |
266 | -/* (requires Winamp 2.4+) | |
267 | -** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_SHUFFLE); | |
268 | -** | |
269 | -** IPC_GET_SHUFFLE returns the status of the Shuffle option (1 if set) | |
270 | -*/ | |
271 | - | |
272 | - | |
273 | -#define IPC_GET_REPEAT 251 | |
274 | -/* (requires Winamp 2.4+) | |
275 | -** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_REPEAT); | |
276 | -** | |
277 | -** IPC_GET_REPEAT returns the status of the Repeat option (1 if set) | |
278 | -*/ | |
279 | - | |
280 | - | |
281 | -#define IPC_SET_SHUFFLE 252 | |
282 | -/* (requires Winamp 2.4+) | |
283 | -** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_SHUFFLE); | |
284 | -** | |
285 | -** IPC_SET_SHUFFLE sets the status of the Shuffle option (1 to turn it on) | |
286 | -*/ | |
287 | - | |
288 | - | |
289 | -#define IPC_SET_REPEAT 253 | |
290 | -/* (requires Winamp 2.4+) | |
291 | -** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_REPEAT); | |
292 | -** | |
293 | -** IPC_SET_REPEAT sets the status of the Repeat option (1 to turn it on) | |
294 | -*/ | |
295 | - | |
296 | - | |
297 | -#define IPC_ENABLEDISABLE_ALL_WINDOWS 259 // 0xdeadbeef to disable | |
298 | -/* (requires Winamp 2.9+) | |
299 | -** SendMessage(hwnd_winamp,WM_WA_IPC,enable?0:0xdeadbeef,IPC_MBOPENREAL); | |
300 | -** sending with 0xdeadbeef as the param disables all winamp windows, | |
301 | -** any other values will enable all winamp windows. | |
302 | -*/ | |
303 | - | |
304 | - | |
305 | -#define IPC_GETWND 260 | |
306 | -/* (requires Winamp 2.9+) | |
307 | -** HWND h=SendMessage(hwnd_winamp,WM_WA_IPC,IPC_GETWND_xxx,IPC_GETWND); | |
308 | -** returns the HWND of the window specified. | |
309 | -*/ | |
310 | - #define IPC_GETWND_EQ 0 // use one of these for the param | |
311 | - #define IPC_GETWND_PE 1 | |
312 | - #define IPC_GETWND_MB 2 | |
313 | - #define IPC_GETWND_VIDEO 3 | |
314 | -#define IPC_ISWNDVISIBLE 261 // same param as IPC_GETWND | |
315 | - | |
316 | - | |
317 | - | |
318 | - | |
319 | -/************************************************************************ | |
320 | -***************** in-process only (WE LOVE PLUGINS) | |
321 | -************************************************************************/ | |
322 | - | |
323 | - | |
324 | -#define IPC_SETSKIN 200 | |
325 | -/* (requires Winamp 2.04+, only usable from plug-ins (not external apps)) | |
326 | -** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"skinname",IPC_SETSKIN); | |
327 | -** IPC_SETSKIN sets the current skin to "skinname". Note that skinname | |
328 | -** can be the name of a skin, a skin .zip file, with or without path. | |
329 | -** If path isn't specified, the default search path is the winamp skins | |
330 | -** directory. | |
331 | -*/ | |
332 | - | |
333 | - | |
334 | -#define IPC_GETSKIN 201 | |
335 | -/* (requires Winamp 2.04+, only usable from plug-ins (not external apps)) | |
336 | -** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)skinname_buffer,IPC_GETSKIN); | |
337 | -** IPC_GETSKIN puts the directory where skin bitmaps can be found | |
338 | -** into skinname_buffer. | |
339 | -** skinname_buffer must be MAX_PATH characters in length. | |
340 | -** When using a .zip'd skin file, it'll return a temporary directory | |
341 | -** where the ZIP was decompressed. | |
342 | -*/ | |
343 | - | |
344 | - | |
345 | -#define IPC_EXECPLUG 202 | |
346 | -/* (requires Winamp 2.04+, only usable from plug-ins (not external apps)) | |
347 | -** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"vis_file.dll",IPC_EXECPLUG); | |
348 | -** IPC_EXECPLUG executes a visualization plug-in pointed to by WPARAM. | |
349 | -** the format of this string can be: | |
350 | -** "vis_whatever.dll" | |
351 | -** "vis_whatever.dll,0" // (first mod, file in winamp plug-in dir) | |
352 | -** "C:\\dir\\vis_whatever.dll,1" | |
353 | -*/ | |
354 | - | |
355 | - | |
356 | -#define IPC_GETPLAYLISTFILE 211 | |
357 | -/* (requires Winamp 2.04+, only usable from plug-ins (not external apps)) | |
358 | -** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE); | |
359 | -** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index]. | |
360 | -** returns a pointer to it. returns NULL on error. | |
361 | -*/ | |
362 | - | |
363 | - | |
364 | -#define IPC_GETPLAYLISTTITLE 212 | |
365 | -/* (requires Winamp 2.04+, only usable from plug-ins (not external apps)) | |
366 | -** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTTITLE); | |
367 | -** | |
368 | -** IPC_GETPLAYLISTTITLE gets the title of the playlist entry [index]. | |
369 | -** returns a pointer to it. returns NULL on error. | |
370 | -*/ | |
371 | - | |
372 | - | |
373 | -#define IPC_GETHTTPGETTER 240 | |
374 | -/* retrieves a function pointer to a HTTP retrieval function. | |
375 | -** if this is unsupported, returns 1 or 0. | |
376 | -** the function should be: | |
377 | -** int (*httpRetrieveFile)(HWND hwnd, char *url, char *file, char *dlgtitle); | |
378 | -** if you call this function, with a parent window, a URL, an output file, and a dialog title, | |
379 | -** it will return 0 on successful download, 1 on error. | |
380 | -*/ | |
381 | - | |
382 | - | |
383 | -#define IPC_MBOPEN 241 | |
384 | -/* (requires Winamp 2.05+) | |
385 | -** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_MBOPEN); | |
386 | -** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)url,IPC_MBOPEN); | |
387 | -** IPC_MBOPEN will open a new URL in the minibrowser. if url is NULL, it will open the Minibrowser window. | |
388 | -*/ | |
389 | - | |
390 | - | |
391 | - | |
392 | -#define IPC_CHANGECURRENTFILE 245 | |
393 | -/* (requires Winamp 2.05+) | |
394 | -** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)file,IPC_CHANGECURRENTFILE); | |
395 | -** IPC_CHANGECURRENTFILE will set the current playlist item. | |
396 | -*/ | |
397 | - | |
398 | - | |
399 | -#define IPC_GETMBURL 246 | |
400 | -/* (requires Winamp 2.2+) | |
401 | -** char buffer[4096]; // Urls can be VERY long | |
402 | -** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)buffer,IPC_GETMBURL); | |
403 | -** IPC_GETMBURL will retrieve the current Minibrowser URL into buffer. | |
404 | -** buffer must be at least 4096 bytes long. | |
405 | -*/ | |
406 | - | |
407 | - | |
408 | -#define IPC_MBBLOCK 248 | |
409 | -/* (requires Winamp 2.4+) | |
410 | -** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_MBBLOCK); | |
411 | -** | |
412 | -** IPC_MBBLOCK will block the Minibrowser from updates if value is set to 1 | |
413 | -*/ | |
414 | - | |
415 | -#define IPC_MBOPENREAL 249 | |
416 | -/* (requires Winamp 2.4+) | |
417 | -** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)url,IPC_MBOPENREAL); | |
418 | -** | |
419 | -** IPC_MBOPENREAL works the same as IPC_MBOPEN except that it will works even if | |
420 | -** IPC_MBBLOCK has been set to 1 | |
421 | -*/ | |
422 | - | |
423 | -#define IPC_ADJUST_OPTIONSMENUPOS 280 | |
424 | -/* (requires Winamp 2.9+) | |
425 | -** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_OPTIONSMENUPOS); | |
426 | -** moves where winamp expects the Options menu in the main menu. Useful if you wish to insert a | |
427 | -** menu item above the options/skins/vis menus. | |
428 | -*/ | |
429 | - | |
430 | -#define IPC_GET_HMENU 281 | |
431 | -/* (requires Winamp 2.9+) | |
432 | -** HMENU hMenu=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)0,IPC_GET_HMENU); | |
433 | -** values for data: | |
434 | -** 0 : main popup menu | |
435 | -** 1 : main menubar file menu | |
436 | -** 2 : main menubar options menu | |
437 | -** 3 : main menubar windows menu | |
438 | -** 4 : main menubar help menu | |
439 | -** other values will return NULL. | |
440 | -*/ | |
441 | - | |
442 | -#define IPC_GET_EXTENDED_FILE_INFO 290 //pass a pointer to the following struct in wParam | |
443 | -#define IPC_GET_EXTENDED_FILE_INFO_HOOKABLE 296 | |
444 | -/* (requires Winamp 2.9+) | |
445 | -** to use, create an extendedFileInfoStruct, point the values filename and metadata to the | |
446 | -** filename and metadata field you wish to query, and ret to a buffer, with retlen to the | |
447 | -** length of that buffer, and then SendMessage(hwnd_winamp,WM_WA_IPC,&struct,IPC_GET_EXTENDED_FILE_INFO); | |
448 | -** the results should be in the buffer pointed to by ret. | |
449 | -** returns 1 if the decoder supports a getExtendedFileInfo method | |
450 | -*/ | |
451 | -typedef struct { | |
452 | - char *filename; | |
453 | - char *metadata; | |
454 | - char *ret; | |
455 | - int retlen; | |
456 | -} extendedFileInfoStruct; | |
457 | - | |
458 | -#define IPC_GET_BASIC_FILE_INFO 291 //pass a pointer to the following struct in wParam | |
459 | -typedef struct { | |
460 | - char *filename; | |
461 | - | |
462 | - int quickCheck; // set to 0 to always get, 1 for quick, 2 for default (if 2, quickCheck will be set to 0 if quick wasnot used) | |
463 | - | |
464 | - // filled in by winamp | |
465 | - int length; | |
466 | - char *title; | |
467 | - int titlelen; | |
468 | -} basicFileInfoStruct; | |
469 | - | |
470 | -#define IPC_GET_EXTLIST 292 //returns doublenull delimited. GlobalFree() it when done. if data is 0, returns raw extlist, if 1, returns something suitable for getopenfilename | |
471 | - | |
472 | -#define IPC_INFOBOX 293 | |
473 | -typedef struct { | |
474 | - HWND parent; | |
475 | - char *filename; | |
476 | -} infoBoxParam; | |
477 | - | |
478 | -#define IPC_SET_EXTENDED_FILE_INFO 294 //pass a pointer to the a extendedFileInfoStruct in wParam | |
479 | -/* (requires Winamp 2.9+) | |
480 | -** to use, create an extendedFileInfoStruct, point the values filename and metadata to the | |
481 | -** filename and metadata field you wish to write in ret. (retlen is not used). and then | |
482 | -** SendMessage(hwnd_winamp,WM_WA_IPC,&struct,IPC_SET_EXTENDED_FILE_INFO); | |
483 | -** returns 1 if the metadata is supported | |
484 | -** Call IPC_WRITE_EXTENDED_FILE_INFO once you're done setting all the metadata you want to update | |
485 | -*/ | |
486 | - | |
487 | -#define IPC_WRITE_EXTENDED_FILE_INFO 295 | |
488 | -/* (requires Winamp 2.9+) | |
489 | -** writes all the metadata set thru IPC_SET_EXTENDED_FILE_INFO to the file | |
490 | -** returns 1 if the file has been successfully updated, 0 if error | |
491 | -*/ | |
492 | - | |
493 | -#define IPC_FORMAT_TITLE 297 | |
494 | -typedef struct | |
495 | -{ | |
496 | - char *spec; // NULL=default winamp spec | |
497 | - void *p; | |
498 | - | |
499 | - char *out; | |
500 | - int out_len; | |
501 | - | |
502 | - char * (*TAGFUNC)(char * tag, void * p); //return 0 if not found | |
503 | - void (*TAGFREEFUNC)(char * tag,void * p); | |
504 | -} waFormatTitle; | |
505 | - | |
506 | -#define IPC_GETUNCOMPRESSINTERFACE 331 | |
507 | -/* returns a function pointer to uncompress(). | |
508 | -** int (*uncompress)(unsigned char *dest, unsigned long *destLen, const unsigned char *source, unsigned long sourceLen); | |
509 | -** right out of zlib, useful for decompressing zlibbed data. | |
510 | -** if you pass the parm of 0x10100000, it will return a wa_inflate_struct * to an inflate API. | |
511 | -*/ | |
512 | - | |
513 | -typedef struct { | |
514 | - int (*inflateReset)(void *strm); | |
515 | - int (*inflateInit_)(void *strm,const char *version, int stream_size); | |
516 | - int (*inflate)(void *strm, int flush); | |
517 | - int (*inflateEnd)(void *strm); | |
518 | - unsigned long (*crc32)(unsigned long crc, const unsigned char *buf, unsigned int len); | |
519 | -} wa_inflate_struct; | |
520 | - | |
521 | - | |
522 | -#define IPC_ADD_PREFS_DLG 332 | |
523 | -#define IPC_REMOVE_PREFS_DLG 333 | |
524 | -/* (requires Winamp 2.9+) | |
525 | -** to use, allocate a prefsDlgRec structure (either on the heap or some global | |
526 | -** data, but NOT on the stack), initialze the members: | |
527 | -** hInst to the DLL instance where the resource is located | |
528 | -** dlgID to the ID of the dialog, | |
529 | -** proc to the window procedure for the dialog | |
530 | -** name to the name of the prefs page in the prefs. | |
531 | -** where to 0 (eventually we may add more options) | |
532 | -** then, SendMessage(hwnd_winamp,WM_WA_IPC,&prefsRec,IPC_ADD_PREFS_DLG); | |
533 | -** | |
534 | -** you can also IPC_REMOVE_PREFS_DLG with the address of the same prefsRec, | |
535 | -** but you shouldn't really ever have to. | |
536 | -** | |
537 | -*/ | |
538 | -#define IPC_OPENPREFSTOPAGE 380 // pass an id of a builtin page, or a &prefsDlgRec of prefs page to open | |
539 | - | |
540 | -typedef struct _prefsDlgRec { | |
541 | - HINSTANCE hInst; | |
542 | - int dlgID; | |
543 | - void *proc; | |
544 | - | |
545 | - char *name; | |
546 | - int where; // 0 for options, 1 for plugins, 2 for skins, 3 for bookmarks, 4 for prefs | |
547 | - | |
548 | - | |
549 | - int _id; | |
550 | - struct _prefsDlgRec *next; | |
551 | -} prefsDlgRec; | |
552 | - | |
553 | - | |
554 | -#define IPC_GETINIFILE 334 // returns a pointer to winamp.ini | |
555 | -#define IPC_GETINIDIRECTORY 335 // returns a pointer to the directory to put config files in (if you dont want to use winamp.ini) | |
556 | - | |
557 | -#define IPC_SPAWNBUTTONPOPUP 361 // param = | |
558 | -// 0 = eject | |
559 | -// 1 = previous | |
560 | -// 2 = next | |
561 | -// 3 = pause | |
562 | -// 4 = play | |
563 | -// 5 = stop | |
564 | - | |
565 | -#define IPC_OPENURLBOX 360 // pass a HWND to a parent, returns a HGLOBAL that needs to be freed with GlobalFree(), if successful | |
566 | -#define IPC_OPENFILEBOX 362 // pass a HWND to a parent | |
567 | -#define IPC_OPENDIRBOX 363 // pass a HWND to a parent | |
568 | - | |
569 | -// pass an HWND to a parent. call this if you take over the whole UI so that the dialogs are not appearing on the | |
570 | -// bottom right of the screen since the main winamp window is at 3000x3000, call again with NULL to reset | |
571 | -#define IPC_SETDIALOGBOXPARENT 364 | |
572 | - | |
573 | - | |
574 | - | |
575 | -// pass 0 for a copy of the skin HBITMAP | |
576 | -// pass 1 for name of font to use for playlist editor likeness | |
577 | -// pass 2 for font charset | |
578 | -// pass 3 for font size | |
579 | -#define IPC_GET_GENSKINBITMAP 503 | |
580 | - | |
581 | - | |
582 | -#define IPC_GET_EMBEDIF 505 // pass an embedWindowState | |
583 | -// returns an HWND embedWindow(embedWindowState *); if the data is NULL, otherwise returns the HWND directly | |
584 | -typedef struct | |
585 | -{ | |
586 | - HWND me; //hwnd of the window | |
587 | - | |
588 | - int flags; | |
589 | - | |
590 | - RECT r; | |
591 | - | |
592 | - void *user_ptr; // for application use | |
593 | - | |
594 | - int extra_data[64]; // for internal winamp use | |
595 | -} embedWindowState; | |
596 | - | |
597 | -#define EMBED_FLAGS_NORESIZE 1 // set this bit in embedWindowState.flags to keep window from being resizable | |
598 | -#define EMBED_FLAGS_NOTRANSPARENCY 2 // set this bit in embedWindowState.flags to make gen_ff turn transparency off for this wnd | |
599 | - | |
600 | - | |
601 | -#define IPC_EMBED_ENUM 532 | |
602 | -typedef struct embedEnumStruct | |
603 | -{ | |
604 | - int (*enumProc)(embedWindowState *ws, struct embedEnumStruct *param); // return 1 to abort | |
605 | - int user_data; // or more :) | |
606 | -} embedEnumStruct; | |
607 | - // pass | |
608 | - | |
609 | -#define IPC_EMBED_ISVALID 533 | |
610 | - | |
611 | -#define IPC_CONVERTFILE 506 | |
612 | -/* (requires Winamp 2.92+) | |
613 | -** Converts a given file to a different format (PCM, MP3, etc...) | |
614 | -** To use, pass a pointer to a waFileConvertStruct struct | |
615 | -** This struct can be either on the heap or some global | |
616 | -** data, but NOT on the stack. At least, until the conversion is done. | |
617 | -** | |
618 | -** eg: SendMessage(hwnd_winamp,WM_WA_IPC,&myConvertStruct,IPC_CONVERTFILE); | |
619 | -** | |
620 | -** Return value: | |
621 | -** 0: Can't start the conversion. Look at myConvertStruct->error for details. | |
622 | -** 1: Conversion started. Status messages will be sent to the specified callbackhwnd. | |
623 | -** Be sure to call IPC_CONVERTFILE_END when your callback window receives the | |
624 | -** IPC_CB_CONVERT_DONE message. | |
625 | -*/ | |
626 | -typedef struct | |
627 | -{ | |
628 | - char *sourcefile; // "c:\\source.mp3" | |
629 | - char *destfile; // "c:\\dest.pcm" | |
630 | - int destformat[8]; // like 'PCM ',srate,nch,bps | |
631 | - HWND callbackhwnd; // window that will receive the IPC_CB_CONVERT notification messages | |
632 | - | |
633 | - //filled in by winamp.exe | |
634 | - char *error; //if IPC_CONVERTFILE returns 0, the reason will be here | |
635 | - | |
636 | - int bytes_done; //you can look at both of these values for speed statistics | |
637 | - int bytes_total; | |
638 | - int bytes_out; | |
639 | - | |
640 | - int killswitch; // don't set it manually, use IPC_CONVERTFILE_END | |
641 | - int extra_data[64]; // for internal winamp use | |
642 | -} convertFileStruct; | |
643 | - | |
644 | -#define IPC_CONVERTFILE_END 507 | |
645 | -/* (requires Winamp 2.92+) | |
646 | -** Stop/ends a convert process started from IPC_CONVERTFILE | |
647 | -** You need to call this when you receive the IPC_CB_CONVERTDONE message or when you | |
648 | -** want to abort a conversion process | |
649 | -** | |
650 | -** eg: SendMessage(hwnd_winamp,WM_WA_IPC,&myConvertStruct,IPC_CONVERTFILE_END); | |
651 | -** | |
652 | -** No return value | |
653 | -*/ | |
654 | - | |
655 | -typedef struct { | |
656 | - HWND hwndParent; | |
657 | - int format; | |
658 | - | |
659 | - //filled in by winamp.exe | |
660 | - HWND hwndConfig; | |
661 | - int extra_data[8]; | |
662 | -} convertConfigStruct; | |
663 | -#define IPC_CONVERT_CONFIG 508 | |
664 | -#define IPC_CONVERT_CONFIG_END 509 | |
665 | - | |
666 | -typedef struct | |
667 | -{ | |
668 | - void (*enumProc)(int user_data, const char *desc, int fourcc); | |
669 | - int user_data; | |
670 | -} converterEnumFmtStruct; | |
671 | -#define IPC_CONVERT_CONFIG_ENUMFMTS 510 | |
672 | -/* (requires Winamp 2.92+) | |
673 | -*/ | |
674 | - | |
675 | - | |
676 | -typedef struct | |
677 | -{ | |
678 | - char cdletter; | |
679 | - char *playlist_file; | |
680 | - HWND callback_hwnd; | |
681 | - | |
682 | - //filled in by winamp.exe | |
683 | - char *error; | |
684 | -} burnCDStruct; | |
685 | -#define IPC_BURN_CD 511 | |
686 | -/* (requires Winamp 5.0+) | |
687 | -*/ | |
688 | - | |
689 | -typedef struct | |
690 | -{ | |
691 | - convertFileStruct *cfs; | |
692 | - int priority; | |
693 | -} convertSetPriority; | |
694 | -#define IPC_CONVERT_SET_PRIORITY 512 | |
695 | - | |
696 | -typedef struct | |
697 | -{ | |
698 | - char *filename; | |
699 | - char *title; // 2048 bytes | |
700 | - int length; | |
701 | - int force_useformatting; // can set this to 1 if you want to force a url to use title formatting shit | |
702 | -} waHookTitleStruct; | |
703 | -// return TRUE if you hook this | |
704 | -#define IPC_HOOK_TITLES 850 | |
705 | - | |
706 | -#define IPC_GETSADATAFUNC 800 | |
707 | -// 0: returns a char *export_sa_get() that returns 150 bytes of data | |
708 | -// 1: returns a export_sa_setreq(int want); | |
709 | - | |
710 | -#define IPC_ISMAINWNDVISIBLE 900 | |
711 | - | |
712 | - | |
713 | -#define IPC_SETPLEDITCOLORS 920 | |
714 | -typedef struct | |
715 | -{ | |
716 | - int numElems; | |
717 | - int *elems; | |
718 | - HBITMAP bm; // set if you want to override | |
719 | -} waSetPlColorsStruct; | |
720 | - | |
721 | - | |
722 | -// the following IPC use waSpawnMenuParms as parameter | |
723 | -#define IPC_SPAWNEQPRESETMENU 933 | |
724 | -#define IPC_SPAWNFILEMENU 934 //menubar | |
725 | -#define IPC_SPAWNOPTIONSMENU 935 //menubar | |
726 | -#define IPC_SPAWNWINDOWSMENU 936 //menubar | |
727 | -#define IPC_SPAWNHELPMENU 937 //menubar | |
728 | -#define IPC_SPAWNPLAYMENU 938 //menubar | |
729 | -#define IPC_SPAWNPEFILEMENU 939 //menubar | |
730 | -#define IPC_SPAWNPEPLAYLISTMENU 940 //menubar | |
731 | -#define IPC_SPAWNPESORTMENU 941 //menubar | |
732 | -#define IPC_SPAWNPEHELPMENU 942 //menubar | |
733 | -#define IPC_SPAWNMLFILEMENU 943 //menubar | |
734 | -#define IPC_SPAWNMLVIEWMENU 944 //menubar | |
735 | -#define IPC_SPAWNMLHELPMENU 945 //menubar | |
736 | -#define IPC_SPAWNPELISTOFPLAYLISTS 946 | |
737 | - | |
738 | -typedef struct | |
739 | -{ | |
740 | - HWND wnd; | |
741 | - int xpos; // in screen coordinates | |
742 | - int ypos; | |
743 | -} waSpawnMenuParms; | |
744 | - | |
745 | -// waSpawnMenuParms2 is used by the menubar submenus | |
746 | -typedef struct | |
747 | -{ | |
748 | - HWND wnd; | |
749 | - int xpos; // in screen coordinates | |
750 | - int ypos; | |
751 | - int width; | |
752 | - int height; | |
753 | -} waSpawnMenuParms2; | |
754 | - | |
755 | - | |
756 | -// system tray sends this (you might want to simulate it) | |
757 | -#define WM_WA_SYSTRAY WM_USER+1 | |
758 | - | |
759 | -// input plugins send this when they are done playing back | |
760 | -#define WM_WA_MPEG_EOF WM_USER+2 | |
761 | - | |
762 | - | |
763 | - | |
764 | -//// video stuff | |
765 | - | |
766 | -#define IPC_IS_PLAYING_VIDEO 501 // returns >1 if playing, 0 if not, 1 if old version (so who knows):) | |
767 | -#define IPC_GET_IVIDEOOUTPUT 500 // see below for IVideoOutput interface | |
768 | -#define VIDEO_MAKETYPE(A,B,C,D) ((A) | ((B)<<8) | ((C)<<16) | ((D)<<24)) | |
769 | -#define VIDUSER_SET_INFOSTRING 0x1000 | |
770 | -#define VIDUSER_GET_VIDEOHWND 0x1001 | |
771 | -#define VIDUSER_SET_VFLIP 0x1002 | |
772 | - | |
773 | -#ifndef NO_IVIDEO_DECLARE | |
774 | -#ifdef __cplusplus | |
775 | - | |
776 | -class VideoOutput; | |
777 | -class SubsItem; | |
778 | - | |
779 | -typedef struct { | |
780 | - unsigned char* baseAddr; | |
781 | - long rowBytes; | |
782 | -} YV12_PLANE; | |
783 | - | |
784 | -typedef struct { | |
785 | - YV12_PLANE y; | |
786 | - YV12_PLANE u; | |
787 | - YV12_PLANE v; | |
788 | -} YV12_PLANES; | |
789 | - | |
790 | -class IVideoOutput | |
791 | -{ | |
792 | - public: | |
793 | - virtual ~IVideoOutput() { } | |
794 | - virtual int open(int w, int h, int vflip, double aspectratio, unsigned int fmt)=0; | |
795 | - virtual void setcallback(LRESULT (*msgcallback)(void *token, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam), void *token) { } | |
796 | - virtual void close()=0; | |
797 | - virtual void draw(void *frame)=0; | |
798 | - virtual void drawSubtitle(SubsItem *item) { } | |
799 | - virtual void showStatusMsg(const char *text) { } | |
800 | - virtual int get_latency() { return 0; } | |
801 | - virtual void notifyBufferState(int bufferstate) { } /* 0-255*/ | |
802 | - | |
803 | - virtual int extended(int param1, int param2, int param3) { return 0; } // Dispatchable, eat this! | |
804 | -}; | |
805 | -#endif //cplusplus | |
806 | -#endif//NO_IVIDEO_DECLARE | |
807 | - | |
808 | -// these messages are callbacks that you can grab by subclassing the winamp window | |
809 | - | |
810 | -// wParam = | |
811 | -#define IPC_CB_WND_EQ 0 // use one of these for the param | |
812 | -#define IPC_CB_WND_PE 1 | |
813 | -#define IPC_CB_WND_MB 2 | |
814 | -#define IPC_CB_WND_VIDEO 3 | |
815 | -#define IPC_CB_WND_MAIN 4 | |
816 | - | |
817 | -#define IPC_CB_ONSHOWWND 600 | |
818 | -#define IPC_CB_ONHIDEWND 601 | |
819 | - | |
820 | -#define IPC_CB_GETTOOLTIP 602 | |
821 | - | |
822 | -#define IPC_CB_MISC 603 | |
823 | - #define IPC_CB_MISC_TITLE 0 | |
824 | - #define IPC_CB_MISC_VOLUME 1 // volume/pan | |
825 | - #define IPC_CB_MISC_STATUS 2 | |
826 | - #define IPC_CB_MISC_EQ 3 | |
827 | - #define IPC_CB_MISC_INFO 4 | |
828 | - #define IPC_CB_MISC_VIDEOINFO 5 | |
829 | - | |
830 | -#define IPC_CB_CONVERT_STATUS 604 // param value goes from 0 to 100 (percent) | |
831 | -#define IPC_CB_CONVERT_DONE 605 | |
832 | - | |
833 | -#define IPC_ADJUST_FFWINDOWSMENUPOS 606 | |
834 | -/* (requires Winamp 2.9+) | |
835 | -** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_FFWINDOWSMENUPOS); | |
836 | -** moves where winamp expects the freeform windows in the menubar windows main menu. Useful if you wish to insert a | |
837 | -** menu item above extra freeform windows. | |
838 | -*/ | |
839 | - | |
840 | -#define IPC_ISDOUBLESIZE 608 | |
841 | - | |
842 | -#define IPC_ADJUST_FFOPTIONSMENUPOS 609 | |
843 | -/* (requires Winamp 2.9+) | |
844 | -** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_FFOPTIONSMENUPOS); | |
845 | -** moves where winamp expects the freeform preferences item in the menubar windows main menu. Useful if you wish to insert a | |
846 | -** menu item above preferences item. | |
847 | -*/ | |
848 | - | |
849 | -#define IPC_GETTIMEDISPLAYMODE 610 // returns 0 if displaying elapsed time or 1 if displaying remaining time | |
850 | - | |
851 | -#define IPC_SETVISWND 611 // param is hwnd, setting this allows you to receive ID_VIS_NEXT/PREVOUS/RANDOM/FS wm_commands | |
852 | -#define ID_VIS_NEXT 40382 | |
853 | -#define ID_VIS_PREV 40383 | |
854 | -#define ID_VIS_RANDOM 40384 | |
855 | -#define ID_VIS_FS 40389 | |
856 | -#define ID_VIS_CFG 40390 | |
857 | -#define ID_VIS_MENU 40391 | |
858 | - | |
859 | -#define IPC_GETVISWND 612 // returns the vis cmd handler hwnd | |
860 | -#define IPC_ISVISRUNNING 613 | |
861 | -#define IPC_CB_VISRANDOM 628 // param is status of random | |
862 | - | |
863 | -#define IPC_SETIDEALVIDEOSIZE 614 // sent by winamp to winamp, trap it if you need it. width=HIWORD(param), height=LOWORD(param) | |
864 | - | |
865 | -#define IPC_GETSTOPONVIDEOCLOSE 615 | |
866 | -#define IPC_SETSTOPONVIDEOCLOSE 616 | |
867 | - | |
868 | -typedef struct { | |
869 | - HWND hwnd; | |
870 | - int uMsg; | |
871 | - int wParam; | |
872 | - int lParam; | |
873 | -} transAccelStruct; | |
874 | - | |
875 | -#define IPC_TRANSLATEACCELERATOR 617 | |
876 | - | |
877 | -typedef struct { | |
878 | - int cmd; | |
879 | - int x; | |
880 | - int y; | |
881 | - int align; | |
882 | -} windowCommand; // send this as param to an IPC_PLCMD, IPC_MBCMD, IPC_VIDCMD | |
883 | - | |
884 | -#define IPC_CB_ONTOGGLEAOT 618 | |
885 | - | |
886 | -#define IPC_GETPREFSWND 619 | |
887 | - | |
888 | -#define IPC_SET_PE_WIDTHHEIGHT 620 // data is a pointer to a POINT structure that holds width & height | |
889 | - | |
890 | -#define IPC_GETLANGUAGEPACKINSTANCE 621 | |
891 | - | |
892 | -#define IPC_CB_PEINFOTEXT 622 // data is a string, ie: "04:21/45:02" | |
893 | - | |
894 | -#define IPC_CB_OUTPUTCHANGED 623 // output plugin was changed in config | |
895 | - | |
896 | -#define IPC_GETOUTPUTPLUGIN 625 | |
897 | - | |
898 | -#define IPC_SETDRAWBORDERS 626 | |
899 | -#define IPC_DISABLESKINCURSORS 627 | |
900 | -#define IPC_CB_RESETFONT 629 | |
901 | - | |
902 | -#define IPC_IS_FULLSCREEN 630 // returns 1 if video or vis is in fullscreen mode | |
903 | -#define IPC_SET_VIS_FS_FLAG 631 // a vis should send this message with 1/as param to notify winamp that it has gone to or has come back from fullscreen mode | |
904 | - | |
905 | -#define IPC_SHOW_NOTIFICATION 632 | |
906 | - | |
907 | -#define IPC_GETSKININFO 633 | |
908 | - | |
909 | -// >>>>>>>>>>> Next is 634 | |
910 | - | |
911 | -#define IPC_PLCMD 1000 | |
912 | - | |
913 | -#define PLCMD_ADD 0 | |
914 | -#define PLCMD_REM 1 | |
915 | -#define PLCMD_SEL 2 | |
916 | -#define PLCMD_MISC 3 | |
917 | -#define PLCMD_LIST 4 | |
918 | - | |
919 | -#define IPC_MBCMD 1001 | |
920 | - | |
921 | -#define MBCMD_BACK 0 | |
922 | -#define MBCMD_FORWARD 1 | |
923 | -#define MBCMD_STOP 2 | |
924 | -#define MBCMD_RELOAD 3 | |
925 | -#define MBCMD_MISC 4 | |
926 | - | |
927 | -#define IPC_VIDCMD 1002 | |
928 | - | |
929 | -#define VIDCMD_FULLSCREEN 0 | |
930 | -#define VIDCMD_1X 1 | |
931 | -#define VIDCMD_2X 2 | |
932 | -#define VIDCMD_LIB 3 | |
933 | -#define VIDPOPUP_MISC 4 | |
934 | - | |
935 | -#define IPC_MBURL 1003 //sets the URL | |
936 | -#define IPC_MBGETCURURL 1004 //copies the current URL into wParam (have a 4096 buffer ready) | |
937 | -#define IPC_MBGETDESC 1005 //copies the current URL description into wParam (have a 4096 buffer ready) | |
938 | -#define IPC_MBCHECKLOCFILE 1006 //checks that the link file is up to date (otherwise updates it). wParam=parent HWND | |
939 | -#define IPC_MBREFRESH 1007 //refreshes the "now playing" view in the library | |
940 | -#define IPC_MBGETDEFURL 1008 //copies the default URL into wParam (have a 4096 buffer ready) | |
941 | - | |
942 | -#define IPC_STATS_LIBRARY_ITEMCNT 1300 // updates library count status | |
943 | - | |
944 | -// IPC 2000-3000 reserved for freeform messages, see gen_ff/ff_ipc.h | |
945 | -#define IPC_FF_FIRST 2000 | |
946 | -#define IPC_FF_LAST 3000 | |
947 | - | |
948 | -#define IPC_GETDROPTARGET 3001 | |
949 | - | |
950 | -#define IPC_PLAYLIST_MODIFIED 3002 // sent to main wnd whenever the playlist is modified | |
951 | - | |
952 | -#define IPC_PLAYING_FILE 3003 // sent to main wnd with the file as parm whenever a file is played | |
953 | -#define IPC_FILE_TAG_MAY_HAVE_UPDATED 3004 // sent to main wnd with the file as parm whenever a file tag might be updated | |
954 | - | |
955 | - | |
956 | -#define IPC_ALLOW_PLAYTRACKING 3007 | |
957 | -// send nonzero to allow, zero to disallow | |
958 | - | |
959 | -#define IPC_HOOK_OKTOQUIT 3010 // return 0 to abort a quit, nonzero if quit is OK | |
960 | - | |
961 | -#define IPC_WRITECONFIG 3011 // pass 2 to write all, 1 to write playlist + common, 0 to write common+less common | |
962 | - | |
963 | -// pass a string to be the name to register, and returns a value > 65536, which is a unique value you can use | |
964 | -// for custom WM_WA_IPC messages. | |
965 | -#define IPC_REGISTER_WINAMP_IPCMESSAGE 65536 | |
966 | - | |
967 | -/**************************************************************************/ | |
968 | - | |
969 | -/* | |
970 | -** Finally there are some WM_COMMAND messages that you can use to send | |
971 | -** Winamp misc commands. | |
972 | -** | |
973 | -** To send these, use: | |
974 | -** | |
975 | -** SendMessage(hwnd_winamp, WM_COMMAND,command_name,0); | |
976 | -*/ | |
977 | - | |
978 | -#define WINAMP_OPTIONS_EQ 40036 // toggles the EQ window | |
979 | -#define WINAMP_OPTIONS_PLEDIT 40040 // toggles the playlist window | |
980 | -#define WINAMP_VOLUMEUP 40058 // turns the volume up a little | |
981 | -#define WINAMP_VOLUMEDOWN 40059 // turns the volume down a little | |
982 | -#define WINAMP_FFWD5S 40060 // fast forwards 5 seconds | |
983 | -#define WINAMP_REW5S 40061 // rewinds 5 seconds | |
984 | - | |
985 | -// the following are the five main control buttons, with optionally shift | |
986 | -// or control pressed | |
987 | -// (for the exact functions of each, just try it out) | |
988 | -#define WINAMP_BUTTON1 40044 | |
989 | -#define WINAMP_BUTTON2 40045 | |
990 | -#define WINAMP_BUTTON3 40046 | |
991 | -#define WINAMP_BUTTON4 40047 | |
992 | -#define WINAMP_BUTTON5 40048 | |
993 | -#define WINAMP_BUTTON1_SHIFT 40144 | |
994 | -#define WINAMP_BUTTON2_SHIFT 40145 | |
995 | -#define WINAMP_BUTTON3_SHIFT 40146 | |
996 | -#define WINAMP_BUTTON4_SHIFT 40147 | |
997 | -#define WINAMP_BUTTON5_SHIFT 40148 | |
998 | -#define WINAMP_BUTTON1_CTRL 40154 | |
999 | -#define WINAMP_BUTTON2_CTRL 40155 | |
1000 | -#define WINAMP_BUTTON3_CTRL 40156 | |
1001 | -#define WINAMP_BUTTON4_CTRL 40157 | |
1002 | -#define WINAMP_BUTTON5_CTRL 40158 | |
1003 | - | |
1004 | -#define WINAMP_FILE_PLAY 40029 // pops up the load file(s) box | |
1005 | -#define WINAMP_FILE_DIR 40187 // pops up the load directory box | |
1006 | -#define WINAMP_OPTIONS_PREFS 40012 // pops up the preferences | |
1007 | -#define WINAMP_OPTIONS_AOT 40019 // toggles always on top | |
1008 | -#define WINAMP_HELP_ABOUT 40041 // pops up the about box :) | |
1009 | - | |
1010 | -#define ID_MAIN_PLAY_AUDIOCD1 40323 // starts playing the audio CD in the first CD reader | |
1011 | -#define ID_MAIN_PLAY_AUDIOCD2 40323 // plays the 2nd | |
1012 | -#define ID_MAIN_PLAY_AUDIOCD3 40323 // plays the 3nd | |
1013 | -#define ID_MAIN_PLAY_AUDIOCD4 40323 // plays the 4nd | |
1014 | - | |
1015 | -// IDs 42000 to 45000 are reserved for gen_ff | |
1016 | -// IDs from 45000 to 57000 are reserved for library | |
1017 | - | |
1018 | -#endif//_WA_IPC_H_ | |
1019 | - | |
1020 | -/* | |
1021 | -** EOF.. Enjoy. | |
1022 | -*/ | |
\ No newline at end of file |
@@ -0,0 +1,4317 @@ | ||
1 | +#define BUILD_UNICODE | |
2 | + | |
3 | +#if defined(BUILD_UNICODE) | |
4 | +#if !defined(UNICODE) | |
5 | +#define _UNICODE | |
6 | +#define UNICODE | |
7 | +#endif | |
8 | +#endif | |
9 | + | |
10 | +#if defined(UNICODE) && !defined(BUILD_UNICODE) | |
11 | +#define BUILD_UNICODE | |
12 | +#endif | |
13 | + | |
14 | +#define LONG_PTR_TO_WNDPROC(p) (reinterpret_cast<WNDPROC>(p)) | |
15 | +#define WNDPROC_TO_LONG_PTR(p) (reinterpret_cast<LONG_PTR>(p)) | |
16 | + | |
17 | +#include <windows.h> | |
18 | +#include <lmcons.h> | |
19 | +#include <process.h> | |
20 | +#include <shlobj.h> | |
21 | + | |
22 | +#include <string> | |
23 | +#include <vector> | |
24 | +#include <map> | |
25 | + | |
26 | +typedef std::vector<std::string> Strings; | |
27 | +typedef Strings::iterator StringsIt; | |
28 | +typedef Strings::const_iterator StringsCIt; | |
29 | + | |
30 | +typedef std::map<std::string, std::string> StringMap; | |
31 | +typedef StringMap::iterator StringMapIt; | |
32 | +typedef StringMap::const_iterator StringMapCIt; | |
33 | + | |
34 | +typedef std::map<std::string, UINT> UIntMap; | |
35 | +typedef UIntMap::iterator UIntMapIt; | |
36 | +typedef UIntMap::const_iterator UIntMapCIt; | |
37 | + | |
38 | +#include "../SDK/foobar2000.h" | |
39 | +#include "../SDK/component.h" | |
40 | +#include "../helpers/helpers.h" | |
41 | + | |
42 | +#if 0 | |
43 | +#include <wx/string.h> | |
44 | +#endif | |
45 | + | |
46 | +#include "GEN.h" | |
47 | +#include "wa_ipc.h" | |
48 | + | |
49 | +#if 0 | |
50 | +#define ID3LIB_LINKOPTION 3 | |
51 | +#include <id3/tag.h> | |
52 | +#include <id3/misc_support.h> | |
53 | +#endif | |
54 | + | |
55 | +#include "resource.h" | |
56 | + | |
57 | +#if defined(_FOOBAR2000_UTF8API_H_) | |
58 | +# define FB2K_MAJOR_VERSION 8 | |
59 | +#else | |
60 | +# define FB2K_MAJOR_VERSION 9 | |
61 | +#endif | |
62 | + | |
63 | +#define IS_FB2K_VER08 (FB2K_MAJOR_VERSION == 8) | |
64 | +#define IS_FB2K_VER09 (FB2K_MAJOR_VERSION == 9) | |
65 | + | |
66 | +#define FB2K_COMPONENTS_DIR _T("components\\") | |
67 | +#define GEN_MIXI_FILE_NAME _T("gen_mixi_for_winamp.dll") | |
68 | +#define GEN_MIXI_FUNC_NAME_GET_GENERAL_PURPOSE_PLUGIN "winampGetGeneralPurposePlugin" | |
69 | + | |
70 | +#define DUMMY_MP3_FILE_NAME _T("foo_mixi_feat_winamp.mp3") | |
71 | +#define APPDATA_MIXI_STATION_DIR _T("\\mixi\\mixi") | |
72 | +#define DEFAULT_WINAMP_TITLE "Winamp" | |
73 | +#define DEFAULT_DUMMYAMP_TITLE "DummyAmp" | |
74 | + | |
75 | +#define CODEC_TYPE_VORBIS "Vorbis" | |
76 | +#define CODEC_TYPE_MP3 "MP3" | |
77 | + | |
78 | +#define IS_SUPPORTED_FORMAT_BY_GEN_MIXI(codec) (!::lstrcmpA(codec, CODEC_TYPE_VORBIS) || !::lstrcmpA(codec, CODEC_TYPE_MP3)) | |
79 | + | |
80 | +#if !defined(ENABLE_MSN) | |
81 | +#define PLUGIN_CAPTION "mixi music plugin for Winamp, bridge component" | |
82 | +#define PLUGIN_CAPTION_JP "mixi ミュージック" | |
83 | +#else | |
84 | +#define PLUGIN_CAPTION "Mixi Music plugin for M2M" | |
85 | +#endif | |
86 | + | |
87 | +#define ADVANCED_SETTINGS_CAPTION "高度な設定" | |
88 | +#define DUMMYAMP_FRAME_CAPTION _T("DummyAmp の設定 (動作状態:%s)") | |
89 | +#define DUMMYAMP_BEFORE_INIT_MODE _T("初回再生の待機中") | |
90 | +#define DUMMYAMP_HOOK_MODE _T("既存 Winamp API Emulator をフック中") | |
91 | +#define DUMMYAMP_STANDALONE_MODE _T("単独で Winamp API をエミュレート中") | |
92 | +#define DEBUG_SETTINGS_CAPTION "デバッグ用の設定" | |
93 | +#define PLUGIN_VERSION "0.2.1.0" | |
94 | + | |
95 | +#define DEFAULT_DUMMYAMP_TITLE_FORMAT "[%artist% - ]$if(%title%,%title%,%_filename%)" | |
96 | + | |
97 | +#define URL_FOO_MIXI_HOME "http://foo-mixi.sourceforge.jp/" | |
98 | + | |
99 | +#define FORMAT_FILEPATH "%_path%" | |
100 | +#define FORMAT_FILEPATHRAW "%_path_raw%" | |
101 | +#define FORMAT_ARTIST "%artist%" | |
102 | +#define FORMAT_TRACKTITLE "%title%" | |
103 | +#define FORMAT_ALBUMTITLE "%album%" | |
104 | +#define FORMAT_GENRE "%genre%" | |
105 | +#define FORMAT_CODEC "%__codec%" | |
106 | + | |
107 | +#if IS_FB2K_VER08 | |
108 | +#define FORMAT_LISTINDEX "%_playlist_number%" | |
109 | +#elif IS_FB2K_VER09 | |
110 | +#define FORMAT_LISTINDEX "%list_index%" | |
111 | +#endif | |
112 | + | |
113 | +#define IPC_GETOUTPUTTIME_PositionMSec 0 | |
114 | +#define IPC_GETOUTPUTTIME_TotalSec 1 | |
115 | + | |
116 | +#define IPC_INTERNAL_REFRESHLISTINFO 0x4000 | |
117 | +#define IPC_INTERNAL_REFRESHDYNINFO 0x4001 | |
118 | + | |
119 | +#define RESENT_INTERVAL 5000 | |
120 | +#define FORCE_RESENT_MODE 0 | |
121 | +//#define DISABLE_KICK_GEN_MIXI_LOOP | |
122 | + | |
123 | +#define GEN_MIXI_REQUIRED_SECONDS 6 | |
124 | +#define GEN_MIXI_TRIGGER_SECONDS 6 | |
125 | +#define GEN_MIXI_MARGIN_SECONDS 0 | |
126 | + | |
127 | +#define REQUIRED_MINIMUM_TIME 8 | |
128 | +#define SEND_TIME_RATE_LOWERBOUND 0 | |
129 | +#define REQUIRED_MAXIMUM_TIME 0 | |
130 | + | |
131 | +#define CONTROL_SEND_TIMING | |
132 | + | |
133 | +//#define ENABLE_MSN | |
134 | + | |
135 | +#if IS_FB2K_VER09 | |
136 | +using namespace pfc; | |
137 | +using namespace pfc::stringcvt; | |
138 | +#define pfc_string_to_float string_to_float | |
139 | +#endif | |
140 | + | |
141 | +/* | |
142 | + foo_mixi_feat_winamp: project dependencies | |
143 | + | |
144 | + foo_mixi_feat_winamp | |
145 | + foobar2000_SDK | |
146 | + utf8api(0.8.3) | |
147 | + pfc | |
148 | + foobar2000_sdk_helpers | |
149 | + pfc | |
150 | + foobar2000_component_client(0.9.X) | |
151 | + id3lib | |
152 | + zlib | |
153 | + | |
154 | + library dependencies: wxbase28.lib, id3lib.lib, ../shared/shared.lib(0.9.X) | |
155 | + runtime library: Multi-Thread (DLL) or (Debug,DLL) | |
156 | + !! ensure all projects that depended from this project are correctly set to MT DLL !! | |
157 | + ignore: LIBCMT [Win32 Release] (or LIBCMTD [Win32 Debug]) | |
158 | +*/ | |
159 | + | |
160 | +// if wxWidgets are updated, change lib names below and linker libpath option. | |
161 | + | |
162 | +#if 0 | |
163 | +#if defined(_DEBUG) | |
164 | +#if defined(BUILD_UNICODE) | |
165 | +#pragma comment(lib, "wxbase28ud.lib") | |
166 | +#else | |
167 | +#pragma comment(lib, "wxbase28d.lib") | |
168 | +#endif | |
169 | +#else | |
170 | +#if defined(BUILD_UNICODE) | |
171 | +#pragma comment(lib, "wxbase28u.lib") | |
172 | +#else | |
173 | +#pragma comment(lib, "wxbase28.lib") | |
174 | +#endif | |
175 | +#endif | |
176 | +#endif | |
177 | + | |
178 | +// now id3lib automatically added to linker target, | |
179 | +// because it generated from depended project. | |
180 | +//#pragma comment(lib, "id3lib.lib") | |
181 | + | |
182 | +#if IS_FB2K_VER09 | |
183 | +#pragma comment(lib, "../shared/shared.lib") | |
184 | +#endif | |
185 | + | |
186 | +typedef std::basic_string<TCHAR> tstring; | |
187 | + | |
188 | +typedef TCHAR Str64K[65536]; | |
189 | +typedef char StrDBCS64K[65536]; | |
190 | + | |
191 | +tstring GetErrorMessage(DWORD errCode); | |
192 | +void putLogError(LPCTSTR pMethod, LPCTSTR pErrMsg, DWORD dwErrCode); | |
193 | +void setDlgVersionInfo(HWND wnd, UINT idc_version, UINT idc_build); | |
194 | +void DebugPrint(int severity, LPCTSTR lpszFormat, ...); | |
195 | +void DebugPrintDBCS(int severity, LPCSTR lpszFormat, ...); | |
196 | +void DebugPrint8(int severity, LPCSTR lpszFormat, ...); | |
197 | + | |
198 | +#define LOGLEVEL_NONE 0 | |
199 | +#define LOGLEVEL_WARNING 1 | |
200 | +#define LOGLEVEL_ERROR 2 | |
201 | + | |
202 | +#if IS_FB2K_VER09 | |
203 | +namespace console | |
204 | +{ | |
205 | + enum { | |
206 | + SEVERITY_INFO = 0, | |
207 | + SEVERITY_WARNING = 1, | |
208 | + SEVERITY_CRITICAL = 2 | |
209 | + }; | |
210 | +}; | |
211 | +#endif | |
212 | + | |
213 | +#define LOG_TRACE(f, ...) if(cfg_enable_debug_log) DebugPrint(console::SEVERITY_INFO, f, __VA_ARGS__) | |
214 | +#define LOG_DEBUG(f, ...) if(cfg_enable_debug_log) DebugPrint(console::SEVERITY_INFO, f, __VA_ARGS__) | |
215 | + | |
216 | +#define LOG_TRACE8(f, ...) if(cfg_enable_debug_log) DebugPrint8(console::SEVERITY_INFO, f, __VA_ARGS__) | |
217 | +#define LOG_DEBUG8(f, ...) if(cfg_enable_debug_log) DebugPrint8(console::SEVERITY_INFO, f, __VA_ARGS__) | |
218 | + | |
219 | +#define LOG_TRACE_ANSI(f, ...) if(cfg_enable_debug_log) DebugPrintDBCS(console::SEVERITY_INFO, f, __VA_ARGS__) | |
220 | +#define LOG_DEBUG_ANSI(f, ...) if(cfg_enable_debug_log) DebugPrintDBCS(console::SEVERITY_INFO, f, __VA_ARGS__) | |
221 | + | |
222 | +#define LOG_INFO(f, ...) DebugPrint(console::SEVERITY_INFO, f, __VA_ARGS__) | |
223 | +#define LOG_WARN(f, ...) DebugPrint(console::SEVERITY_WARNING, f, __VA_ARGS__) | |
224 | +#define LOG_ERROR(f, ...) DebugPrint(console::SEVERITY_CRITICAL, f, __VA_ARGS__) | |
225 | + | |
226 | +#if defined(BUILD_UNICODE) | |
227 | +#define TRACE_DBCS(f, ...) if(cfg_enable_debug_log) DebugPrintDBCS(console::SEVERITY_INFO, f, __VA_ARGS__) | |
228 | +#else | |
229 | +#define TRACE_DBCS(f, ...) if(cfg_enable_debug_log) DebugPrint(console::SEVERITY_INFO, f, __VA_ARGS__) | |
230 | +#endif | |
231 | + | |
232 | +#define DEBUG_DUMMYAMP_INIT(f, ...) if(cfg_debug_dummyamp_init >= LOGLEVEL_WARNING) LOG_DEBUG(f, __VA_ARGS__) | |
233 | +#define TRACE_DUMMYAMP_INIT(f, ...) if(cfg_debug_dummyamp_init >= LOGLEVEL_ERROR) LOG_TRACE(f, __VA_ARGS__) | |
234 | + | |
235 | +#define DEBUG_DUMMYAMP_PROC(f, ...) if(cfg_debug_dummyamp_proc >= LOGLEVEL_WARNING) LOG_DEBUG(f, __VA_ARGS__) | |
236 | +#define DEBUG_DUMMYAMP_PROC8(f, ...) if(cfg_debug_dummyamp_proc >= LOGLEVEL_WARNING) LOG_DEBUG8(f, __VA_ARGS__) | |
237 | +#define TRACE_DUMMYAMP_PROC(f, ...) if(cfg_debug_dummyamp_proc >= LOGLEVEL_ERROR) LOG_TRACE(f, __VA_ARGS__) | |
238 | +#define TRACE_DUMMYAMP_PROC8(f, ...) if(cfg_debug_dummyamp_proc >= LOGLEVEL_ERROR) LOG_TRACE8(f, __VA_ARGS__) | |
239 | + | |
240 | +#define DEBUG_TRACK_INFO(f, ...) if(cfg_debug_track_info >= LOGLEVEL_WARNING) LOG_DEBUG(f, __VA_ARGS__) | |
241 | +#define DEBUG_TRACK_INFO8(f, ...) if(cfg_debug_track_info >= LOGLEVEL_WARNING) LOG_DEBUG8(f, __VA_ARGS__) | |
242 | +#define DEBUG_TRACK_INFO_ANSI(f, ...) if(cfg_debug_track_info >= LOGLEVEL_WARNING) LOG_DEBUG_ANSI(f, __VA_ARGS__) | |
243 | +#define TRACE_TRACK_INFO(f, ...) if(cfg_debug_track_info >= LOGLEVEL_ERROR) LOG_TRACE(f, __VA_ARGS__) | |
244 | +#define TRACE_TRACK_INFO8(f, ...) if(cfg_debug_track_info >= LOGLEVEL_ERROR) LOG_TRACE8(f, __VA_ARGS__) | |
245 | +#define TRACE_TRACK_INFO_ANSI(f, ...) if(cfg_debug_track_info >= LOGLEVEL_ERROR) LOG_TRACE_ANSI(f, __VA_ARGS__) | |
246 | + | |
247 | +#define DEBUG_PLUGIN(f, ...) if(cfg_debug_plugin >= LOGLEVEL_WARNING) LOG_DEBUG(f, __VA_ARGS__) | |
248 | +#define TRACE_PLUGIN(f, ...) if(cfg_debug_plugin >= LOGLEVEL_ERROR) LOG_TRACE(f, __VA_ARGS__) | |
249 | + | |
250 | +#define DEBUG_CALLBACK(f, ...) if(cfg_debug_callback >= LOGLEVEL_WARNING) LOG_DEBUG(f, __VA_ARGS__) | |
251 | +#define TRACE_CALLBACK(f, ...) if(cfg_debug_callback >= LOGLEVEL_ERROR) LOG_TRACE(f, __VA_ARGS__) | |
252 | + | |
253 | +static string_utf8_from_os g_pluginCaption8(_T(PLUGIN_CAPTION_JP)); | |
254 | +static string_utf8_from_os g_pluginVersion8(_T(PLUGIN_VERSION)); | |
255 | +static string_utf8_from_os g_pluginAbout8( | |
256 | + _T(PLUGIN_CAPTION_JP) _T(" ") _T(PLUGIN_VERSION) _T("\nCopyright (C) 2006-2009 Yossiepon Oniichan, All Rights Reserved.")); | |
257 | + | |
258 | +DECLARE_COMPONENT_VERSION(g_pluginCaption8, g_pluginVersion8, g_pluginAbout8); | |
259 | + | |
260 | +static string_utf8_from_os g_advancedSettingsCaption8(_T(ADVANCED_SETTINGS_CAPTION)); | |
261 | +static string_utf8_from_os g_debugSettingsCaption8(_T(DEBUG_SETTINGS_CAPTION)); | |
262 | + | |
263 | +static string_utf8_from_os g_menu_item(_T("Components/Mixi/mixiミュージック連携を有効にする")); | |
264 | + | |
265 | +static string_utf8_from_os g_menu_item_title(_T("mixiミュージック連携を有効にする")); | |
266 | +static string_utf8_from_os g_menu_item_description(_T("mixiミュージックへの曲情報の送信について、有効/無効を切り替えます")); | |
267 | + | |
268 | +#if IS_FB2K_VER08 | |
269 | +static cfg_int cfg_use_plugin("usePlugin", 1); | |
270 | + | |
271 | +static cfg_string cfg_no_artist_name("NoArtistName", "No Artist"); | |
272 | +static cfg_string cfg_no_title_name("NoTitleName", "No Title"); | |
273 | +static cfg_string cfg_no_album_name("NoAlbumName", "No Title"); | |
274 | +static cfg_string cfg_no_genre_name("NoGenreName", "Other"); | |
275 | + | |
276 | +static cfg_string cfg_send_interval1("SendInterval1", "20"); | |
277 | +static cfg_string cfg_send_interval2("SendInterval2", "66"); | |
278 | +static cfg_string cfg_send_interval3("SendInterval3", "300"); | |
279 | + | |
280 | +static cfg_int cfg_disable_duplicate_song("DisableDuplicateSong", 0); | |
281 | +static cfg_int cfg_media_library_registered_file_only("MediaLibraryRegisteredFileOnly", 0); | |
282 | +static cfg_int cfg_explicitly_tagged_file_only("ExplicitlyTaggedFileOnly", 0); | |
283 | +static cfg_int cfg_enable_streaming_file("EnableStreamingFile", 0); | |
284 | + | |
285 | +static cfg_int cfg_disable_dummy_mp3("DisableDummyMp3", 0); | |
286 | +static cfg_int cfg_dummy_mp3_location("DummyMp3Location", 0); | |
287 | + | |
288 | +static cfg_int cfg_show_dummyamp("ShowDummyAmp", 0); | |
289 | +static cfg_string cfg_dummyamp_title_format("DummyAmpTitleFormat", DEFAULT_DUMMYAMP_TITLE_FORMAT); | |
290 | +static cfg_string cfg_dummyamp_playlist_format("DummyAmpPlaylistFormat", DEFAULT_DUMMYAMP_TITLE_FORMAT); | |
291 | +static cfg_int cfg_disable_ansi_trans("DisableAnsiTrans", 0); | |
292 | +static cfg_int cfg_enable_ext_ipc_proc("EnableExtIpcProc", 1); | |
293 | + | |
294 | +static cfg_int cfg_enable_debug_log("EnableDebugLog", 1); | |
295 | +static cfg_int cfg_debug_dummyamp_init("DebugDummyAmpInit", 1); | |
296 | +static cfg_int cfg_debug_dummyamp_proc("DebugDummyAmpProc", 1); | |
297 | +static cfg_int cfg_debug_track_info("DebugTrackInfo", 1); | |
298 | +static cfg_int cfg_debug_plugin("DebugPlugin", 1); | |
299 | +static cfg_int cfg_debug_callback("DebugCallback", 1); | |
300 | +#elif IS_FB2K_VER09 | |
301 | +// {DB051102-6DAE-4ff8-B5ED-AA06C2ACFEDE} | |
302 | +static const GUID cfg_use_plugin_guid = { 0xdb051102, 0x6dae, 0x4ff8, { 0xb5, 0xed, 0xaa, 0x6, 0xc2, 0xac, 0xfe, 0xde } }; | |
303 | +static cfg_int cfg_use_plugin(cfg_use_plugin_guid, 1); | |
304 | + | |
305 | +// {1B27EDEC-A28A-4dac-96D4-1E3B51C92004} | |
306 | +static const GUID cfg_no_artist_name_guid = { 0x1b27edec, 0xa28a, 0x4dac, { 0x96, 0xd4, 0x1e, 0x3b, 0x51, 0xc9, 0x20, 0x4 } }; | |
307 | +static cfg_string cfg_no_artist_name(cfg_no_artist_name_guid, "No Artist"); | |
308 | +// {A8CFD50C-05EA-447d-AA74-F4C6975E750E} | |
309 | +static const GUID cfg_no_title_name_guid = { 0xa8cfd50c, 0x5ea, 0x447d, { 0xaa, 0x74, 0xf4, 0xc6, 0x97, 0x5e, 0x75, 0xe } }; | |
310 | +static cfg_string cfg_no_title_name(cfg_no_title_name_guid, "No Title"); | |
311 | +// {A7593537-8B09-4016-9B3C-0EF5516BBFF9} | |
312 | +static const GUID cfg_no_album_name_guid = { 0xa7593537, 0x8b09, 0x4016, { 0x9b, 0x3c, 0xe, 0xf5, 0x51, 0x6b, 0xbf, 0xf9 } }; | |
313 | +static cfg_string cfg_no_album_name(cfg_no_album_name_guid, "No Title"); | |
314 | +// {15774319-0CBE-45fd-B0E8-52D4728319A3} | |
315 | +static const GUID cfg_no_genre_name_guid = { 0x15774319, 0xcbe, 0x45fd, { 0xb0, 0xe8, 0x52, 0xd4, 0x72, 0x83, 0x19, 0xa3 } }; | |
316 | +static cfg_string cfg_no_genre_name(cfg_no_genre_name_guid, "Other"); | |
317 | + | |
318 | +// {ED0C715A-D06D-4641-A29A-AE4485A0B9EF} | |
319 | +static const GUID cfg_send_interval1_guid = { 0xed0c715a, 0xd06d, 0x4641, { 0xa2, 0x9a, 0xae, 0x44, 0x85, 0xa0, 0xb9, 0xef } }; | |
320 | +static cfg_string cfg_send_interval1(cfg_send_interval1_guid, "20"); | |
321 | +// {25989711-B458-4624-8A85-7304FCE799A3} | |
322 | +static const GUID cfg_send_interval2_guid = { 0x25989711, 0xb458, 0x4624, { 0x8a, 0x85, 0x73, 0x4, 0xfc, 0xe7, 0x99, 0xa3 } }; | |
323 | +static cfg_string cfg_send_interval2(cfg_send_interval2_guid, "66"); | |
324 | +// {4287A873-015D-44b5-A31E-34DEE1BF0525} | |
325 | +static const GUID cfg_send_interval3_guid = { 0x4287a873, 0x15d, 0x44b5, { 0xa3, 0x1e, 0x34, 0xde, 0xe1, 0xbf, 0x5, 0x25 } }; | |
326 | +static cfg_string cfg_send_interval3(cfg_send_interval3_guid, "300"); | |
327 | + | |
328 | +// {5C318451-2B6A-405f-814B-2795A764C1DE} | |
329 | +static const GUID cfg_disable_duplicate_song_guid = { 0x5c318451, 0x2b6a, 0x405f, { 0x81, 0x4b, 0x27, 0x95, 0xa7, 0x64, 0xc1, 0xde } }; | |
330 | +static cfg_int cfg_disable_duplicate_song(cfg_disable_duplicate_song_guid, 0); | |
331 | +// {56688AED-A76D-4759-A835-A380D39D34D1} | |
332 | +static const GUID cfg_media_library_registered_file_only_guid = { 0x56688aed, 0xa76d, 0x4759, { 0xa8, 0x35, 0xa3, 0x80, 0xd3, 0x9d, 0x34, 0xd1 } }; | |
333 | +static cfg_int cfg_media_library_registered_file_only(cfg_media_library_registered_file_only_guid, 0); | |
334 | +// {91E0D3D4-85DD-4c45-ADB5-7FAC6F3360CD} | |
335 | +static const GUID cfg_explicitly_tagged_file_only_guid = { 0x91e0d3d4, 0x85dd, 0x4c45, { 0xad, 0xb5, 0x7f, 0xac, 0x6f, 0x33, 0x60, 0xcd } }; | |
336 | +static cfg_int cfg_explicitly_tagged_file_only(cfg_explicitly_tagged_file_only_guid, 0); | |
337 | +// {F4E85669-6EEF-4b75-AFC1-7964AEBE10B0} | |
338 | +static const GUID cfg_enable_streaming_file_guid = { 0xf4e85669, 0x6eef, 0x4b75, { 0xaf, 0xc1, 0x79, 0x64, 0xae, 0xbe, 0x10, 0xb0 } }; | |
339 | +static cfg_int cfg_enable_streaming_file(cfg_enable_streaming_file_guid, 0); | |
340 | + | |
341 | +// {67341E11-A385-45d8-9DE6-B1FABA35AC62} | |
342 | +static const GUID cfg_disable_dummy_mp3_guid = { 0x67341e11, 0xa385, 0x45d8, { 0x9d, 0xe6, 0xb1, 0xfa, 0xba, 0x35, 0xac, 0x62 } }; | |
343 | +static cfg_int cfg_disable_dummy_mp3(cfg_disable_dummy_mp3_guid, 0); | |
344 | +// {87D4D72C-43AB-42ab-8CAC-D689961DA5EA} | |
345 | +static const GUID cfg_dummy_mp3_location_guid = { 0x87d4d72c, 0x43ab, 0x42ab, { 0x8c, 0xac, 0xd6, 0x89, 0x96, 0x1d, 0xa5, 0xea } }; | |
346 | +static cfg_int cfg_dummy_mp3_location(cfg_dummy_mp3_location_guid, 0); | |
347 | + | |
348 | +// {F9DB10F0-1A01-40dd-A342-486A6CB596E7} | |
349 | +static const GUID cfg_show_dummyamp_guid = { 0xf9db10f0, 0x1a01, 0x40dd, { 0xa3, 0x42, 0x48, 0x6a, 0x6c, 0xb5, 0x96, 0xe7 } }; | |
350 | +static cfg_int cfg_show_dummyamp(cfg_show_dummyamp_guid, 0); | |
351 | +// {CC7785CA-B019-4107-9115-161A543B3952} | |
352 | +static const GUID cfg_dummyamp_title_format_guid = { 0xcc7785ca, 0xb019, 0x4107, { 0x91, 0x15, 0x16, 0x1a, 0x54, 0x3b, 0x39, 0x52 } }; | |
353 | +static cfg_string cfg_dummyamp_title_format(cfg_dummyamp_title_format_guid, DEFAULT_DUMMYAMP_TITLE_FORMAT); | |
354 | +// {B964EB32-4957-4e7a-81B5-E89B4405AAAD} | |
355 | +static const GUID cfg_dummyamp_playlist_format_guid = { 0xb964eb32, 0x4957, 0x4e7a, { 0x81, 0xb5, 0xe8, 0x9b, 0x44, 0x5, 0xaa, 0xad } }; | |
356 | +static cfg_string cfg_dummyamp_playlist_format(cfg_dummyamp_title_format_guid, DEFAULT_DUMMYAMP_TITLE_FORMAT); | |
357 | + | |
358 | +// {094571BA-1484-455c-9D6E-E18B13296149} | |
359 | +static const GUID cfg_disable_ansi_trans_guid = { 0x94571ba, 0x1484, 0x455c, { 0x9d, 0x6e, 0xe1, 0x8b, 0x13, 0x29, 0x61, 0x49 } }; | |
360 | +static cfg_int cfg_disable_ansi_trans(cfg_disable_ansi_trans_guid, 0); | |
361 | +// {8961A829-F010-461c-9CC8-C06308BFA4A2} | |
362 | +static const GUID cfg_enable_ext_ipc_proc_guid = { 0x8961a829, 0xf010, 0x461c, { 0x9c, 0xc8, 0xc0, 0x63, 0x8, 0xbf, 0xa4, 0xa2 } }; | |
363 | +static cfg_int cfg_enable_ext_ipc_proc(cfg_enable_ext_ipc_proc_guid, 1); | |
364 | + | |
365 | +// {3B6B73F9-F6AF-4b6c-8015-E73A1B87AD5C} | |
366 | +static const GUID cfg_enable_debug_log_guid = { 0x3b6b73f9, 0xf6af, 0x4b6c, { 0x80, 0x15, 0xe7, 0x3a, 0x1b, 0x87, 0xad, 0x5c } }; | |
367 | +static cfg_int cfg_enable_debug_log(cfg_enable_debug_log_guid, 1); // debug log enabled | |
368 | +// {0BF3522F-BC55-4f77-AA95-B02F6E159544} | |
369 | +static const GUID cfg_debug_dummyamp_init_guid = { 0xbf3522f, 0xbc55, 0x4f77, { 0xaa, 0x95, 0xb0, 0x2f, 0x6e, 0x15, 0x95, 0x44 } }; | |
370 | +static cfg_int cfg_debug_dummyamp_init(cfg_debug_dummyamp_init_guid, 1); // debug level | |
371 | +// {D1256573-7560-41db-A781-9985AE50CE07} | |
372 | +static const GUID cfg_debug_dummyamp_proc_guid = { 0xd1256573, 0x7560, 0x41db, { 0xa7, 0x81, 0x99, 0x85, 0xae, 0x50, 0xce, 0x7 } }; | |
373 | +static cfg_int cfg_debug_dummyamp_proc(cfg_debug_dummyamp_proc_guid, 1); // debug level | |
374 | +// {0A7E2CAE-905F-4ecb-A82D-8DD853FBFFF3} | |
375 | +static const GUID cfg_debug_track_info_guid = { 0xa7e2cae, 0x905f, 0x4ecb, { 0xa8, 0x2d, 0x8d, 0xd8, 0x53, 0xfb, 0xff, 0xf3 } }; | |
376 | +static cfg_int cfg_debug_track_info(cfg_debug_track_info_guid, 1); // debug level | |
377 | +// {67A78DB7-3591-4416-84FC-96436082B619} | |
378 | +static const GUID cfg_debug_plugin_guid = { 0x67a78db7, 0x3591, 0x4416, { 0x84, 0xfc, 0x96, 0x43, 0x60, 0x82, 0xb6, 0x19 } }; | |
379 | +static cfg_int cfg_debug_plugin(cfg_debug_plugin_guid, 1); // debug level | |
380 | +// {DBED8400-527F-4b98-9227-2C0BA95B3206} | |
381 | +static const GUID cfg_debug_callback_guid = { 0xdbed8400, 0x527f, 0x4b98, { 0x92, 0x27, 0x2c, 0xb, 0xa9, 0x5b, 0x32, 0x6 } }; | |
382 | +static cfg_int cfg_debug_callback(cfg_debug_callback_guid, 1); // debug level | |
383 | +#endif | |
384 | + | |
385 | +class TrackInfo | |
386 | +{ | |
387 | +public: | |
388 | + std::string m_nullStr; | |
389 | + | |
390 | + StringMap m_infoMap8; | |
391 | + StringMap m_infoMapAnsi; | |
392 | + | |
393 | + UIntMap m_infoMapNum; | |
394 | + | |
395 | + TrackInfo() { | |
396 | + } | |
397 | + | |
398 | + TrackInfo(const TrackInfo &other) | |
399 | + : m_infoMap8(other.m_infoMap8) | |
400 | + , m_infoMapAnsi(other.m_infoMapAnsi) | |
401 | + , m_infoMapNum(other.m_infoMapNum) { | |
402 | + } | |
403 | + | |
404 | + ~TrackInfo() { | |
405 | + } | |
406 | + | |
407 | + TrackInfo &operator =(const TrackInfo &other) | |
408 | + { | |
409 | + TrackInfo temp(other); | |
410 | + swap(temp); | |
411 | + | |
412 | + return *this; | |
413 | + } | |
414 | + | |
415 | + void show_map(StringMap &map, bool bAnsi = false) | |
416 | + { | |
417 | + StringMapCIt beginIt(map.begin()), endIt(map.end()), it; | |
418 | + | |
419 | + for(it = beginIt; it != endIt; it ++) { | |
420 | + | |
421 | + if(bAnsi) { | |
422 | + TRACE_TRACK_INFO_ANSI("show_map_ansi: [%s, %s]", it->first.c_str(), it->second.c_str()); | |
423 | + } else { | |
424 | + TRACE_TRACK_INFO8("show_map8: [%s, %s]", it->first.c_str(), it->second.c_str()); | |
425 | + } | |
426 | + } | |
427 | + } | |
428 | + | |
429 | + void swap(TrackInfo &other) | |
430 | + { | |
431 | + m_infoMap8.swap(other.m_infoMap8); | |
432 | + m_infoMapAnsi.swap(other.m_infoMapAnsi); | |
433 | + m_infoMapNum.swap(other.m_infoMapNum); | |
434 | + } | |
435 | + | |
436 | + void clear() | |
437 | + { | |
438 | + TRACE_TRACK_INFO(_T("TRACK_INFO::clear - called.")); | |
439 | + | |
440 | + m_infoMap8.clear(); | |
441 | + m_infoMapAnsi.clear(); | |
442 | + m_infoMapNum.clear(); | |
443 | + } | |
444 | + | |
445 | + bool isEmpty() const { return m_infoMap8.empty() & m_infoMapNum.empty(); } | |
446 | + | |
447 | +public: | |
448 | + | |
449 | +#if IS_FB2K_VER08 | |
450 | + void setStrings(const Strings &keys, metadb_handle * track) | |
451 | +#elif IS_FB2K_VER09 | |
452 | + void setStrings(const Strings &keys, metadb_handle_ptr track) | |
453 | +#endif | |
454 | + { | |
455 | + TRACE_TRACK_INFO(_T("TrackInfo::setStrings - called.")); | |
456 | + | |
457 | + StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
458 | + | |
459 | + for(it = beginIt; it != endIt; it ++) { | |
460 | + | |
461 | + string8 info8; | |
462 | + | |
463 | +#if IS_FB2K_VER08 | |
464 | + track->handle_format_title(info8, it->c_str(), 0); | |
465 | +#elif IS_FB2K_VER09 | |
466 | + service_ptr_t<titleformat_object> titleformat; | |
467 | + | |
468 | + static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, it->c_str()); | |
469 | + track->format_title(NULL, info8, titleformat, 0); | |
470 | +#endif | |
471 | +// DEBUG_TRACK_INFO8("TrackInfo::setStrings - %s: %s", it->c_str(), (LPCSTR)info8); | |
472 | + | |
473 | + putString(it->c_str(), (LPCSTR)info8); | |
474 | + } | |
475 | + } | |
476 | + | |
477 | + void setDynamicStrings(const Strings &keys) | |
478 | + { | |
479 | + TRACE_TRACK_INFO(_T("TrackInfo::setDynamicStrings - called.")); | |
480 | + | |
481 | +#if IS_FB2K_VER08 | |
482 | + metadb_handle *track = play_control::get()->get_now_playing(); | |
483 | +#elif IS_FB2K_VER09 | |
484 | + metadb_handle_ptr track; | |
485 | + static_api_ptr_t<playback_control>()->get_now_playing(track); | |
486 | +#endif | |
487 | + | |
488 | + StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
489 | + | |
490 | + for(it = beginIt; it != endIt; it ++) { | |
491 | + | |
492 | + string8 info8; | |
493 | + | |
494 | +#if IS_FB2K_VER08 | |
495 | + play_control::get()->playback_format_title_ex(track, info8, it->c_str(), NULL, false, true); | |
496 | +#elif IS_FB2K_VER09 | |
497 | + service_ptr_t<titleformat_object> titleformat; | |
498 | + | |
499 | + static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, it->c_str()); | |
500 | + static_api_ptr_t<playback_control>()->playback_format_title_ex(track, NULL, info8, titleformat, NULL, play_control::display_level_titles); | |
501 | +#endif | |
502 | +// DEBUG_TRACK_INFO8("TrackInfo::setDynamicStrings - %s: %s", it->c_str(), (LPCSTR)info8); | |
503 | + | |
504 | + const std::string &oldValue = getString(*it); | |
505 | + | |
506 | + if((::lstrcmpA(info8, "?") != 0) || (oldValue.length() == 0)) | |
507 | + { | |
508 | + putString(it->c_str(), (LPCSTR)info8); | |
509 | + } | |
510 | + } | |
511 | + | |
512 | +#if IS_FB2K_VER08 | |
513 | + if(track) { | |
514 | + track->handle_release(); | |
515 | + } | |
516 | +#endif | |
517 | + } | |
518 | + | |
519 | + void setPlaylistStrings(const Strings &keys) | |
520 | + { | |
521 | + TRACE_TRACK_INFO(_T("TrackInfo::setPlaylistStrings - called.")); | |
522 | + | |
523 | +#if IS_FB2K_VER08 | |
524 | + int track_index; | |
525 | + track_index = playlist_oper::get()->get_now_playing(); | |
526 | +#elif IS_FB2K_VER09 | |
527 | + t_size playlist_index, track_index; | |
528 | + static_api_ptr_t<playlist_manager>()->get_playing_item_location(&playlist_index, &track_index); | |
529 | +#endif | |
530 | + | |
531 | + StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
532 | + | |
533 | + for(it = beginIt; it != endIt; it ++) { | |
534 | + | |
535 | + string8 info8; | |
536 | + | |
537 | +#if IS_FB2K_VER08 | |
538 | + playlist_oper::get()->format_title(track_index, info8, it->c_str(), NULL); | |
539 | +#elif IS_FB2K_VER09 | |
540 | + service_ptr_t<titleformat_object> titleformat; | |
541 | + | |
542 | + static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, it->c_str()); | |
543 | + static_api_ptr_t<playlist_manager>()->playlist_item_format_title(playlist_index, track_index, | |
544 | + NULL, info8, titleformat, NULL, play_control::display_level_titles); | |
545 | +#endif | |
546 | +// DEBUG_TRACK_INFO8("TrackInfo::setPlaylistStrings - %s: %s", it->c_str(), (LPCSTR)info8); | |
547 | + | |
548 | + putString(it->c_str(), (LPCSTR)info8); | |
549 | + } | |
550 | + } | |
551 | + | |
552 | +#if IS_FB2K_VER08 | |
553 | + void setNumbers(const Strings &keys, metadb_handle * track) | |
554 | +#elif IS_FB2K_VER09 | |
555 | + void setNumbers(const Strings &keys, metadb_handle_ptr track) | |
556 | +#endif | |
557 | + { | |
558 | + TRACE_TRACK_INFO(_T("TrackInfo::setNumbers - called.")); | |
559 | + | |
560 | + StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
561 | + | |
562 | + for(it = beginIt; it != endIt; it ++) { | |
563 | + | |
564 | + string8 info8; | |
565 | + | |
566 | +#if IS_FB2K_VER08 | |
567 | + track->handle_format_title(info8, it->c_str(), 0); | |
568 | +#elif IS_FB2K_VER09 | |
569 | + service_ptr_t<titleformat_object> titleformat; | |
570 | + | |
571 | + static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, it->c_str()); | |
572 | + track->format_title(NULL, info8, titleformat, 0); | |
573 | +#endif | |
574 | +// DEBUG_TRACK_INFO8("TrackInfo::setNumbers - %s: %s", it->c_str(), (LPCSTR)info8); | |
575 | + | |
576 | + putNumber(it->c_str(), static_cast<UINT>(::atol(info8)) ); | |
577 | + } | |
578 | + } | |
579 | + | |
580 | + void setDynamicNumbers(const Strings &keys) | |
581 | + { | |
582 | + TRACE_TRACK_INFO(_T("TrackInfo::setDynamicNumbers - called.")); | |
583 | + | |
584 | +#if IS_FB2K_VER08 | |
585 | + metadb_handle *track = play_control::get()->get_now_playing(); | |
586 | +#elif IS_FB2K_VER09 | |
587 | + metadb_handle_ptr track; | |
588 | + static_api_ptr_t<playback_control>()->get_now_playing(track); | |
589 | +#endif | |
590 | + | |
591 | + StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
592 | + | |
593 | + for(it = beginIt; it != endIt; it ++) { | |
594 | + | |
595 | + string8 info8; | |
596 | + | |
597 | +#if IS_FB2K_VER08 | |
598 | + play_control::get()->playback_format_title_ex(track, info8, it->c_str(), NULL, false, true); | |
599 | +#elif IS_FB2K_VER09 | |
600 | + service_ptr_t<titleformat_object> titleformat; | |
601 | + | |
602 | + static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, it->c_str()); | |
603 | + static_api_ptr_t<playback_control>()->playback_format_title_ex(track, NULL, info8, titleformat, NULL, play_control::display_level_titles); | |
604 | +#endif | |
605 | +// DEBUG_TRACK_INFO8("TrackInfo::setDynamicNumbers - %s: %s", it->c_str(), (LPCSTR)info8); | |
606 | + | |
607 | + UINT newValue = static_cast<UINT>(::atol(info8)); | |
608 | + UINT oldValue = getNumber(*it); | |
609 | + | |
610 | + if((newValue != 0) || (oldValue == 0)) { | |
611 | + putNumber(it->c_str(), newValue); | |
612 | + } | |
613 | + } | |
614 | + | |
615 | +#if IS_FB2K_VER08 | |
616 | + if(track) { | |
617 | + track->handle_release(); | |
618 | + } | |
619 | +#endif | |
620 | + } | |
621 | + | |
622 | + void setPlaylistNumbers(const Strings &keys) | |
623 | + { | |
624 | + TRACE_TRACK_INFO(_T("TrackInfo::setPlaylistNumbers - called.")); | |
625 | + | |
626 | +#if IS_FB2K_VER08 | |
627 | + int track_index; | |
628 | + track_index = playlist_oper::get()->get_now_playing(); | |
629 | +#elif IS_FB2K_VER09 | |
630 | + t_size playlist_index, track_index; | |
631 | + static_api_ptr_t<playlist_manager>()->get_playing_item_location(&playlist_index, &track_index); | |
632 | +#endif | |
633 | + | |
634 | + StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
635 | + | |
636 | + for(it = beginIt; it != endIt; it ++) { | |
637 | + | |
638 | + string8 info8; | |
639 | + | |
640 | +#if IS_FB2K_VER08 | |
641 | + playlist_oper::get()->format_title(track_index, info8, it->c_str(), NULL); | |
642 | +#elif IS_FB2K_VER09 | |
643 | + service_ptr_t<titleformat_object> titleformat; | |
644 | + | |
645 | + static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, it->c_str()); | |
646 | + static_api_ptr_t<playlist_manager>()->playlist_item_format_title(playlist_index, track_index, | |
647 | + NULL, info8, titleformat, NULL, play_control::display_level_titles); | |
648 | +#endif | |
649 | +// DEBUG_TRACK_INFO8("TrackInfo::setPlaylistNumbers - %s: %s", it->c_str(), (LPCSTR)info8); | |
650 | + | |
651 | + putNumber(it->c_str(), static_cast<UINT>(::atol(info8)) ); | |
652 | + } | |
653 | + } | |
654 | + | |
655 | + void putString(const std::string &key, const std::string &value) | |
656 | + { | |
657 | + DEBUG_TRACK_INFO8("TrackInfo::putString - %s: %s", key.c_str(), value.c_str()); | |
658 | + | |
659 | + insert(m_infoMap8, key.c_str(), value.c_str()); | |
660 | + | |
661 | + string_ansi_from_utf8 valueAnsi(value.c_str()); | |
662 | + | |
663 | + insert(m_infoMapAnsi, key.c_str(), (LPCSTR)valueAnsi, true); | |
664 | + } | |
665 | + | |
666 | + void putNumber(const std::string &key, UINT value) | |
667 | + { | |
668 | + DEBUG_TRACK_INFO8("TrackInfo::putNumber - %s: %u", key.c_str(), value); | |
669 | + | |
670 | + insert(m_infoMapNum, key.c_str(), value); | |
671 | + } | |
672 | + | |
673 | + const std::string &getString(const std::string &key, bool bForceUTF8 = false) const { | |
674 | + | |
675 | + if((bForceUTF8 == true) || (cfg_disable_ansi_trans == 1)) | |
676 | + { | |
677 | + StringMapCIt it(m_infoMap8.find(key)), endIt(m_infoMap8.end()); | |
678 | + | |
679 | + if(it == endIt) { | |
680 | + return m_nullStr; | |
681 | + } | |
682 | + | |
683 | + return it->second; | |
684 | + } | |
685 | + else | |
686 | + { | |
687 | + StringMapCIt it(m_infoMapAnsi.find(key)), endIt(m_infoMapAnsi.end()); | |
688 | + | |
689 | + if(it == endIt) { | |
690 | + return m_nullStr; | |
691 | + } | |
692 | + | |
693 | + return it->second; | |
694 | + } | |
695 | + } | |
696 | + | |
697 | + const UINT getNumber(const std::string &key) const { | |
698 | + | |
699 | + UIntMapCIt it(m_infoMapNum.find(key)), endIt(m_infoMapNum.end()); | |
700 | + | |
701 | + if(it == endIt) { | |
702 | + return 0; | |
703 | + } | |
704 | + | |
705 | + return it->second; | |
706 | + } | |
707 | + | |
708 | + void removeStrings(const Strings &keys) | |
709 | + { | |
710 | + TRACE_TRACK_INFO(_T("TrackInfo::removeStrings - called.")); | |
711 | + | |
712 | + StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
713 | + | |
714 | + for(it = beginIt; it != endIt; it ++) { | |
715 | + removeString(*it); | |
716 | + } | |
717 | + } | |
718 | + | |
719 | + void removeString(const std::string &key) | |
720 | + { | |
721 | + TRACE_TRACK_INFO8("TrackInfo::removeString - %s", key.c_str()); | |
722 | + | |
723 | + m_infoMap8.erase(m_infoMap8.find(key)); | |
724 | + m_infoMapAnsi.erase(m_infoMapAnsi.find(key)); | |
725 | + } | |
726 | + | |
727 | + void removeNumbers(const Strings &keys) | |
728 | + { | |
729 | + TRACE_TRACK_INFO(_T("TrackInfo::removeNumbers - called.")); | |
730 | + | |
731 | + StringsCIt beginIt(keys.begin()), endIt(keys.end()), it; | |
732 | + | |
733 | + for(it = beginIt; it != endIt; it ++) { | |
734 | + removeNumber(*it); | |
735 | + } | |
736 | + } | |
737 | + | |
738 | + void removeNumber(const std::string &key) | |
739 | + { | |
740 | + TRACE_TRACK_INFO8("TrackInfo::removeNumber - %s", key.c_str()); | |
741 | + | |
742 | + m_infoMapNum.erase(m_infoMapNum.find(key)); | |
743 | + } | |
744 | + | |
745 | +protected: | |
746 | + | |
747 | + static void insert(StringMap &map, LPCSTR pKey, LPCSTR pValue, bool bAnsi = false) | |
748 | + { | |
749 | +#if 0 | |
750 | + if(bAnsi) { | |
751 | + TRACE_TRACK_INFO_ANSI("insertAnsi: [%s, %s]", pKey, pValue); | |
752 | + } else { | |
753 | + TRACE_TRACK_INFO8("insert8: [%s, %s]", pKey, pValue); | |
754 | + } | |
755 | +#endif | |
756 | + | |
757 | + map.insert(std::make_pair(pKey, pValue)); | |
758 | + } | |
759 | + | |
760 | + static void insert(UIntMap &map, LPCSTR pKey, UINT value) | |
761 | + { | |
762 | +// TRACE_TRACK_INFO8("insertNum: [%s, %u]", pKey, value); | |
763 | + | |
764 | + map.insert(std::make_pair(pKey, value)); | |
765 | + } | |
766 | +}; | |
767 | + | |
768 | +class PathInfo | |
769 | +{ | |
770 | + protected: | |
771 | + PathInfo() { | |
772 | + } | |
773 | + | |
774 | + public: | |
775 | + static tstring getFB2Kpath() | |
776 | + { | |
777 | + TCHAR modulePath[_MAX_PATH], moduleDrive[_MAX_DRIVE], moduleDir[_MAX_DIR]; | |
778 | + TCHAR returnPath[_MAX_PATH]; | |
779 | + | |
780 | + ::GetModuleFileName(NULL, modulePath, _MAX_PATH); | |
781 | + ::_tsplitpath_s(modulePath, moduleDrive, _MAX_DRIVE, moduleDir, _MAX_DIR, NULL, 0, NULL, 0); | |
782 | + ::_tmakepath_s(returnPath, _MAX_PATH, moduleDrive, moduleDir, NULL, NULL); | |
783 | + | |
784 | + return tstring(returnPath); | |
785 | + } | |
786 | + | |
787 | + static tstring getFB2KComponentsPath() { | |
788 | + return getFB2Kpath() + FB2K_COMPONENTS_DIR; | |
789 | + } | |
790 | + | |
791 | + static std::string getGenMixiDefaultPath() | |
792 | + { | |
793 | + string_utf8_from_os path(getFB2KComponentsPath().c_str()); | |
794 | + return (LPCSTR)path; | |
795 | + } | |
796 | + | |
797 | + static tstring getMixiStationAppPath() { | |
798 | + return getSpecialFolderPath(CSIDL_APPDATA, FALSE) + APPDATA_MIXI_STATION_DIR; | |
799 | + } | |
800 | + | |
801 | + static tstring getFooMixiPlayInfoPath() | |
802 | + { | |
803 | + switch(cfg_dummy_mp3_location) | |
804 | + { | |
805 | + case 1: | |
806 | + return getTemporaryFolderPath(); | |
807 | + | |
808 | + case 2: | |
809 | + return getFB2KComponentsPath() ; | |
810 | + | |
811 | + case 0: | |
812 | + default: | |
813 | + return getMixiStationAppPath() + _T("\\"); | |
814 | + } | |
815 | + } | |
816 | + | |
817 | + static tstring getDummyPlayInfoMp3Path() { | |
818 | + return getFooMixiPlayInfoPath() + DUMMY_MP3_FILE_NAME; | |
819 | + } | |
820 | + | |
821 | + static tstring splitPath(const string8 &srcPath) | |
822 | + { | |
823 | + string_os_from_utf8 srcPathOs(srcPath); | |
824 | + return splitPath(srcPathOs); | |
825 | + } | |
826 | + | |
827 | + static tstring splitPath(LPCTSTR srcPath) | |
828 | + { | |
829 | + TCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], dstPath[_MAX_PATH]; | |
830 | + ::_tsplitpath_s(srcPath, drive, _MAX_DRIVE, dir, _MAX_DIR, NULL, 0, NULL, 0); | |
831 | + ::_tmakepath_s(dstPath, _MAX_PATH, drive, dir, NULL, NULL); | |
832 | + return dstPath; | |
833 | + } | |
834 | + | |
835 | + //! get the special folder path | |
836 | + static tstring getSpecialFolderPath(int nFolder, BOOL bCreate) | |
837 | + { | |
838 | + tstring resStr; | |
839 | + HRESULT hr = NO_ERROR; | |
840 | + | |
841 | + IMalloc *pMalloc = 0; | |
842 | + ITEMIDLIST *pItemID = 0; | |
843 | + TCHAR folderPath[MAX_PATH]; | |
844 | + | |
845 | + folderPath[0] = _T('\0'); | |
846 | + hr = SHGetMalloc(&pMalloc); | |
847 | + | |
848 | + if(hr == NO_ERROR) | |
849 | + { | |
850 | + hr = SHGetSpecialFolderLocation(0, nFolder, &pItemID); | |
851 | + | |
852 | + if(hr == NO_ERROR) | |
853 | + { | |
854 | + if(SHGetPathFromIDList(pItemID, folderPath) == FALSE) | |
855 | + hr = GetLastError(); | |
856 | + | |
857 | + pMalloc->Free(pItemID); | |
858 | + } | |
859 | + | |
860 | + pMalloc->Release(); | |
861 | + } | |
862 | + | |
863 | + resStr = folderPath; | |
864 | + | |
865 | + if(hr != NO_ERROR) | |
866 | + { | |
867 | + return _T(""); | |
868 | + } | |
869 | + | |
870 | + return resStr; | |
871 | + } | |
872 | + | |
873 | + //! get the temporary folder path | |
874 | + static tstring getTemporaryFolderPath() { | |
875 | + | |
876 | + TCHAR strTempPath[MAX_PATH]; | |
877 | + ::GetTempPath(MAX_PATH, strTempPath); | |
878 | + | |
879 | + return strTempPath; | |
880 | + } | |
881 | +}; | |
882 | + | |
883 | +#if IS_FB2K_VER08 | |
884 | +static cfg_string cfg_gen_mixi_path("GenMixiPath", PathInfo::getGenMixiDefaultPath().c_str()); | |
885 | +#elif IS_FB2K_VER09 | |
886 | +// {1EC28435-C243-483c-81EC-E0E57A96727E} | |
887 | +static const GUID cfg_gen_mixi_path_guid = { 0x1ec28435, 0xc243, 0x483c, { 0x81, 0xec, 0xe0, 0xe5, 0x7a, 0x96, 0x72, 0x7e } }; | |
888 | +static cfg_string cfg_gen_mixi_path(cfg_gen_mixi_path_guid, PathInfo::getGenMixiDefaultPath().c_str()); | |
889 | +#endif | |
890 | + | |
891 | +class PlayInfo | |
892 | +{ | |
893 | + public: | |
894 | + | |
895 | + enum EPlayStatus | |
896 | + { | |
897 | + PLAY_STOP = 0, | |
898 | + PLAY_START = 1, | |
899 | + PLAY_PAUSE = 3 | |
900 | + }; | |
901 | + | |
902 | + public: | |
903 | + | |
904 | + PlayInfo() : | |
905 | + m_playStatus(PLAY_STOP), | |
906 | + m_isResentMode(false), | |
907 | + m_playLength(0), | |
908 | + m_playPosition(0), | |
909 | + m_playCount(0), | |
910 | + m_isPlayInfoMp3Available(false), | |
911 | + m_resetBasePosition(0) { | |
912 | + } | |
913 | + | |
914 | + public: | |
915 | + | |
916 | + void setPlayStatusStart() { | |
917 | + setPlayStatus(PLAY_START); | |
918 | + } | |
919 | + | |
920 | + void setPlayStatusStop() { | |
921 | + setPlayStatus(PLAY_STOP); | |
922 | + } | |
923 | + | |
924 | + void setPlayStatusPause() { | |
925 | + setPlayStatus(PLAY_PAUSE); | |
926 | + } | |
927 | + | |
928 | + void clearPlayInfo(bool isResentMode = true) | |
929 | + { | |
930 | + setPlayStatusStop(); | |
931 | + m_isResentMode = isResentMode; | |
932 | + setPlayPosition(0); | |
933 | + setPlayLength(0); | |
934 | + setPlayInfoMp3Available(false); | |
935 | + m_resetBasePosition = 0; | |
936 | + } | |
937 | + | |
938 | + void setResentMode(bool bIncrementCounter = true) | |
939 | + { | |
940 | + if(bIncrementCounter) { | |
941 | + incrementPlayCount(); | |
942 | + } | |
943 | + m_isResentMode = true; | |
944 | + m_resetBasePosition = m_playPosition; | |
945 | + } | |
946 | + | |
947 | + void clearResentMode() { | |
948 | + m_isResentMode = false; | |
949 | + } | |
950 | + | |
951 | + void incrementPlayCount() { | |
952 | + setPlayCount(getPlayCount() + 1); | |
953 | + } | |
954 | + | |
955 | + public: | |
956 | + | |
957 | + EPlayStatus getPlayStatus() const | |
958 | + { | |
959 | + if((m_playStatus == PLAY_START) && m_isResentMode) { | |
960 | + return PLAY_STOP; | |
961 | + } | |
962 | + return m_playStatus; | |
963 | + } | |
964 | + | |
965 | + void setPlayStatus(EPlayStatus status) { | |
966 | + m_playStatus = status; | |
967 | + } | |
968 | + | |
969 | + int getPlayPosition() const | |
970 | + { | |
971 | + if(m_resetBasePosition > 0) { | |
972 | + return m_playPosition - m_resetBasePosition; | |
973 | + } | |
974 | + return m_playPosition; | |
975 | + } | |
976 | + | |
977 | + void setPlayPosition(int pos) { | |
978 | + m_playPosition = pos; | |
979 | + } | |
980 | + | |
981 | + int getPlayLength() const | |
982 | + { | |
983 | +#if FORCE_RESENT_MODE == 0 | |
984 | + if(m_resetBasePosition > 0) { | |
985 | +#else | |
986 | + if(true) { | |
987 | +#endif | |
988 | + return GEN_MIXI_REQUIRED_SECONDS; | |
989 | + } | |
990 | + return m_playLength; | |
991 | + } | |
992 | + | |
993 | + void setPlayLength(int len) { | |
994 | + m_playLength = len; | |
995 | + } | |
996 | + | |
997 | + int getPlayCount() const { | |
998 | + return m_playCount; | |
999 | + } | |
1000 | + | |
1001 | + void setPlayCount(int count) { | |
1002 | + m_playCount = count; | |
1003 | + } | |
1004 | + | |
1005 | + bool isPlayInfoMp3Available() const { | |
1006 | + return m_isPlayInfoMp3Available; | |
1007 | + } | |
1008 | + | |
1009 | + void setPlayInfoMp3Available(bool isAvailable) { | |
1010 | + m_isPlayInfoMp3Available = isAvailable; | |
1011 | + } | |
1012 | + | |
1013 | + void setPlayInfoMp3Path(LPCSTR path) | |
1014 | + { | |
1015 | +#if 0 | |
1016 | + m_playInfoMp3Path = path; | |
1017 | + | |
1018 | + string_utf8_from_os path8(path); | |
1019 | + | |
1020 | + if(cfg_disable_ansi_trans == 1) | |
1021 | + { | |
1022 | + | |
1023 | + m_playInfoMp3Path8 = path8; | |
1024 | + } | |
1025 | + else | |
1026 | + { | |
1027 | + string_ansi_from_utf8 pathAnsi(path8); | |
1028 | + | |
1029 | + m_playInfoMp3Path8 = pathAnsi; | |
1030 | + } | |
1031 | +#else | |
1032 | + m_playInfoMp3Path8 = path; | |
1033 | +#endif | |
1034 | + } | |
1035 | + | |
1036 | + const string8 &getPlayInfoMp3Path8() const { | |
1037 | + return m_playInfoMp3Path8; | |
1038 | + } | |
1039 | + | |
1040 | + bool isResentMode() const { | |
1041 | + return m_isResentMode; | |
1042 | + } | |
1043 | + | |
1044 | + protected: | |
1045 | + | |
1046 | + EPlayStatus m_playStatus; | |
1047 | + | |
1048 | + int m_playLength; | |
1049 | + int m_playPosition; | |
1050 | + int m_playCount; | |
1051 | + | |
1052 | + bool m_isPlayInfoMp3Available; | |
1053 | + bool m_isResentMode; | |
1054 | + int m_resetBasePosition; | |
1055 | + | |
1056 | + string8 m_playInfoMp3Path8; | |
1057 | +}; | |
1058 | + | |
1059 | +class id3Info | |
1060 | +{ | |
1061 | + public: | |
1062 | + | |
1063 | + typedef std::vector<UINT16> UInt16Array; | |
1064 | + | |
1065 | + id3Info(const TrackInfo & info) : m_info(info), m_hMp3File(INVALID_HANDLE_VALUE) { | |
1066 | + } | |
1067 | + | |
1068 | + ~id3Info() { | |
1069 | + close(); | |
1070 | + } | |
1071 | + | |
1072 | + DWORD write(LPCTSTR path) { | |
1073 | + | |
1074 | + string_wide_from_utf8 title_utf16(m_info.getString(FORMAT_TRACKTITLE, true).c_str()); | |
1075 | + string_wide_from_utf8 artist_utf16(m_info.getString(FORMAT_ARTIST, true).c_str()); | |
1076 | + string_wide_from_utf8 album_utf16(m_info.getString(FORMAT_ALBUMTITLE, true).c_str()); | |
1077 | + string_wide_from_utf8 genre_utf16(m_info.getString(FORMAT_GENRE, true).c_str()); | |
1078 | + | |
1079 | + DWORD dwErr = S_OK; | |
1080 | + | |
1081 | + if((dwErr = open(path)) != S_OK) { | |
1082 | + return dwErr; | |
1083 | + } | |
1084 | + | |
1085 | + UInt16Array title = makeTextFrame("TIT2", makeUTF16LE(title_utf16)); | |
1086 | + UInt16Array album = makeTextFrame("TALB", makeUTF16LE(album_utf16)); | |
1087 | + UInt16Array artist = makeTextFrame("TPE1", makeUTF16LE(artist_utf16)); | |
1088 | + UInt16Array genre = makeTextFrame("TCON", makeUTF16LE(genre_utf16)); | |
1089 | + | |
1090 | + dwErr = writeHeader(static_cast<UINT32>( | |
1091 | + title.size()*2 + album.size()*2 + artist.size()*2 + genre.size()*2 + 4)); | |
1092 | + // add charset code size (4bytes) | |
1093 | + | |
1094 | + if(dwErr == S_OK) { | |
1095 | + dwErr = writeTextFrame(title); | |
1096 | + } | |
1097 | + | |
1098 | + if(dwErr == S_OK) { | |
1099 | + dwErr = writeTextFrame(album); | |
1100 | + } | |
1101 | + | |
1102 | + if(dwErr == S_OK) { | |
1103 | + dwErr = writeTextFrame(artist); | |
1104 | + } | |
1105 | + | |
1106 | + if(dwErr == S_OK) { | |
1107 | + dwErr = writeTextFrame(genre); | |
1108 | + } | |
1109 | + | |
1110 | + close(); | |
1111 | + | |
1112 | + return dwErr; | |
1113 | + } | |
1114 | + | |
1115 | + protected: | |
1116 | + | |
1117 | + DWORD open(LPCTSTR path) | |
1118 | + { | |
1119 | + close(); | |
1120 | + | |
1121 | + // open dummy mp3 file | |
1122 | + m_hMp3File = ::CreateFile( | |
1123 | + path, GENERIC_WRITE, 0, NULL, | |
1124 | + TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL | |
1125 | + ); | |
1126 | + | |
1127 | + if(m_hMp3File == INVALID_HANDLE_VALUE) | |
1128 | + { | |
1129 | + return ::GetLastError(); | |
1130 | + } | |
1131 | + | |
1132 | + return S_OK; | |
1133 | + } | |
1134 | + | |
1135 | + UInt16Array makeUTF16LE(const string_wide_from_utf8 &str) { | |
1136 | + | |
1137 | + LPCWSTR pStr = str.get_ptr(); | |
1138 | + size_t len = ::lstrlenW(pStr); | |
1139 | + UInt16Array utf16(len + 2); | |
1140 | + | |
1141 | + utf16[0] = 0xfeff; // BOM | |
1142 | + ::CopyMemory(&utf16[1], str.get_ptr(), len * 2); | |
1143 | + | |
1144 | + // swap byte order (big endian to little endian); | |
1145 | + for(size_t i = 0; i < len + 1; i++) { | |
1146 | + utf16[i] = (utf16[i] << 8) | (utf16[i] >> 8); | |
1147 | + } | |
1148 | + | |
1149 | + utf16[len + 1] = 0; // add NULL character | |
1150 | + | |
1151 | + return utf16; | |
1152 | + } | |
1153 | + | |
1154 | + UInt16Array makeTextFrame(LPCSTR pFrameID, const UInt16Array &data) { | |
1155 | + | |
1156 | + UInt16Array frame(data.size() + 5); | |
1157 | + | |
1158 | + UINT32 size = static_cast<UINT32>(data.size() * 2 + 1); // add charset code size (1byte) | |
1159 | + | |
1160 | + const UCHAR *pUCFrameID = reinterpret_cast<const UCHAR *>(pFrameID); | |
1161 | + const UCHAR *pUCSize = reinterpret_cast<const UCHAR *>(&size); | |
1162 | + | |
1163 | + frame[0] = ((UINT16)pUCFrameID[1]) << 8 | pUCFrameID[0]; | |
1164 | + frame[1] = ((UINT16)pUCFrameID[3]) << 8 | pUCFrameID[2]; | |
1165 | + | |
1166 | + frame[2] = ((UINT16)pUCSize[2]) << 8 | pUCSize[3]; | |
1167 | + frame[3] = ((UINT16)pUCSize[0]) << 8 | pUCSize[1]; | |
1168 | + | |
1169 | + frame[4] = 0; // frame flag | |
1170 | + | |
1171 | + ::CopyMemory(&frame[5], &data[0], data.size() * 2); | |
1172 | + | |
1173 | + return frame; | |
1174 | + } | |
1175 | + | |
1176 | + void close() { | |
1177 | + if(m_hMp3File != INVALID_HANDLE_VALUE) { | |
1178 | + ::CloseHandle(m_hMp3File); | |
1179 | + m_hMp3File = INVALID_HANDLE_VALUE; | |
1180 | + } | |
1181 | + } | |
1182 | + | |
1183 | + DWORD writeHeader(UINT32 size) | |
1184 | + { | |
1185 | + UInt16Array header(5); | |
1186 | + | |
1187 | + header[0] = ((UINT16)'D') << 8 | (UCHAR)'I'; | |
1188 | + header[1] = ((UINT16) 3 ) << 8 | (UCHAR)'3'; | |
1189 | + | |
1190 | + header[2] = 0; | |
1191 | + | |
1192 | + UInt16Array length = makeLength(size); | |
1193 | + | |
1194 | + header[3] = length[0]; | |
1195 | + header[4] = length[1]; | |
1196 | + | |
1197 | + DWORD dwSize; | |
1198 | + if(!::WriteFile(m_hMp3File, &header[0], 10, &dwSize, NULL)) { | |
1199 | + return ::GetLastError(); | |
1200 | + } | |
1201 | + | |
1202 | + return S_OK; | |
1203 | + } | |
1204 | + | |
1205 | + DWORD writeTextFrame(const UInt16Array &packet) | |
1206 | + { | |
1207 | + DWORD dwErr = S_OK; | |
1208 | + | |
1209 | + UCHAR charsetCode = 0x01; // UNICODE | |
1210 | + | |
1211 | + DWORD dwSize; | |
1212 | + if(!::WriteFile(m_hMp3File, &packet[0], 10, &dwSize, NULL)) { | |
1213 | + return ::GetLastError(); | |
1214 | + } | |
1215 | + if(!::WriteFile(m_hMp3File, &charsetCode, 1, &dwSize, NULL)) { | |
1216 | + return ::GetLastError(); | |
1217 | + } | |
1218 | + if(!::WriteFile(m_hMp3File, &packet[5], static_cast<DWORD>(packet.size() * 2 - 10), &dwSize, NULL)) { | |
1219 | + return ::GetLastError(); | |
1220 | + } | |
1221 | + | |
1222 | + return S_OK; | |
1223 | + } | |
1224 | + | |
1225 | + UInt16Array makeLength(UINT32 size) | |
1226 | + { | |
1227 | + UInt16Array length(2); | |
1228 | + UCHAR sizes[4]; | |
1229 | + | |
1230 | + /* | |
1231 | + 00001111111111111111111111111111 | |
1232 | + | |
1233 | + 1111111000000000000000000000 | |
1234 | + f e 0 0 0 0 0 | |
1235 | + 111111100000000000000 | |
1236 | + 1 f c 0 0 0 | |
1237 | + 11111110000000 | |
1238 | + 3 f 8 0 | |
1239 | + 1111111 | |
1240 | + 7 f | |
1241 | + */ | |
1242 | + | |
1243 | + sizes[3] = static_cast<UCHAR>((size & 0x0000007f) >> 0); | |
1244 | + sizes[2] = static_cast<UCHAR>((size & 0x00003f80) >> 7); | |
1245 | + sizes[1] = static_cast<UCHAR>((size & 0x001fc000) >> 14); | |
1246 | + sizes[0] = static_cast<UCHAR>((size & 0x0fe00000) >> 21); | |
1247 | + | |
1248 | + | |
1249 | + length[0] = ((UINT16)sizes[1]) << 8 | sizes[0]; | |
1250 | + length[1] = ((UINT16)sizes[3]) << 8 | sizes[2]; | |
1251 | + | |
1252 | + return length; | |
1253 | + } | |
1254 | + | |
1255 | + protected: | |
1256 | + | |
1257 | + TrackInfo m_info; | |
1258 | + HANDLE m_hMp3File; | |
1259 | +}; | |
1260 | + | |
1261 | +class DummyAmp | |
1262 | +{ | |
1263 | + public: | |
1264 | + | |
1265 | + DummyAmp() | |
1266 | + : m_bReady(false) | |
1267 | + , m_hInstGenMixi((HINSTANCE)INVALID_HANDLE_VALUE) | |
1268 | + , m_pGenMixi(NULL) | |
1269 | + , m_hWinampWnd((HWND)INVALID_HANDLE_VALUE) | |
1270 | + , m_GETPLAYLISTFILE_time(0) | |
1271 | + , m_hDirChangeNotify((HANDLE)INVALID_HANDLE_VALUE) | |
1272 | + , m_isDummyPlayInfoMp3Available(false) | |
1273 | + , m_isAnotherWinampWindowAvailable(false) | |
1274 | + { | |
1275 | + | |
1276 | + m_winampTitle = _T("Winamp"); | |
1277 | + } | |
1278 | + | |
1279 | + ~DummyAmp() | |
1280 | + { | |
1281 | + release(); | |
1282 | + destroyWindow(); | |
1283 | + closeDirChangeNotifyHandle(); | |
1284 | + } | |
1285 | + | |
1286 | + public: | |
1287 | + | |
1288 | + static DummyAmp *getInstance() | |
1289 | + { | |
1290 | + if(m_pMe == NULL) | |
1291 | + { | |
1292 | + m_pMe = new DummyAmp(); | |
1293 | + } | |
1294 | + | |
1295 | + return m_pMe; | |
1296 | + } | |
1297 | + | |
1298 | + void load() | |
1299 | + { | |
1300 | + TRACE_DUMMYAMP_INIT(_T("DummyAmp::load - called.")); | |
1301 | + | |
1302 | + // initialize gen_mixi_for_winamp | |
1303 | + initGenMixi(); | |
1304 | + | |
1305 | + // initialize dummy mp3 file, if dummy mp3 is enabled | |
1306 | + if(cfg_disable_dummy_mp3 == 0) { | |
1307 | + initDummyMp3(); | |
1308 | + } | |
1309 | + | |
1310 | + // set ready flag, if initialization successfully done | |
1311 | + if( (getGenMixi() != NULL) && ((cfg_disable_dummy_mp3 == 0) || (isDummyPlayInfoMp3Available() == true)) ){ | |
1312 | + setReady(true); | |
1313 | + } | |
1314 | + } | |
1315 | + | |
1316 | + void config() | |
1317 | + { | |
1318 | + TRACE_DUMMYAMP_INIT(_T("DummyAmp::config - called.")); | |
1319 | + | |
1320 | + if(getGenMixi() != NULL) { | |
1321 | + getGenMixi()->config(); | |
1322 | + } | |
1323 | + } | |
1324 | + | |
1325 | + void release() | |
1326 | + { | |
1327 | + TRACE_DUMMYAMP_INIT(_T("DummyAmp::release - called.")); | |
1328 | + | |
1329 | + // finalize gen_mixi_for_winamp | |
1330 | + finalizeGenMixi(); | |
1331 | + | |
1332 | + // finalize dummy mp3 file, if dummy mp3 is enbaled | |
1333 | + if(isDummyPlayInfoMp3Available()) | |
1334 | + { | |
1335 | + finalizeDummyMp3(); | |
1336 | + } | |
1337 | + } | |
1338 | + | |
1339 | + void clearDummyAmpTitle() | |
1340 | + { | |
1341 | + uSetWindowText(getWnd(), DEFAULT_DUMMYAMP_TITLE); | |
1342 | + } | |
1343 | + | |
1344 | + void createWindow() | |
1345 | + { | |
1346 | + TRACE_PLUGIN(_T("DummyAmp::createWindow - called.")); | |
1347 | + | |
1348 | + if(getWnd() == INVALID_HANDLE_VALUE) | |
1349 | + { | |
1350 | + if(getGenMixi() != NULL) | |
1351 | + { | |
1352 | + HWND hAnotherWinamp = FindWindowEx(NULL, NULL, _T("Winamp v1.x"), NULL); | |
1353 | + | |
1354 | + // found another winamp window | |
1355 | + if(hAnotherWinamp != NULL) | |
1356 | + { | |
1357 | + DEBUG_PLUGIN(_T("DummyAmp::createWindow - Winamp のウィンドウを検出しました。ハンドル: %08x"), hAnotherWinamp); | |
1358 | + | |
1359 | + DWORD dwAnotherWndProcessID; | |
1360 | + ::GetWindowThreadProcessId(hAnotherWinamp, &dwAnotherWndProcessID); | |
1361 | + | |
1362 | + DWORD dwFb2kProcessID = ::GetCurrentProcessId(); | |
1363 | + | |
1364 | + DEBUG_PLUGIN(_T("DummyAmp::createWindow - Winamp ウィンドウが属するプロセスのハンドル: %08x"), dwAnotherWndProcessID); | |
1365 | + DEBUG_PLUGIN(_T("DummyAmp::createWindow - 現在実行中の foobar2000 プロセスのハンドル: %08x"), dwFb2kProcessID); | |
1366 | + | |
1367 | + // another winamp window owned by foobar2000 process | |
1368 | + if(dwAnotherWndProcessID == dwFb2kProcessID) { | |
1369 | + // subclass it, because it's winamp api simulator plugin's window | |
1370 | + setWnd(subclassWinampWindow(hAnotherWinamp)); | |
1371 | + } else { | |
1372 | + LOG_ERROR( | |
1373 | + _T("DummyAmp::createWindow - 検出した Winamp ウィンドウが他のプロセスに属しています")); | |
1374 | + LOG_ERROR( | |
1375 | + _T("DummyAmp::createWindow - Winamp と思われるプログラムが実行されているため、") | |
1376 | + _T("mixi station への送信機能は使用できません")); | |
1377 | + LOG_ERROR( | |
1378 | + _T("DummyAmp::createWindow - 該当のプログラム(プロセスID:%d)を終了し、") | |
1379 | + _T("foobar2000 を再起動してください") | |
1380 | + , dwAnotherWndProcessID); | |
1381 | + | |
1382 | + // unset dummyAmp ready flag | |
1383 | + setReady(false); | |
1384 | + } | |
1385 | + } | |
1386 | + // create own winamp simulating window | |
1387 | + else | |
1388 | + { | |
1389 | + setWnd(createWinampWindow()); | |
1390 | + } | |
1391 | + | |
1392 | + // initialize gen_mixi_for_winamp, if winamp window successfully created or subclassed | |
1393 | + if(getWnd() != INVALID_HANDLE_VALUE) | |
1394 | + { | |
1395 | + getGenMixi()->hwndParent = getWnd(); | |
1396 | + getGenMixi()->hDllInstance = getHInstance(); | |
1397 | + getGenMixi()->init(); | |
1398 | + } | |
1399 | + else | |
1400 | + { | |
1401 | + // unset dummyAmp ready flag | |
1402 | + setReady(false); | |
1403 | + } | |
1404 | + } | |
1405 | + } | |
1406 | + } | |
1407 | + | |
1408 | + void refreshAmpInfo() | |
1409 | + { | |
1410 | +#if !defined(CONTROL_SEND_TIMING) | |
1411 | + // increment play counter on dummyamp | |
1412 | + getPlayInfo().incrementPlayCount(); | |
1413 | + | |
1414 | + // update dummyamp title | |
1415 | + updateDummyAmpTitle(); | |
1416 | +#endif | |
1417 | + // use currently playing mp3 or ogg/vorbis file instead when dummy playinfo mp3 file disabled by user | |
1418 | + // (other codec types will be ignored, because they are not supported by gen_mixi_for_winamp) | |
1419 | + if(cfg_disable_dummy_mp3 == 1) | |
1420 | + { | |
1421 | + // set playinfo mp3 file path to dummyAmp | |
1422 | + getPlayInfo().setPlayInfoMp3Path(m_trackInfo.getString(FORMAT_FILEPATH).c_str()); | |
1423 | + | |
1424 | + // set playinfo mp3 file available flag to dummyAmp | |
1425 | + LPCSTR codec = m_trackInfo.getString(FORMAT_CODEC).c_str(); | |
1426 | + getPlayInfo().setPlayInfoMp3Available(IS_SUPPORTED_FORMAT_BY_GEN_MIXI(codec)); | |
1427 | + } | |
1428 | + else | |
1429 | + { | |
1430 | + // check dummy playinfo mp3 exists and writable | |
1431 | + if(isDummyPlayInfoMp3Available()) | |
1432 | + { | |
1433 | + // update dummy mp3 file | |
1434 | + tstring playInfoMp3Path = PathInfo::getDummyPlayInfoMp3Path(); | |
1435 | +#if 1 | |
1436 | + id3Info id3Info(m_trackInfo); | |
1437 | + DWORD dwErrCode; | |
1438 | + | |
1439 | + if(( dwErrCode = id3Info.write(playInfoMp3Path.c_str()) ) == S_OK) | |
1440 | + { | |
1441 | + string_utf8_from_os dummyMp3Path8(playInfoMp3Path.c_str()); | |
1442 | + | |
1443 | + // set dummy playinfo mp3 file path to dummyAmp | |
1444 | + getPlayInfo().setPlayInfoMp3Path(dummyMp3Path8); | |
1445 | + | |
1446 | + // set playinfo mp3 file available flag to dummyAmp | |
1447 | + getPlayInfo().setPlayInfoMp3Available(true); | |
1448 | + } | |
1449 | + else | |
1450 | + { | |
1451 | + putLogError(_T("DummyAmp::refreshAmpInfo"), _T("ダミーMP3ファイルの書き込み中にエラーが発生しました"), dwErrCode); | |
1452 | + LOG_ERROR(_T("DummyAmp::refreshAmpInfo - ファイルパス: %s"), playInfoMp3Path.c_str()); | |
1453 | + | |
1454 | + // set playinfo mp3 file available flag | |
1455 | + getPlayInfo().setPlayInfoMp3Available(false); | |
1456 | + | |
1457 | + // unset dummyAmp ready flag | |
1458 | + setReady(false); | |
1459 | + } | |
1460 | +#else | |
1461 | + // set id3v2 informations | |
1462 | + | |
1463 | + string_utf8_from_os dummyMp3Path8(playInfoMp3Path.c_str()); | |
1464 | + string_ansi_from_utf8 dummyMp3PathAnsi(dummyMp3Path8); | |
1465 | + ID3_Tag dummySong(dummyMp3PathAnsi); | |
1466 | + | |
1467 | + string_wide_from_utf8 title_utf16(m_trackInfo.getString(FORMAT_TRACKTITLE, true).c_str()); | |
1468 | + string_wide_from_utf8 artist_utf16(m_trackInfo.getString(FORMAT_ARTIST, true).c_str()); | |
1469 | + string_wide_from_utf8 album_utf16(m_trackInfo.getString(FORMAT_ALBUMTITLE, true).c_str()); | |
1470 | + string_wide_from_utf8 genre_utf16(m_trackInfo.getString(FORMAT_GENRE, true).c_str()); | |
1471 | + | |
1472 | + AddTitle(&dummySong, title_utf16, true); | |
1473 | + AddArtist(&dummySong, artist_utf16, true); | |
1474 | + AddAlbum(&dummySong, album_utf16, true); | |
1475 | + AddGenre(&dummySong, genre_utf16, true); | |
1476 | + | |
1477 | + // write id3v2 tag | |
1478 | + dummySong.SetPadding(false); | |
1479 | + dummySong.SetUnsync(false); | |
1480 | + if(dummySong.Update(ID3TT_ID3V2) != ID3TT_NONE) | |
1481 | + { | |
1482 | + // set dummy playinfo mp3 file path to dummyAmp | |
1483 | + getPlayInfo().setPlayInfoMp3Path(dummyMp3Path8); | |
1484 | + | |
1485 | + // set playinfo mp3 file available flag to dummyAmp | |
1486 | + getPlayInfo().setPlayInfoMp3Available(true); | |
1487 | + } | |
1488 | + else | |
1489 | + { | |
1490 | + LOG_ERROR(_T("DummyAmp::refreshAmpInfo - ID3_Tag::Update(ID3TT_ID3V2) failed.")); | |
1491 | + | |
1492 | + // set playinfo mp3 file available flag | |
1493 | + getPlayInfo().setPlayInfoMp3Available(false); | |
1494 | + | |
1495 | + // unset dummyAmp ready flag | |
1496 | + setReady(false); | |
1497 | + } | |
1498 | +#endif | |
1499 | + } | |
1500 | + else | |
1501 | + { | |
1502 | + // reset playinfo mp3 file available flag | |
1503 | + getPlayInfo().setPlayInfoMp3Available(false); | |
1504 | + | |
1505 | + LOG_WARN(_T("DummyAmp::refreshAmpInfo - ダミーMP3ファイルが無効になっているため、送信情報を書き込めません。")); | |
1506 | + } | |
1507 | + } | |
1508 | + | |
1509 | +#if !defined(CONTROL_SEND_TIMING) | |
1510 | + // set dummyamp status PLAY_START | |
1511 | + getPlayInfo().setPlayStatusStart(); | |
1512 | +#endif | |
1513 | + } | |
1514 | + | |
1515 | + public: | |
1516 | + | |
1517 | + bool isReady() const { | |
1518 | + return m_bReady; | |
1519 | + } | |
1520 | + | |
1521 | + HWND getWnd() const { | |
1522 | + return m_hWinampWnd; | |
1523 | + } | |
1524 | + | |
1525 | + const TrackInfo &getTrackInfo() const { | |
1526 | + return m_trackInfo; | |
1527 | + } | |
1528 | + | |
1529 | + TrackInfo &getMutableTrackInfo() { | |
1530 | + return m_trackInfo; | |
1531 | + } | |
1532 | + | |
1533 | + void setTrackInfo(const TrackInfo &trackInfo) { | |
1534 | + m_trackInfo = trackInfo; | |
1535 | + } | |
1536 | + | |
1537 | + PlayInfo &getPlayInfo() { | |
1538 | + return m_playInfo; | |
1539 | + } | |
1540 | + | |
1541 | + PlayInfo &getRawPlayInfo() { | |
1542 | + return m_rawPlayInfo; | |
1543 | + } | |
1544 | + | |
1545 | + | |
1546 | + void setPlaylistTitle(LPCTSTR pTitle) { | |
1547 | + | |
1548 | + TRACE_PLUGIN(_T("DummyAmp::setPlayListTitle - %s"), pTitle); | |
1549 | + | |
1550 | + m_playlistTitle = pTitle; | |
1551 | + | |
1552 | + string_utf8_from_os playListTitle8(pTitle); | |
1553 | + | |
1554 | + if(cfg_disable_ansi_trans == 1) | |
1555 | + { | |
1556 | + | |
1557 | + m_playlistTitle8 = playListTitle8; | |
1558 | + } | |
1559 | + else | |
1560 | + { | |
1561 | + string_ansi_from_utf8 playListTitleAnsi(playListTitle8); | |
1562 | + | |
1563 | + m_playlistTitle8 = playListTitleAnsi; | |
1564 | + } | |
1565 | + } | |
1566 | + | |
1567 | + const tstring &getPlaylistTitle() const { | |
1568 | + return m_playlistTitle; | |
1569 | + } | |
1570 | + | |
1571 | + const string8 &getPlaylistTitle8() const { | |
1572 | + return m_playlistTitle8; | |
1573 | + } | |
1574 | + | |
1575 | + void setWinampTitle(LPCTSTR pTitle) { | |
1576 | + | |
1577 | + TRACE_PLUGIN(_T("DummyAmp::setWinampTitle - %s"), pTitle); | |
1578 | + | |
1579 | + m_winampTitle = pTitle; | |
1580 | + } | |
1581 | + | |
1582 | + const tstring &getWinampTitle() const { | |
1583 | + return m_winampTitle; | |
1584 | + } | |
1585 | + | |
1586 | + void setBaseWinampTitle(LPCTSTR pTitle) | |
1587 | + { | |
1588 | + TRACE_PLUGIN(_T("DummyAmp::setRawWinampTitle - %s"), pTitle); | |
1589 | + | |
1590 | + m_baseWinampTitle = pTitle; | |
1591 | + | |
1592 | + updateDummyAmpTitle(); | |
1593 | + } | |
1594 | + | |
1595 | + const tstring &getBaseWinampTitle() const { | |
1596 | + return m_baseWinampTitle; | |
1597 | + } | |
1598 | + | |
1599 | + const tstring &getDummyPlayInfoMp3Path() const { | |
1600 | + return m_dummyPlayInfoMp3Path; | |
1601 | + } | |
1602 | + | |
1603 | + bool isDummyPlayInfoMp3Available() const { | |
1604 | + return m_isDummyPlayInfoMp3Available; | |
1605 | + } | |
1606 | + | |
1607 | + bool isAnotherWinampWindowAvailable() const { | |
1608 | + return m_isAnotherWinampWindowAvailable; | |
1609 | + } | |
1610 | + | |
1611 | + void showDummyAmpWindow(bool bShow) { | |
1612 | + showDummyAmpWindow(getWnd(), bShow); | |
1613 | + } | |
1614 | + | |
1615 | + protected: | |
1616 | + | |
1617 | + void initGenMixi() | |
1618 | + { | |
1619 | + string_os_from_utf8 path(cfg_gen_mixi_path); | |
1620 | + tstring genMixiPath = path; | |
1621 | + genMixiPath += GEN_MIXI_FILE_NAME; | |
1622 | + | |
1623 | + setHInstance(::LoadLibrary(genMixiPath.c_str())); | |
1624 | + | |
1625 | + if(getHInstance() == NULL) | |
1626 | + { | |
1627 | + setHInstance((HINSTANCE)INVALID_HANDLE_VALUE); | |
1628 | + | |
1629 | + tstring msg; | |
1630 | + msg = GEN_MIXI_FILE_NAME _T(" が見つかりません。\n以下のパスにファイルが存在するか確認してください。\n"); | |
1631 | + msg += genMixiPath; | |
1632 | + | |
1633 | + string_utf8_from_os uMsg(msg.c_str()); | |
1634 | + | |
1635 | + uMessageBox(NULL, uMsg, PLUGIN_CAPTION, MB_ICONEXCLAMATION | MB_OK); | |
1636 | + } | |
1637 | + else | |
1638 | + { | |
1639 | + winampGeneralPurposePluginGetter funcWinampGetGeneralPurposePlugin = NULL; | |
1640 | + | |
1641 | + funcWinampGetGeneralPurposePlugin = (winampGeneralPurposePluginGetter) | |
1642 | + ::GetProcAddress(getHInstance(), GEN_MIXI_FUNC_NAME_GET_GENERAL_PURPOSE_PLUGIN); | |
1643 | + | |
1644 | + if(funcWinampGetGeneralPurposePlugin != NULL) | |
1645 | + { | |
1646 | + setGenMixi(funcWinampGetGeneralPurposePlugin()); | |
1647 | + // create window later. | |
1648 | + } | |
1649 | + else | |
1650 | + { | |
1651 | + tstring msg; | |
1652 | + msg = _T("関数 ") _T(GEN_MIXI_FUNC_NAME_GET_GENERAL_PURPOSE_PLUGIN) _T("() が見つかりません。\n") | |
1653 | + GEN_MIXI_FILE_NAME _T(" が壊れている可能性があります。"); | |
1654 | + | |
1655 | + string_utf8_from_os uMsg(msg.c_str()); | |
1656 | + | |
1657 | + uMessageBox(NULL, uMsg, PLUGIN_CAPTION, MB_ICONEXCLAMATION | MB_OK); | |
1658 | + } | |
1659 | + } | |
1660 | + } | |
1661 | + | |
1662 | + void initDummyMp3() | |
1663 | + { | |
1664 | + // if dummy mp3 file not exist | |
1665 | + tstring dummyPlayInfoMp3Path = PathInfo::getDummyPlayInfoMp3Path(); | |
1666 | + DWORD dwAttr = ::GetFileAttributes(dummyPlayInfoMp3Path.c_str()); | |
1667 | + | |
1668 | + if(dwAttr == -1) | |
1669 | + { | |
1670 | + // create dummy mp3 file | |
1671 | + HANDLE hMp3File = ::CreateFile( | |
1672 | + dummyPlayInfoMp3Path.c_str(), 0, 0, NULL, | |
1673 | + CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL | |
1674 | + ); | |
1675 | + | |
1676 | + if(hMp3File == INVALID_HANDLE_VALUE) | |
1677 | + { | |
1678 | + DWORD dwErrCode = ::GetLastError(); | |
1679 | + putLogError(_T("DummyAmp::initDummyMp3"), _T("ダミーMP3ファイルの作成中にエラーが発生しました"), dwErrCode); | |
1680 | + LOG_ERROR(_T("DummyAmp::initDummyMp3 - ファイルパス: %s"), dummyPlayInfoMp3Path.c_str()); | |
1681 | + | |
1682 | + LOG_ERROR(_T("DummyAmp::initDummyMp3 - ダミーMP3ファイルが使用できないため、送信機能は無効になります")); | |
1683 | + } | |
1684 | + else | |
1685 | + { | |
1686 | + DEBUG_DUMMYAMP_INIT(_T("DummyAmp::initDummyMp3 - ダミーMP3ファイルを [%s] に作成しました"), dummyPlayInfoMp3Path.c_str()); | |
1687 | + | |
1688 | + ::CloseHandle(hMp3File); | |
1689 | + | |
1690 | + setDummyPlayInfoMp3Path(dummyPlayInfoMp3Path); | |
1691 | + setDummyPlayInfoMp3Available(true); | |
1692 | + } | |
1693 | + } | |
1694 | + else if((dwAttr & FILE_ATTRIBUTE_READONLY) != 0) | |
1695 | + { | |
1696 | + LOG_ERROR(_T("DummyAmp::initDummyMp3 - ダミーMP3ファイルがパス [%s] 上に既に存在しますが、") | |
1697 | + _T("読み込み専用属性のため書き込みできません"), dummyPlayInfoMp3Path.c_str()); | |
1698 | + | |
1699 | + LOG_ERROR(_T("DummyAmp::initDummyMp3 - ダミーMP3ファイルが使用できないため、送信機能は無効になります")); | |
1700 | + } | |
1701 | + else | |
1702 | + { | |
1703 | + LOG_WARN(_T("DummyAmp::initDummyMp3 - ダミーMP3ファイルがパス [%s] 上に既に存在します"), dummyPlayInfoMp3Path.c_str()); | |
1704 | + LOG_WARN(_T("DummyAmp::initDummyMp3 - このMP3ファイルは逐次上書きされ、終了時に削除されます")); | |
1705 | + | |
1706 | + setDummyPlayInfoMp3Path(dummyPlayInfoMp3Path); | |
1707 | + setDummyPlayInfoMp3Available(true); | |
1708 | + } | |
1709 | + } | |
1710 | + | |
1711 | + void finalizeGenMixi() | |
1712 | + { | |
1713 | + if(getHInstance() != INVALID_HANDLE_VALUE) | |
1714 | + { | |
1715 | + if(getGenMixi() != NULL) | |
1716 | + { | |
1717 | + getGenMixi()->quit(); | |
1718 | + setGenMixi(NULL); | |
1719 | + } | |
1720 | + ::FreeLibrary(getHInstance()); | |
1721 | + setHInstance((HINSTANCE)INVALID_HANDLE_VALUE); | |
1722 | + } | |
1723 | + | |
1724 | + } | |
1725 | + | |
1726 | + void finalizeDummyMp3() | |
1727 | + { | |
1728 | + tstring dummyPlayInfoMp3Path = getDummyPlayInfoMp3Path(); | |
1729 | + | |
1730 | + if(::DeleteFile(dummyPlayInfoMp3Path.c_str()) == FALSE) | |
1731 | + { | |
1732 | + DWORD dwErrCode = ::GetLastError(); | |
1733 | + putLogError(_T("DummyAmp::finalizeDummyMp3"), _T("ダミーMP3ファイルの削除中にエラーが発生しました"), dwErrCode); | |
1734 | + LOG_ERROR(_T("DummyAmp::finalizeDummyMp3 - ファイルパス: %s"), dummyPlayInfoMp3Path.c_str()); | |
1735 | + } | |
1736 | + else | |
1737 | + { | |
1738 | + DEBUG_DUMMYAMP_INIT(_T("DummyAmp::finalizeDummyMp3 - ダミーMP3ファイル [%s] を削除しました"), dummyPlayInfoMp3Path.c_str()); | |
1739 | + setDummyPlayInfoMp3Available(false); | |
1740 | + } | |
1741 | + } | |
1742 | + | |
1743 | + void updateDummyAmpTitle() | |
1744 | + { | |
1745 | + bool bDisableDuplicatedSong = (cfg_disable_duplicate_song == 0); | |
1746 | + tstring winampTitle = makeDummyAmpTitle(getBaseWinampTitle(), bDisableDuplicatedSong); | |
1747 | + | |
1748 | + setWinampTitle(winampTitle.c_str()); | |
1749 | + | |
1750 | + if(isAnotherWinampWindowAvailable() == false) { | |
1751 | + ::SetWindowText(getWnd(), winampTitle.c_str()); | |
1752 | + } | |
1753 | + } | |
1754 | + | |
1755 | + protected: | |
1756 | + | |
1757 | + void setReady(bool bReady) { | |
1758 | + m_bReady = bReady; | |
1759 | + } | |
1760 | + | |
1761 | + void setWnd(HWND hWnd) { | |
1762 | + m_hWinampWnd = hWnd; | |
1763 | + } | |
1764 | + | |
1765 | + HINSTANCE getHInstance() const { | |
1766 | + return m_hInstGenMixi; | |
1767 | + } | |
1768 | + | |
1769 | + void setHInstance(HINSTANCE hInst) { | |
1770 | + m_hInstGenMixi = hInst; | |
1771 | + } | |
1772 | + | |
1773 | + winampGeneralPurposePlugin *getGenMixi() const { | |
1774 | + return m_pGenMixi; | |
1775 | + } | |
1776 | + | |
1777 | + void setGenMixi(winampGeneralPurposePlugin *pGenMixi) { | |
1778 | + m_pGenMixi = pGenMixi; | |
1779 | + } | |
1780 | + | |
1781 | + void setDummyPlayInfoMp3Path(const tstring &path) { | |
1782 | + m_dummyPlayInfoMp3Path = path; | |
1783 | + } | |
1784 | + | |
1785 | + void setDummyPlayInfoMp3Available(bool isAvailable) { | |
1786 | + m_isDummyPlayInfoMp3Available = isAvailable; | |
1787 | + } | |
1788 | + | |
1789 | + void setAnotherWinampWindowAvailable(bool isAvailable) { | |
1790 | + m_isAnotherWinampWindowAvailable = isAvailable; | |
1791 | + } | |
1792 | + | |
1793 | + int getGetPlayListFileTime() const { | |
1794 | + return m_GETPLAYLISTFILE_time; | |
1795 | + } | |
1796 | + | |
1797 | + void setGetPlayListFileTime(int time) { | |
1798 | + m_GETPLAYLISTFILE_time = time; | |
1799 | + } | |
1800 | + | |
1801 | + HANDLE getDirChangeNotifyHandle() const { | |
1802 | + return m_hDirChangeNotify; | |
1803 | + } | |
1804 | + | |
1805 | + void setDirChangeNotifyHandle(HANDLE handle) { | |
1806 | + m_hDirChangeNotify = handle; | |
1807 | + } | |
1808 | + | |
1809 | + protected: | |
1810 | + | |
1811 | + HWND createWinampWindow() | |
1812 | + { | |
1813 | + TRACE_PLUGIN(_T("DummyAmp::createWinampWindow - called.")); | |
1814 | + | |
1815 | + static bool isInited = false; | |
1816 | + | |
1817 | +#if IS_FB2K_VER08 | |
1818 | + static const char class_name[] = "Winamp v1.x"; | |
1819 | + if (!isInited) | |
1820 | + { | |
1821 | + isInited = true; | |
1822 | + uWNDCLASS wc; | |
1823 | + memset(&wc,0,sizeof(wc)); | |
1824 | + wc.style = 0; | |
1825 | + wc.lpfnWndProc = windowproc; | |
1826 | + wc.hInstance = core_api::get_my_instance(); | |
1827 | + wc.hCursor = NULL; //uLoadCursor(0, IDC_ARROW); | |
1828 | + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); | |
1829 | + wc.lpszClassName = class_name; | |
1830 | + uRegisterClass(&wc); | |
1831 | + } | |
1832 | + HWND hWinampWnd = uCreateWindowEx( | |
1833 | + 0, class_name, DEFAULT_DUMMYAMP_TITLE, | |
1834 | + WS_OVERLAPPED|WS_CAPTION|WS_SIZEBOX, | |
1835 | + CW_USEDEFAULT, CW_USEDEFAULT, 300, 150, | |
1836 | +#if 1 | |
1837 | + core_api::get_main_window(), 0, core_api::get_my_instance(), NULL | |
1838 | +#else | |
1839 | + NULL, 0, core_api::get_my_instance(), NULL | |
1840 | +#endif | |
1841 | + ); | |
1842 | +#elif IS_FB2K_VER09 | |
1843 | + static const TCHAR class_name[] = _T("Winamp v1.x"); | |
1844 | + if (!isInited) | |
1845 | + { | |
1846 | + isInited = true; | |
1847 | + WNDCLASS wc; | |
1848 | + memset(&wc,0,sizeof(wc)); | |
1849 | + wc.style = 0; | |
1850 | + wc.lpfnWndProc = windowproc; | |
1851 | + wc.hInstance = core_api::get_my_instance(); | |
1852 | + wc.hCursor = NULL; //uLoadCursor(0, IDC_ARROW); | |
1853 | + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); | |
1854 | + wc.lpszClassName = class_name; | |
1855 | + RegisterClass(&wc); | |
1856 | + } | |
1857 | + HWND hWinampWnd = CreateWindowEx( | |
1858 | + 0, class_name, _T(DEFAULT_DUMMYAMP_TITLE), | |
1859 | + WS_OVERLAPPED|WS_CAPTION|WS_SIZEBOX, | |
1860 | + CW_USEDEFAULT, CW_USEDEFAULT, 300, 150, | |
1861 | +#if 1 | |
1862 | + core_api::get_main_window(), 0, core_api::get_my_instance(), NULL | |
1863 | +#else | |
1864 | + NULL, 0, core_api::get_my_instance(), NULL | |
1865 | +#endif | |
1866 | + ); | |
1867 | +#endif | |
1868 | + if (!hWinampWnd) | |
1869 | + { | |
1870 | + DWORD dwErrCode = ::GetLastError(); | |
1871 | + putLogError(_T("DummyAmp::createWinampWindow"), _T("DummyAmp ウィンドウの生成に失敗しました"), dwErrCode); | |
1872 | + | |
1873 | + return NULL; | |
1874 | + } | |
1875 | + | |
1876 | + DEBUG_PLUGIN(_T("DummyAmp::createWinampWindow - DummyAmp ウィンドウを生成しました")); | |
1877 | + | |
1878 | + showDummyAmpWindow(hWinampWnd, cfg_show_dummyamp == 1); | |
1879 | + | |
1880 | + return hWinampWnd; | |
1881 | + } | |
1882 | + | |
1883 | + HWND subclassWinampWindow(HWND hAnotherWinampWnd) { | |
1884 | + // subclass another dummyamp window | |
1885 | + m_pfnOldAnotherWinampProc = | |
1886 | + SetWindowLongPtr(hAnotherWinampWnd, GWL_WNDPROC, WNDPROC_TO_LONG_PTR(hookWinampWindowProc)); | |
1887 | + | |
1888 | + if(hAnotherWinampWnd != NULL) | |
1889 | + { | |
1890 | + DEBUG_PLUGIN(_T("DummyAmp::subclassWinampWindow - API エミュレータと思われる Winamp ウィンドウのプロシージャをフックしました")); | |
1891 | + setAnotherWinampWindowAvailable(true); | |
1892 | + | |
1893 | + return hAnotherWinampWnd; | |
1894 | + } | |
1895 | + else | |
1896 | + { | |
1897 | + DWORD dwErrCode = ::GetLastError(); | |
1898 | + putLogError(_T("DummyAmp::subclassWinampWindow"), _T("Winamp ウィンドウのサブクラス化に失敗しました"), dwErrCode); | |
1899 | + | |
1900 | + LOG_ERROR(_T("DummyAmp::subclassWinampWindow - Winamp ウィンドウのプロシージャをフックできなかったため、送信機能は無効になります")); | |
1901 | + } | |
1902 | + | |
1903 | + return (HWND)INVALID_HANDLE_VALUE; | |
1904 | + } | |
1905 | + | |
1906 | + void unsubclassWinampWindow() { | |
1907 | + SetWindowLongPtr(getWnd(), GWL_WNDPROC, m_pfnOldAnotherWinampProc); | |
1908 | + } | |
1909 | + | |
1910 | + void showDummyAmpWindow(HWND hWinampWnd, bool bShow) | |
1911 | + { | |
1912 | + if(bShow) { | |
1913 | + ShowWindow(hWinampWnd, SW_SHOW); | |
1914 | + } else { | |
1915 | + ShowWindow(hWinampWnd, SW_HIDE); | |
1916 | + } | |
1917 | + } | |
1918 | + | |
1919 | + void destroyWindow() | |
1920 | + { | |
1921 | + TRACE_PLUGIN(_T("DummyAmp::destroyWindow - called.")); | |
1922 | + | |
1923 | + if(getWnd() != INVALID_HANDLE_VALUE) | |
1924 | + { | |
1925 | + if(isAnotherWinampWindowAvailable() == false) { | |
1926 | + uDestroyWindow(getWnd()); | |
1927 | + } else { | |
1928 | + unsubclassWinampWindow(); | |
1929 | + | |
1930 | + DEBUG_PLUGIN(_T("DummyAmp::destroyWindow - Winamp ウィンドウのサブクラス化を解除しました")); | |
1931 | + } | |
1932 | + | |
1933 | + setWnd((HWND)INVALID_HANDLE_VALUE); | |
1934 | + } | |
1935 | + } | |
1936 | + | |
1937 | + void closeDirChangeNotifyHandle() | |
1938 | + { | |
1939 | + TRACE_PLUGIN(_T("DummyAmp::closeDirChangeNotifyHandle - called.")); | |
1940 | + | |
1941 | + if(m_hDirChangeNotify != INVALID_HANDLE_VALUE) | |
1942 | + { | |
1943 | + ::FindCloseChangeNotification(m_hDirChangeNotify); | |
1944 | + TRACE_PLUGIN(_T("DummyAmp::closeDirChangeNotifyHandle - ディレクトリ変更通知イベントのハンドル (ID:%08x) を閉じました"), m_hDirChangeNotify); | |
1945 | + | |
1946 | + m_hDirChangeNotify = (HANDLE)INVALID_HANDLE_VALUE; | |
1947 | + } | |
1948 | + } | |
1949 | + | |
1950 | + tstring makeDummyAmpTitle(const tstring &rawTitle, bool bCounterReflection) | |
1951 | + { | |
1952 | + TRACE_PLUGIN(_T("DummyAmp::makeDummyAmpTitle - called.")); | |
1953 | + | |
1954 | + Str64K formatBuf; | |
1955 | + | |
1956 | + if(bCounterReflection) | |
1957 | + { | |
1958 | + _stprintf_s( | |
1959 | + formatBuf, sizeof(formatBuf) / sizeof(TCHAR), | |
1960 | + _T("%d. %s - ") _T(DEFAULT_WINAMP_TITLE), | |
1961 | + getPlayInfo().getPlayCount(), | |
1962 | + (LPCTSTR)rawTitle.c_str() | |
1963 | + ); | |
1964 | + } | |
1965 | + else | |
1966 | + { | |
1967 | + _stprintf_s( | |
1968 | + formatBuf, sizeof(formatBuf) / sizeof(TCHAR), | |
1969 | + _T("%d. %s - ") _T(DEFAULT_WINAMP_TITLE), | |
1970 | + m_trackInfo.getNumber(FORMAT_LISTINDEX), | |
1971 | + (LPCTSTR)rawTitle.c_str() | |
1972 | + ); | |
1973 | + } | |
1974 | + | |
1975 | + return formatBuf; | |
1976 | + } | |
1977 | + | |
1978 | + void refreshTitle() | |
1979 | + { | |
1980 | + // get formatted dynamic titles | |
1981 | + string8 dummyAmp_title8; | |
1982 | + string8 playlist_title8; | |
1983 | +#if IS_FB2K_VER08 | |
1984 | + metadb_handle *track = play_control::get()->get_now_playing(); | |
1985 | + if(track) | |
1986 | + { | |
1987 | + play_control::get()->playback_format_title_ex(track, dummyAmp_title8, cfg_dummyamp_title_format, NULL, false, true); | |
1988 | + play_control::get()->playback_format_title_ex(track, playlist_title8, cfg_dummyamp_playlist_format, NULL, false, true); | |
1989 | + track->handle_release(); | |
1990 | + } | |
1991 | +#elif IS_FB2K_VER09 | |
1992 | + metadb_handle_ptr track; | |
1993 | + static_api_ptr_t<playback_control>()->get_now_playing(track); | |
1994 | + | |
1995 | + service_ptr_t<titleformat_object> titleformat; | |
1996 | + | |
1997 | + static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, cfg_dummyamp_title_format); | |
1998 | + static_api_ptr_t<playback_control>()->playback_format_title_ex(track, NULL, dummyAmp_title8, titleformat, NULL, play_control::display_level_all); | |
1999 | + | |
2000 | + static_api_ptr_t<titleformat_compiler>()->compile_safe(titleformat, cfg_dummyamp_playlist_format); | |
2001 | + static_api_ptr_t<playback_control>()->playback_format_title_ex(track, NULL, playlist_title8, titleformat, NULL, play_control::display_level_all); | |
2002 | +#endif | |
2003 | + // convert utf8 track informations to os charset | |
2004 | + string_os_from_utf8 dummyAmp_title(dummyAmp_title8); | |
2005 | + string_os_from_utf8 playlist_title(playlist_title8); | |
2006 | + | |
2007 | + // set base dummyamp title to dummyamp | |
2008 | + setBaseWinampTitle(dummyAmp_title); | |
2009 | + | |
2010 | + // set dummyamp playlist current item title to dummyamp | |
2011 | + setPlaylistTitle(playlist_title); | |
2012 | + } | |
2013 | + | |
2014 | +#if 0 | |
2015 | + private: | |
2016 | + | |
2017 | + ID3_Frame* AddArtist(ID3_Tag *tag, const wchar_t *text, bool replace) | |
2018 | + { | |
2019 | + ID3_Frame* frame = NULL; | |
2020 | + if (NULL != tag && NULL != text && lstrlen(text) > 0) | |
2021 | + { | |
2022 | + if (replace) | |
2023 | + { | |
2024 | + RemoveArtists(tag); | |
2025 | + } | |
2026 | + if (replace || | |
2027 | + (tag->Find(ID3FID_LEADARTIST) == NULL && | |
2028 | + tag->Find(ID3FID_BAND) == NULL && | |
2029 | + tag->Find(ID3FID_CONDUCTOR) == NULL && | |
2030 | + tag->Find(ID3FID_COMPOSER) == NULL)) | |
2031 | + { | |
2032 | + frame = new ID3_Frame(ID3FID_LEADARTIST); | |
2033 | + if (frame) | |
2034 | + { | |
2035 | + frame->GetField(ID3FN_TEXT)->SetEncoding(ID3TE_UNICODE); | |
2036 | + frame->GetField(ID3FN_TEXT)->Set(SwapByteOrder(text)); | |
2037 | + frame->GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE); | |
2038 | + tag->AttachFrame(frame); | |
2039 | + } | |
2040 | + } | |
2041 | + } | |
2042 | + return frame; | |
2043 | + } | |
2044 | + | |
2045 | + size_t RemoveArtists(ID3_Tag *tag) | |
2046 | + { | |
2047 | + size_t num_removed = 0; | |
2048 | + ID3_Frame *frame = NULL; | |
2049 | + | |
2050 | + if (NULL == tag) | |
2051 | + { | |
2052 | + return num_removed; | |
2053 | + } | |
2054 | + | |
2055 | + while ((frame = tag->Find(ID3FID_LEADARTIST)) != NULL) | |
2056 | + { | |
2057 | + frame = tag->RemoveFrame(frame); | |
2058 | + delete frame; | |
2059 | + num_removed++; | |
2060 | + } | |
2061 | + while ((frame = tag->Find(ID3FID_BAND)) != NULL) | |
2062 | + { | |
2063 | + frame = tag->RemoveFrame(frame); | |
2064 | + delete frame; | |
2065 | + num_removed++; | |
2066 | + } | |
2067 | + while ((frame = tag->Find(ID3FID_CONDUCTOR)) != NULL) | |
2068 | + { | |
2069 | + frame = tag->RemoveFrame(frame); | |
2070 | + delete frame; | |
2071 | + num_removed++; | |
2072 | + } | |
2073 | + while ((frame = tag->Find(ID3FID_COMPOSER)) != NULL) | |
2074 | + { | |
2075 | + frame = tag->RemoveFrame(frame); | |
2076 | + delete frame; | |
2077 | + num_removed++; | |
2078 | + } | |
2079 | + | |
2080 | + return num_removed; | |
2081 | + } | |
2082 | + | |
2083 | + ID3_Frame* AddAlbum(ID3_Tag *tag, const wchar_t *text, bool replace) | |
2084 | + { | |
2085 | + ID3_Frame* frame = NULL; | |
2086 | + if (NULL != tag && NULL != text && lstrlen(text) > 0) | |
2087 | + { | |
2088 | + if (replace) | |
2089 | + { | |
2090 | + RemoveAlbums(tag); | |
2091 | + } | |
2092 | + if (replace || tag->Find(ID3FID_ALBUM) == NULL) | |
2093 | + { | |
2094 | + frame = new ID3_Frame(ID3FID_ALBUM); | |
2095 | + if (frame) | |
2096 | + { | |
2097 | + frame->GetField(ID3FN_TEXT)->SetEncoding(ID3TE_UNICODE); | |
2098 | + frame->GetField(ID3FN_TEXT)->Set(SwapByteOrder(text)); | |
2099 | + frame->GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE); | |
2100 | + tag->AttachFrame(frame); | |
2101 | + } | |
2102 | + } | |
2103 | + } | |
2104 | + | |
2105 | + return frame; | |
2106 | + } | |
2107 | + | |
2108 | + size_t RemoveAlbums(ID3_Tag *tag) | |
2109 | + { | |
2110 | + size_t num_removed = 0; | |
2111 | + ID3_Frame *frame = NULL; | |
2112 | + | |
2113 | + if (NULL == tag) | |
2114 | + { | |
2115 | + return num_removed; | |
2116 | + } | |
2117 | + | |
2118 | + while ((frame = tag->Find(ID3FID_ALBUM)) != NULL) | |
2119 | + { | |
2120 | + frame = tag->RemoveFrame(frame); | |
2121 | + delete frame; | |
2122 | + num_removed++; | |
2123 | + } | |
2124 | + | |
2125 | + return num_removed; | |
2126 | + } | |
2127 | + | |
2128 | + ID3_Frame* AddTitle(ID3_Tag *tag, const wchar_t *text, bool replace) | |
2129 | + { | |
2130 | + ID3_Frame* frame = NULL; | |
2131 | + if (NULL != tag && NULL != text && lstrlen(text) > 0) | |
2132 | + { | |
2133 | + if (replace) | |
2134 | + { | |
2135 | + RemoveTitles(tag); | |
2136 | + } | |
2137 | + if (replace || tag->Find(ID3FID_TITLE) == NULL) | |
2138 | + { | |
2139 | + frame = new ID3_Frame(ID3FID_TITLE); | |
2140 | + if (frame) | |
2141 | + { | |
2142 | + frame->GetField(ID3FN_TEXT)->SetEncoding(ID3TE_UNICODE); | |
2143 | + frame->GetField(ID3FN_TEXT)->Set(SwapByteOrder(text)); | |
2144 | + frame->GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE); | |
2145 | + tag->AttachFrame(frame); | |
2146 | + } | |
2147 | + } | |
2148 | + } | |
2149 | + | |
2150 | + return frame; | |
2151 | + } | |
2152 | + | |
2153 | + size_t RemoveTitles(ID3_Tag *tag) | |
2154 | + { | |
2155 | + size_t num_removed = 0; | |
2156 | + ID3_Frame *frame = NULL; | |
2157 | + | |
2158 | + if (NULL == tag) | |
2159 | + { | |
2160 | + return num_removed; | |
2161 | + } | |
2162 | + | |
2163 | + while ((frame = tag->Find(ID3FID_TITLE)) != NULL) | |
2164 | + { | |
2165 | + frame = tag->RemoveFrame(frame); | |
2166 | + delete frame; | |
2167 | + num_removed++; | |
2168 | + } | |
2169 | + | |
2170 | + return num_removed; | |
2171 | + } | |
2172 | + | |
2173 | + //following routine courtesy of John George | |
2174 | + ID3_Frame* AddGenre(ID3_Tag* tag, const wchar_t *genre, bool replace) | |
2175 | + { | |
2176 | + ID3_Frame* frame = NULL; | |
2177 | + if (NULL != tag && NULL != genre && lstrlen(genre) > 0) | |
2178 | + { | |
2179 | + if (replace) | |
2180 | + { | |
2181 | + RemoveGenres(tag); | |
2182 | + } | |
2183 | + if (replace || NULL == tag->Find(ID3FID_CONTENTTYPE)) | |
2184 | + { | |
2185 | + frame = new ID3_Frame(ID3FID_CONTENTTYPE); | |
2186 | + if (NULL != frame) | |
2187 | + { | |
2188 | + frame->GetField(ID3FN_TEXT)->SetEncoding(ID3TE_UNICODE); | |
2189 | + frame->GetField(ID3FN_TEXT)->Set(SwapByteOrder(genre)); | |
2190 | + frame->GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE); | |
2191 | + tag->AttachFrame(frame); | |
2192 | + } | |
2193 | + } | |
2194 | + } | |
2195 | + | |
2196 | + return frame; | |
2197 | + } | |
2198 | + | |
2199 | + size_t RemoveGenres(ID3_Tag *tag) | |
2200 | + { | |
2201 | + size_t num_removed = 0; | |
2202 | + ID3_Frame *frame = NULL; | |
2203 | + | |
2204 | + if (NULL == tag) | |
2205 | + { | |
2206 | + return num_removed; | |
2207 | + } | |
2208 | + | |
2209 | + while ((frame = tag->Find(ID3FID_CONTENTTYPE)) != NULL) | |
2210 | + { | |
2211 | + frame = tag->RemoveFrame(frame); | |
2212 | + delete frame; | |
2213 | + num_removed++; | |
2214 | + } | |
2215 | + | |
2216 | + return num_removed; | |
2217 | + } | |
2218 | + | |
2219 | + const unicode_t *SwapByteOrder(const wchar_t *text) | |
2220 | + { | |
2221 | + static unicode_t resBuf[65536]; | |
2222 | + const wchar_t *pText; | |
2223 | + unicode_t *pBuf; | |
2224 | + | |
2225 | + for(pText = text, pBuf = resBuf; *pText != L'\0'; pText ++, pBuf ++) | |
2226 | + { | |
2227 | + wchar_t srcVal = *pText; | |
2228 | + //unicode_t dstVal = srcVal; | |
2229 | + unicode_t dstVal = (srcVal << 8) | (srcVal >> 8); | |
2230 | + *pBuf = dstVal; | |
2231 | + } | |
2232 | + | |
2233 | + *pBuf = L'\0'; | |
2234 | + | |
2235 | + return resBuf; | |
2236 | + } | |
2237 | +#endif | |
2238 | + | |
2239 | + protected: | |
2240 | + | |
2241 | + static LRESULT WINAPI hookWinampWindowProc(HWND wnd,UINT msg, WPARAM wp, LPARAM lp); | |
2242 | + static LRESULT WINAPI windowproc(HWND wnd,UINT msg, WPARAM wp, LPARAM lp); | |
2243 | + static std::pair<bool, LRESULT> WINAPI innerWinampWindowProc(HWND wnd,UINT msg, WPARAM wp, LPARAM lp); | |
2244 | + static std::pair<bool, LRESULT> WINAPI outerWinampWindowProc(HWND wnd,UINT msg, WPARAM wp, LPARAM lp); | |
2245 | + | |
2246 | + protected: | |
2247 | + | |
2248 | + static DummyAmp *m_pMe; | |
2249 | + | |
2250 | + bool m_bReady; | |
2251 | + | |
2252 | + HINSTANCE m_hInstGenMixi; | |
2253 | + winampGeneralPurposePlugin *m_pGenMixi; | |
2254 | + | |
2255 | + HWND m_hWinampWnd; | |
2256 | + bool m_isAnotherWinampWindowAvailable; | |
2257 | + | |
2258 | + static LONG_PTR m_pfnOldAnotherWinampProc; | |
2259 | + | |
2260 | + HANDLE m_hDirChangeNotify; | |
2261 | + | |
2262 | + PlayInfo m_playInfo; | |
2263 | + PlayInfo m_rawPlayInfo; | |
2264 | + | |
2265 | + TrackInfo m_trackInfo; | |
2266 | + int m_GETPLAYLISTFILE_time; | |
2267 | + | |
2268 | + tstring m_playlistTitle; | |
2269 | + string8 m_playlistTitle8; | |
2270 | + | |
2271 | + tstring m_winampTitle; | |
2272 | + tstring m_baseWinampTitle; | |
2273 | + | |
2274 | + tstring m_dummyPlayInfoMp3Path; | |
2275 | + bool m_isDummyPlayInfoMp3Available; | |
2276 | +}; | |
2277 | + | |
2278 | +DummyAmp *DummyAmp::m_pMe = NULL; | |
2279 | + | |
2280 | +LONG_PTR DummyAmp::m_pfnOldAnotherWinampProc = NULL; | |
2281 | + | |
2282 | +LRESULT CALLBACK DummyAmp::hookWinampWindowProc(HWND wnd,UINT msg, WPARAM wp, LPARAM lp) | |
2283 | +{ | |
2284 | + if(InSendMessage() || (msg != WM_WA_IPC)) | |
2285 | + { | |
2286 | + switch(msg) | |
2287 | + { | |
2288 | + case WM_CLOSE: | |
2289 | + DEBUG_DUMMYAMP_PROC(_T("DummyAmp::hookWinampWindowProc - WM_CLOSE %s"), | |
2290 | + InSendMessage() == TRUE ? _T("from other thread") : _T("")); | |
2291 | + | |
2292 | + DummyAmp::getInstance()->destroyWindow(); | |
2293 | + break; | |
2294 | + | |
2295 | + case WM_GETTEXT: | |
2296 | + { | |
2297 | + // message from same thread | |
2298 | + if((InSendMessage() == FALSE) && (DummyAmp::getInstance()->isAnotherWinampWindowAvailable() == true)) | |
2299 | + { | |
2300 | + LPCTSTR pWinampTitle = DummyAmp::getInstance()->getWinampTitle().c_str(); | |
2301 | + int nLen = ::lstrlen(pWinampTitle); | |
2302 | + TRACE_DUMMYAMP_PROC(_T("DummyAmp::hookWinampWindowProc - WM_GETTEXT / window title [%s]."), pWinampTitle); | |
2303 | + | |
2304 | + ::lstrcpyn(reinterpret_cast<LPTSTR>(lp), pWinampTitle, static_cast<int>(wp)); | |
2305 | + | |
2306 | + return (LRESULT)nLen; | |
2307 | + } | |
2308 | + } | |
2309 | + break; | |
2310 | + | |
2311 | + case WM_GETTEXTLENGTH: | |
2312 | + { | |
2313 | + // message from same thread | |
2314 | + if((InSendMessage() == FALSE) && (DummyAmp::getInstance()->isAnotherWinampWindowAvailable() == true)) | |
2315 | + { | |
2316 | + LPCTSTR pWinampTitle = DummyAmp::getInstance()->getWinampTitle().c_str(); | |
2317 | + int nLen = ::lstrlen(pWinampTitle); | |
2318 | + TRACE_DUMMYAMP_PROC(_T("DummyAmp::hookWinampWindowProc - WM_GETTEXTLENGTH / window title length %d."), nLen); | |
2319 | + | |
2320 | + return (LRESULT)nLen; | |
2321 | + } | |
2322 | + } | |
2323 | + break; | |
2324 | + | |
2325 | + case WM_SETTEXT: | |
2326 | + { | |
2327 | + // message from same thread | |
2328 | + if((InSendMessage() == FALSE) && (DummyAmp::getInstance()->isAnotherWinampWindowAvailable() == true)) | |
2329 | + { | |
2330 | + TRACE_DUMMYAMP_PROC(_T("DummyAmp::hookWinampWindowProc - WM_SETTEXT / window title [%s]."), reinterpret_cast<LPCTSTR>(lp)); | |
2331 | + } | |
2332 | + } | |
2333 | + break; | |
2334 | + | |
2335 | + default: | |
2336 | + | |
2337 | + if(InSendMessage()) | |
2338 | + { | |
2339 | + if(msg == WM_WA_IPC) { | |
2340 | + if(cfg_enable_ext_ipc_proc == 1) | |
2341 | + { | |
2342 | + std::pair<bool, LRESULT> res = outerWinampWindowProc(wnd, msg, wp, lp); | |
2343 | + if(res.first == true) { | |
2344 | + return res.second; | |
2345 | + } | |
2346 | + } | |
2347 | + |