summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpescuma <pescuma@c086bb3d-8645-0410-b8da-73a8550f86e7>2011-10-10 01:58:47 +0000
committerpescuma <pescuma@c086bb3d-8645-0410-b8da-73a8550f86e7>2011-10-10 01:58:47 +0000
commit8069c247dc4f4964c34b29ea4c13cf92e5b55507 (patch)
tree4b2304130da6279132e084e79a9a1a3181a694b5
parente9bf8a6e2d782dc480fb97cb59928c8cfe1dd777 (diff)
Moved files from BerliOS
git-svn-id: http://pescuma.googlecode.com/svn/trunk/Miranda@230 c086bb3d-8645-0410-b8da-73a8550f86e7
-rw-r--r--Plugins/listeningto/Docs/langpack_listeningto.txt69
-rw-r--r--Plugins/listeningto/Docs/listeningto_changelog.txt125
-rw-r--r--Plugins/listeningto/Docs/listeningto_readme.txt25
-rw-r--r--Plugins/listeningto/Docs/listeningto_version.txt1
-rw-r--r--Plugins/listeningto/Docs/readme_players.txt90
-rw-r--r--Plugins/listeningto/ZIP/doit.bat115
-rw-r--r--Plugins/listeningto/commons.h128
-rw-r--r--Plugins/listeningto/listeningto.cpp1301
-rw-r--r--Plugins/listeningto/listeningto.dsp327
-rw-r--r--Plugins/listeningto/listeningto.dsw29
-rw-r--r--Plugins/listeningto/m_listeningto.h79
-rw-r--r--Plugins/listeningto/music.cpp171
-rw-r--r--Plugins/listeningto/music.h68
-rw-r--r--Plugins/listeningto/options.cpp349
-rw-r--r--Plugins/listeningto/options.h88
-rw-r--r--Plugins/listeningto/players/foo_mlt/foo_mlt.cpp337
-rw-r--r--Plugins/listeningto/players/foo_mlt/foo_mlt.dsp111
-rw-r--r--Plugins/listeningto/players/foo_mlt/foo_mlt.sln50
-rw-r--r--Plugins/listeningto/players/foo_mlt/foo_mlt.vcproj250
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/abort_callback.cpp17
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/abort_callback.h72
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/advconfig.h164
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/app_close_blocker.cpp12
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/app_close_blocker.h18
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_chunk.cpp290
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_chunk.h254
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_chunk_channel_config.cpp131
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_postprocessor.h30
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/cfg_var.cpp70
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/cfg_var.h118
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/chapterizer.cpp24
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/chapterizer.h74
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/commandline.cpp27
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/commandline.h50
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/completion_notify.cpp25
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/completion_notify.h48
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/component.h44
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/component_client.h6
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/components_menu.h7
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/componentversion.h61
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_io_callback.cpp19
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_io_callback.h17
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_object.cpp206
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_object.h85
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_object_impl.h157
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/console.cpp43
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/console.h35
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/contextmenu.h215
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/contextmenu_manager.h108
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/core_api.h33
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/coreversion.h25
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp.cpp395
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp.h435
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp_manager.cpp137
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp_manager.h52
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info.cpp447
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info.h228
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info_impl.cpp243
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info_impl.h146
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info_merge.cpp130
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_operation_callback.cpp93
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_operation_callback.h25
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem.cpp821
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem.h494
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem_helper.cpp106
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem_helper.h265
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/foobar2000.h87
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/foobar2000_SDK.vcproj2280
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/genrand.h19
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/guids.cpp1042
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/hasher_md5.cpp22
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/hasher_md5.h37
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/info_lookup_handler.h24
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/initquit.h19
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input.cpp245
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input.h174
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input_file_type.cpp67
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input_file_type.h42
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input_impl.h327
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/library_manager.h133
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/link_resolver.cpp17
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/link_resolver.h33
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/main_thread_callback.h20
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/mainmenu.cpp34
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/masstagger_action.h71
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/mem_block_container.cpp12
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/mem_block_container.h49
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu.h127
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_helpers.cpp360
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_helpers.h183
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_item.cpp40
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_manager.cpp307
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/message_loop.h56
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb.cpp176
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb.h301
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb_handle.cpp48
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb_handle.h191
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb_handle_list.cpp264
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/modeless_dialog.cpp19
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/modeless_dialog.h24
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/packet_decoder.cpp14
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/packet_decoder.h113
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/play_callback.h96
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playable_location.cpp23
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playable_location.h87
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playback_control.cpp13
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playback_control.h140
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist.cpp699
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist.h611
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist_loader.cpp241
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist_loader.h136
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist_lock.cpp1
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/popup_message.cpp6
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/popup_message.h34
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/preferences_page.cpp12
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/preferences_page.h82
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/replaygain.cpp223
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/replaygain.h53
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/replaygain_info.cpp136
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/resampler.h25
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/service.cpp24
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/service.h454
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/service_impl.h28
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/shared.h11
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/shortcut_actions.h1
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/stdafx.cpp2
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/tag_processor.cpp169
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/tag_processor.h103
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/tag_processor_id3v2.cpp97
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/threaded_process.cpp36
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/threaded_process.h62
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat.cpp748
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat.h149
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat_config.cpp112
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat_config.h67
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/track_property.h30
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/ui.cpp35
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/ui.h110
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/unpack.h27
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/utf8api.cpp11
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/SDK/vis.h46
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/foobar2000_component_client/component_client.cpp132
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/foobar2000_component_client/foobar2000_component_client.vcproj332
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/StdAfx.cpp6
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/StdAfx.h22
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/bitreader_helper.h122
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cfg_guidlist.h29
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cfg_structlist.h25
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/create_directory_helper.cpp151
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/create_directory_helper.h10
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_creator.cpp171
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_creator.h17
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_parser.cpp764
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_parser.h428
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_parser_embedding.cpp358
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cuesheet_index_list.cpp139
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cuesheet_index_list.h31
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dialog_resize_helper.cpp230
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dialog_resize_helper.h58
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dropdown_helper.cpp152
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dropdown_helper.h22
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dynamic_bitrate_helper.cpp74
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dynamic_bitrate_helper.h15
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_cached.h115
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_info_const_impl.cpp287
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_info_const_impl.h78
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_list_helper.cpp63
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_list_helper.h28
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_move_helper.cpp278
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_move_helper.h60
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_win32_wrapper.h183
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_wrapper_simple.cpp75
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_wrapper_simple.h21
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/foobar2000_sdk_helpers.vcproj884
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/format_title_group.cpp63
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/format_title_group.h1
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/helpers.h38
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/inplace_edit.cpp340
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/inplace_edit.h116
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/input_helpers.cpp363
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/input_helpers.h83
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/listview_helper.cpp147
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/listview_helper.h38
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/meta_table_builder.h67
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/metadb_io_hintlist.cpp39
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/metadb_io_hintlist.h49
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/mp3_utils.cpp190
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/mp3_utils.h58
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/preload_info_helper.cpp29
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/preload_info_helper.h6
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/search_filter.cpp587
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/search_filter.h47
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/seekabilizer.cpp218
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/seekabilizer.h36
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/stream_buffer_helper.cpp79
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/stream_buffer_helper.h26
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/string_filter.h24
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/text_file_loader.cpp100
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/text_file_loader.h9
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/wildcard.cpp44
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/wildcard.h11
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_dialog.cpp278
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_dialog.h121
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_misc.cpp68
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_misc.h168
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/window_placement_helper.cpp202
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/helpers/window_placement_helper.h33
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/shared/audio_math.h78
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/shared/shared.h655
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/shared/shared.libbin0 -> 34348 bytes
-rw-r--r--Plugins/listeningto/players/foo_mlt/foobar2000/shared/win32_misc.h194
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/alloc.h408
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/array.h229
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/avltree.h374
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/bit_array.h44
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/bit_array_impl.h222
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/bsearch.cpp19
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/bsearch.h85
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/bsearch_inline.h46
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/byte_order_helper.h209
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/chainlist.h581
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/com_ptr_t.h75
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/guid.cpp144
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/guid.h39
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/instance_tracker.h49
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/int_types.h120
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/license.txt10
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/list.h577
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/map.h183
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/mem_block_mgr.h71
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/order_helper.h42
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/other.cpp56
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/other.h170
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/pfc.h151
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/pfc.vcproj766
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/pfc.vcproj.NOTEBOOK.pescuma.user65
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/primitives.h731
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/printf.cpp117
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/profiler.cpp34
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/profiler.h100
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/ptr_list.h45
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/rcptr.h274
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/ref_counter.h95
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/selftest.cpp25
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/sort.cpp230
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/sort.h181
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/stdafx.cpp2
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/string.cpp711
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/string.h610
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/string8_impl.h164
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/string_conv.cpp163
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/string_conv.h355
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/string_list.h58
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/traits.h81
-rw-r--r--Plugins/listeningto/players/foo_mlt/pfc/utf8.cpp286
-rw-r--r--Plugins/listeningto/players/foobar.cpp35
-rw-r--r--Plugins/listeningto/players/foobar.h25
-rw-r--r--Plugins/listeningto/players/generic.cpp337
-rw-r--r--Plugins/listeningto/players/generic.h34
-rw-r--r--Plugins/listeningto/players/iTunesCOMInterface.h13053
-rw-r--r--Plugins/listeningto/players/iTunesCOMInterface_i.c140
-rw-r--r--Plugins/listeningto/players/itunes.cpp188
-rw-r--r--Plugins/listeningto/players/itunes.h48
-rw-r--r--Plugins/listeningto/players/mlt_winamp/GEN.H22
-rw-r--r--Plugins/listeningto/players/mlt_winamp/mlt_winamp.cpp465
-rw-r--r--Plugins/listeningto/players/mlt_winamp/mlt_winamp.def4
-rw-r--r--Plugins/listeningto/players/mlt_winamp/mlt_winamp.dsp140
-rw-r--r--Plugins/listeningto/players/mlt_winamp/mlt_winamp.dsw29
-rw-r--r--Plugins/listeningto/players/mlt_winamp/wa_ipc.h1607
-rw-r--r--Plugins/listeningto/players/player.cpp223
-rw-r--r--Plugins/listeningto/players/player.h81
-rw-r--r--Plugins/listeningto/players/wa_ipc.h1022
-rw-r--r--Plugins/listeningto/players/watrack.cpp153
-rw-r--r--Plugins/listeningto/players/watrack.h35
-rw-r--r--Plugins/listeningto/players/winamp.cpp35
-rw-r--r--Plugins/listeningto/players/winamp.h25
-rw-r--r--Plugins/listeningto/players/wmp.cpp204
-rw-r--r--Plugins/listeningto/players/wmp.h33
-rw-r--r--Plugins/listeningto/res/listening_to.icobin0 -> 2038 bytes
-rw-r--r--Plugins/listeningto/res/ttb_disabled.bmpbin0 -> 1016 bytes
-rw-r--r--Plugins/listeningto/res/ttb_enabled.bmpbin0 -> 1016 bytes
-rw-r--r--Plugins/listeningto/resource.h93
-rw-r--r--Plugins/listeningto/resource.rc243
-rw-r--r--Plugins/listeningto/sdk/m_cluiframes.h338
-rw-r--r--Plugins/listeningto/sdk/m_metacontacts.h162
-rw-r--r--Plugins/listeningto/sdk/m_music.h345
-rw-r--r--Plugins/listeningto/sdk/m_proto_listeningto.h143
-rw-r--r--Plugins/listeningto/sdk/m_toptoolbar.h107
-rw-r--r--Plugins/listeningto/sdk/m_updater.h146
-rw-r--r--Plugins/listeningto/sdk/m_variables.h718
290 files changed, 61327 insertions, 0 deletions
diff --git a/Plugins/listeningto/Docs/langpack_listeningto.txt b/Plugins/listeningto/Docs/langpack_listeningto.txt
new file mode 100644
index 0000000..2c17ffb
--- /dev/null
+++ b/Plugins/listeningto/Docs/langpack_listeningto.txt
@@ -0,0 +1,69 @@
+; ListeningTo
+; Author: Pescuma
+; http://forums.miranda-im.org/showthread.php?t=10912
+
+[Listening to]
+
+; Menu item
+[Send to all protocols]
+[Send to %s]
+
+; Toptoolbar
+[Enable/Disable sending Listening To info (to all protocols)]
+
+; Options
+[Contact List]
+
+[Status]
+[Listening info]
+
+[General]
+[ Listening to information ]
+[Enable sending listening information to contacts]
+[Music]
+[Radio]
+[Video]
+[Others]
+[You also have to enable it per protocol in the main menu]
+[ XStatus ]
+[For protocols that don't support listening to but support XStatus:]
+[Set XStatus to Music and show listening info]
+[If other XStatus is not set, set XStatus to Music and show listening info]
+[If XStatus is Music, show listening info]
+[Do nothing]
+[ Contacts ]
+[Apply template for info from contacts (overrides contacts template)]
+[Show advanced icon in slot]
+
+[Format]
+[ Listening to ]
+[Template:]
+[Variables:]
+[%artist% - Artist name]
+[%album% - Album name]
+[%title% - Song title]
+[%track% - Track number]
+[%year% - Song year]
+[%genre% - Song genre]
+[%length% - Song length]
+[%player% - Player name]
+[%type% - Media type (Music, Radio, Video, etc)]
+[When variable not found, use:]
+[ XStatus ]
+[Title:]
+[Message:]
+[Other Variables:]
+[%listening% - Listening to info (as set above)]
+[When nothing is playing, replace %listening% with:]
+
+[Players]
+[Get info from WATrack plugin]
+[Get info from these players:]
+[Winamp (*)]
+[Windows Media Player]
+[iTunes]
+[foobar2000 (need to install the plugin manually)]
+[Other players]
+[Ask for new info every]
+[seconds]
+[Allow auto-loading plugins into players (affect players with *)]
diff --git a/Plugins/listeningto/Docs/listeningto_changelog.txt b/Plugins/listeningto/Docs/listeningto_changelog.txt
new file mode 100644
index 0000000..8a3a578
--- /dev/null
+++ b/Plugins/listeningto/Docs/listeningto_changelog.txt
@@ -0,0 +1,125 @@
+ListeningTo
+
+Changelog:
+
+. 0.3.0.0
+ + A lot of changes for the internal logic for handling players
+
+. 0.2.1.0
+ * Fix for disable by menu item
+ * Fix for no output (closes #33)
+
+. 0.2.0.0
+ + Added support for accounts
+ + Added support for extra icons service
+ - Hotkeys only for enable/disable all status
+
+. 0.1.3.2
+ * Fixes for foobar
+ * Better WATrack support
+
+. 0.1.3.1
+ + Added hotkeys to toggle sending info (closes #54)
+ * Fixed variables support (closes #75)
+ + Better handling of menu items (closes #74)
+
+. 0.1.3.0
+ + Added hotkeys to enable/disable sending info (closes #54)
+ * Fixed graying radio in optionc (closes # 52)
+ * Better cleanup on exit (for #63)
+
+. 0.1.2.3
+ * Fix for memory leak
+ * Fix for variables (also need latest variables version)
+
+. 0.1.2.2
+ * Fix to work on Win 9X
+ * Fix to compile in VS2005
+
+. 0.1.2.1
+ + Support not moded version of variables too
+ * Fix for foo_mlt and non english tags
+
+. 0.1.2.0
+ + Added variables support for template and XStatus template - need Variables MOD
+ + Added option to disable info per type
+ + Added foobar plugin (need to be installed manually) - thanks LRN for this one
+
+. 0.1.1.8
+ + First step for foobar support
+ + Added service to allow other plugins to send info to this one
+ * Renamed mlt_winamp.dll to gen_mlt.dll (to be more compatible with winamp). You can delete mlt_winamp.dll
+
+. 0.1.1.7
+ * Fix for crash when disabled
+ + Wait at least 10s beetween protocol notifications
+
+. 0.1.1.6
+ * Fix to get info from radio station in winamp
+ * Fix to remove listening to data on startup
+
+. 0.1.1.5
+ + Added icon to main menu
+ - Removed old hack for clist classic
+ + Changed variables to show unknown text when an info is not available and to, if tested with ?if(), return false
+
+. 0.1.1.4
+ + Added support for Miranda 0.8
+
+. 0.1.1.3
+ + Added variables to variables plugin. Now listening info can be used in away messages.
+ + Winamp plugin will reload info for current song at each 3s. This will make radio station names be handled better.
+
+. 0.1.1.2
+ + Added 'If other XStatus is not set, set XStatus to Music and show listening info'
+ * Changes in options dialog strings
+
+. 0.1.1.1
+ * Fix for IcoLib support
+
+. 0.1.1.0
+ + Added handling of XStatus
+ + Added IcoLib support
+ + Added langpack file
+ - Removed option to remove menu item (use menu order option dialog instead)
+
+. 0.1.0.9
+ + Option to set string to show when info is not avaible
+ * Changed host of files
+ * Changes for miranda 0.6 mmi
+ * fix for pressing configure in winamp
+
+. 0.1.0.8
+ * Fix for getting video info from winamp
+
+. 0.1.0.7
+ * Fixes for winamp 5.3
+ + Change internal struct. THIS VERSION IS NOT COMPATIBLE WITH PREVIOUS ONE. USE NEW VERSION OF PROTOCOLS.
+
+. 0.1.0.6
+ * More fixes for winamp
+ * Try tp fix (null) in MSN client
+
+. 0.1.0.5
+ * Fixes for WMP and winamp
+
+. 0.1.0.4
+ * Fixes in winamp plugin (first song was not set and pause was not handled)
+ + Added help file in listeningto dir
+ * WATrack integration works
+
+. 0.1.0.3
+ + Event to help My Details
+ * Fix for winamp stop playing
+
+. 0.1.0.2
+ + Made external plugin for winamp
+ + Option to auto-load plugin
+ + Listening to extra icon
+
+. 0.1.0.1
+ + More code to work with WATrack (don't work yet)
+ * Fixes
+
+. 0.1.0.0
+ + Initial version \ No newline at end of file
diff --git a/Plugins/listeningto/Docs/listeningto_readme.txt b/Plugins/listeningto/Docs/listeningto_readme.txt
new file mode 100644
index 0000000..6bbdd4c
--- /dev/null
+++ b/Plugins/listeningto/Docs/listeningto_readme.txt
@@ -0,0 +1,25 @@
+ListeningTo plugin
+------------------
+
+This plugins allows to set/remove your listening info to protocols that support it. It also has basic support for getting this info from the players.
+
+This means that it set the user listening to information, not the info from your contacts. To see the info from your contacts you need a clist that supports it (only modern now) or a plugin like tipper (for a contact this info is stored inside <ProtocolName>/ListeningTo db key of the contact).
+
+Any protocol that support some services (in m_proto_listeningto.h) can interface with this plugin. By now it means JGmail unicode version, MSN and Jabber.
+
+This protocol also save the listening info for the user (you!) into <ProtocolName>/ListeningTo db key.
+
+This plugin is disbled by default. To enable it you need to use the main menu: Listening to->Send to all protocols or use My Details (the option is in popup menu).
+
+If you want this to implement some other player, I need a link to a page that explain how to do it, getting all the data, if possible without polling. (iTunes do it now but wont do in future). If you need more options, etc, use WATrack... This plugin is meant to be kept small.
+
+One last thing: when reporting bugs, please post the name and version of the player you are using.
+
+It also support Variables plugin to format the info, but it has to be the lastest version of the plugin. This version allows to use temporary variables in the replacement too, so you can use %artist%.
+
+Todo:
+- Better support for iTunes (it is not good now)
+
+To report bugs/make suggestions, go to the forum thread: http://forums.miranda-im.org/showthread.php?t=10912
+
+This plugin requires at least miranda 0.6, but is fully functional only in miranda 0.7 \ No newline at end of file
diff --git a/Plugins/listeningto/Docs/listeningto_version.txt b/Plugins/listeningto/Docs/listeningto_version.txt
new file mode 100644
index 0000000..e0799e6
--- /dev/null
+++ b/Plugins/listeningto/Docs/listeningto_version.txt
@@ -0,0 +1 @@
+ListeningTo 0.3.0.0 \ No newline at end of file
diff --git a/Plugins/listeningto/Docs/readme_players.txt b/Plugins/listeningto/Docs/readme_players.txt
new file mode 100644
index 0000000..af2fce1
--- /dev/null
+++ b/Plugins/listeningto/Docs/readme_players.txt
@@ -0,0 +1,90 @@
+Some plugins in this folder can be automatically loaded into players. This means that you don't have to do nothing and the plugin will be loaded into the player when it is first detected running.
+
+For this to happen 3 things are needed:
+1. The following option must be enabled: "Allow auto-loading plugins into players (affect players with *)" (Inside Options->Status->Listening info->Players)
+2. The implementation allow this to happen (only Winamp by now)
+3. The plugin isn't loaded previously (aka it wasn't installed into player by the user)
+
+One warning: for the auto-loading to work, some inter-process messages have to happen (namelly code injection) and some anti-virus or firewalls can complain. Also, I don't know if this works if the user don't have admin rights.
+
+You also can install this plugins into the player yourself (and avoid the above warning). Instructions in how to do that are based on the player:
+
+- Winamp: copy the gen_mlt.dll to <WinampDir>\Plugins\gen_mlt.dll
+- foobar2000: copy the foo_mlt.dll to <FoobarDir>\components\foo_mlt.dll
+- QCD: can be found at http://test.quinnware.com/list_plugins.php?plugin=149
+- Songbird: you can use WMP support from http://addons.songbirdnest.com/addon/1204
+
+PS: Auto loading does not work on Win 9X
+
+
+
+
+
+------------------------------------------------------------------------------
+
+
+
+
+For developers: if you want to add support for listening to in your player, this is what you need to do:
+
+To send the info you have to create a unicode string with the format:
+L"<Status 0-stoped 1-playing>\\0<Player>\\0<Type>\\0<Title>\\0<Artist>\\0<Album>\\0<Track>\\0<Year>\\0<Genre>\\0<Length (secs)>\\0<Station name>\\0"
+(almost all fields are optional, except player name and title or artist) and pass it to SendData function.
+
+Some examples:
+ - Stopped playing:
+ SendData(L"0\\0My Player Name\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0");
+ - New song:
+ SendData(L"1\\0My Player Name\\0Music\\0Title 1\\0Artist 1\\0Album 1\\001\\01997\\0\\0123\\0\\0\\0");
+ - New video:
+ SendData(L"1\\0My Player Name\\0Video\\0Title 1\\0\\0\\0\\0\\0\\0\\0\\0\\0");
+ - New radio song:
+ SendData(L"1\\0My Player Name\\0Radio\\0Title 1\\0Artist 1\\0\\0\\0\\0\\0\\0\\0X FM\\0");
+
+
+
+
+
+// Code to send data
+
+#define DATA_SIZE 1024
+#define MIRANDA_WINDOWCLASS _T("Miranda.ListeningTo")
+#define MIRANDA_DW_PROTECTION 0x8754
+
+
+BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
+{
+ // Find the windows
+ TCHAR class_name[256];
+ if (GetClassName(hwnd, class_name, 256))
+ {
+ class_name[255] = _T('\0');
+
+ if (lstrcmpi(MIRANDA_WINDOWCLASS, class_name) == 0)
+ {
+ COPYDATASTRUCT *cds = (COPYDATASTRUCT *) lParam;
+ SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) cds);
+ }
+ }
+
+ return TRUE;
+}
+
+inline void SendData(WCHAR *text)
+{
+ static WCHAR lastMsg[DATA_SIZE] = L"";
+
+ if (wcscmp(lastMsg, text) == 0)
+ return;
+
+ // Prepare the struct
+ COPYDATASTRUCT cds;
+ cds.dwData = MIRANDA_DW_PROTECTION;
+ cds.lpData = text;
+ cds.cbData = (wcslen(text) + 1) * sizeof(WCHAR);
+
+ EnumWindows(EnumWindowsProc, (LPARAM) &cds);
+
+ wcsncpy(lastMsg, text, DATA_SIZE);
+ lastMsg[DATA_SIZE-1] = L'\0';
+}
diff --git a/Plugins/listeningto/ZIP/doit.bat b/Plugins/listeningto/ZIP/doit.bat
new file mode 100644
index 0000000..116ff82
--- /dev/null
+++ b/Plugins/listeningto/ZIP/doit.bat
@@ -0,0 +1,115 @@
+@echo off
+
+rem Batch file to build and upload files
+rem
+rem TODO: Integration with FL
+
+set name=listeningto
+
+rem To upload, this var must be set here or in other batch
+rem set ftp=ftp://<user>:<password>@<ftp>/<path>
+
+echo Building %name% ...
+
+msdev ..\%name%.dsp /MAKE "%name% - Win32 Release" /REBUILD
+msdev ..\%name%.dsp /MAKE "%name% - Win32 Unicode Release" /REBUILD
+msdev ..\players\mlt_winamp\mlt_winamp.dsp /MAKE "mlt_winamp - Win32 Release" /REBUILD
+"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.com" /Rebuild "Release Unicode" ..\players\foo_mlt\foo_mlt.sln
+
+echo Generating files for %name% ...
+
+del *.zip
+del *.dll
+copy ..\Docs\%name%_changelog.txt
+copy ..\Docs\%name%_version.txt
+copy ..\Docs\%name%_readme.txt
+mkdir Docs
+cd Docs
+del /Q *.*
+copy ..\..\Docs\langpack_%name%.txt
+copy ..\..\m_%name%.h
+cd ..
+mkdir Plugins
+cd Plugins
+mkdir listeningto
+cd listeningto
+copy "..\..\..\..\..\bin\release\Plugins\listeningto\*.dll"
+copy ..\..\..\Docs\readme_players.txt
+cd ..
+cd ..
+mkdir src
+cd src
+del /Q *.*
+copy ..\..\*.h
+copy ..\..\*.cpp
+copy ..\..\*.
+copy ..\..\*.rc
+copy ..\..\*.dsp
+copy ..\..\*.dsw
+mkdir Docs
+cd Docs
+del /Q *.*
+copy ..\..\..\Docs\*.*
+cd ..
+mkdir sdk
+cd sdk
+del /Q *.*
+copy ..\..\..\sdk\*.*
+cd ..
+cd ..
+
+cd Plugins
+copy "..\..\..\..\bin\release\Plugins\%name%.dll"
+cd ..
+
+"C:\Program Files\Filzip\Filzip.exe" -a -rp %name%.zip %name%.dll Docs Plugins
+
+cd Plugins
+del /Q %name%.dll
+copy "..\..\..\..\bin\release unicode\Plugins\%name%W.dll"
+cd ..
+
+"C:\Program Files\Filzip\Filzip.exe" -a -rp %name%W.zip %name%W.dll Docs Plugins
+
+"C:\Program Files\Filzip\Filzip.exe" -a -rp %name%_src.zip src
+
+del *.dll
+cd Docs
+del /Q *.*
+cd ..
+rmdir Docs
+cd Plugins
+cd listeningto
+del /Q *.*
+cd ..
+rmdir listeningto
+del /Q *.*
+cd ..
+rmdir Plugins
+cd src
+del /Q *.*
+cd Docs
+del /Q *.*
+cd ..
+rmdir Docs
+cd sdk
+del /Q *.*
+cd ..
+rmdir sdk
+cd ..
+rmdir src
+
+if "%ftp%"=="" GOTO END
+
+echo Going to upload files...
+pause
+
+"C:\Program Files\FileZilla\FileZilla.exe" -u .\%name%.zip %ftp% -overwrite -close
+"C:\Program Files\FileZilla\FileZilla.exe" -u .\%name%W.zip %ftp% -overwrite -close
+"C:\Program Files\FileZilla\FileZilla.exe" -u .\%name%_changelog.txt %ftp% -overwrite -close
+"C:\Program Files\FileZilla\FileZilla.exe" -u .\%name%_version.txt %ftp% -overwrite -close
+"C:\Program Files\FileZilla\FileZilla.exe" -u .\%name%_readme.txt %ftp% -overwrite -close
+
+:END
+
+echo Done.
diff --git a/Plugins/listeningto/commons.h b/Plugins/listeningto/commons.h
new file mode 100644
index 0000000..6c52073
--- /dev/null
+++ b/Plugins/listeningto/commons.h
@@ -0,0 +1,128 @@
+/*
+Copyright (C) 2006 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __COMMONS_H__
+# define __COMMONS_H__
+
+
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <time.h>
+#include <vector>
+#include <algorithm>
+#include <functional>
+
+
+
+// Miranda headers
+#define MIRANDA_VER 0x0600
+
+#include <newpluginapi.h>
+#include <win2k.h>
+#include <m_system.h>
+#include <m_protocols.h>
+#include <m_protosvc.h>
+#include <m_clist.h>
+#include <m_contacts.h>
+#include <m_langpack.h>
+#include <m_database.h>
+#include <m_options.h>
+#include <m_utils.h>
+#include <m_updater.h>
+#include <m_metacontacts.h>
+#include <m_popup.h>
+#include <m_history.h>
+#include <m_proto_listeningto.h>
+#include <m_music.h>
+#include <m_toptoolbar.h>
+#include <m_icolib.h>
+#include <m_icq.h>
+#include <m_variables.h>
+#include <m_clui.h>
+#include <m_cluiframes.h>
+#include <m_genmenu.h>
+#include <m_hotkeys.h>
+#include <m_extraicons.h>
+
+
+#include "../utils/mir_memory.h"
+#include "../utils/mir_options.h"
+#include "../utils/mir_icons.h"
+#include "../utils/mir_buffer.h"
+#include "../utils/utf8_helpers.h"
+
+#include "m_listeningto.h"
+#include "music.h"
+#include "resource.h"
+#include "options.h"
+
+
+#define MODULE_NAME "ListeningTo"
+
+
+// Global Variables
+extern HINSTANCE hInst;
+extern PLUGINLINK *pluginLink;
+extern BOOL loaded;
+
+
+#define MIR_FREE(_X_) { mir_free(_X_); _X_ = NULL; }
+#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) )
+
+
+#define MIN_TIME_BEETWEEN_SETS 10000 // ms
+
+
+void RebuildMenu();
+void StartTimer();
+int ProtoServiceExists(const char *szModule, const char *szService);
+
+
+struct ProtocolInfo
+{
+ char proto[128];
+ TCHAR account[128];
+ HANDLE hMenu;
+ int old_xstatus;
+ TCHAR old_xstatus_name[1024];
+ TCHAR old_xstatus_message[1024];
+};
+
+ProtocolInfo *GetProtoInfo(char *proto);
+int m_log(const TCHAR *function, const TCHAR *fmt, ...);
+
+
+static bool IsEmpty(const char *str)
+{
+ return str == NULL || str[0] == 0;
+}
+static bool IsEmpty(const WCHAR *str)
+{
+ return str == NULL || str[0] == 0;
+}
+
+#define DUP(_X_) ( IsEmpty(_X_) ? NULL : mir_tstrdup(_X_) )
+#define DUPD(_X_, _DEF_) ( IsEmpty(_X_) ? mir_tstrdup(_DEF_) : mir_tstrdup(_X_) )
+#define U2T(_X_) ( IsEmpty(_X_) ? NULL : mir_u2t(_X_) )
+#define U2TD(_X_, _DEF_) ( IsEmpty(_X_) ? mir_u2t(_DEF_) : mir_u2t(_X_) )
+
+
+#endif // __COMMONS_H__
diff --git a/Plugins/listeningto/listeningto.cpp b/Plugins/listeningto/listeningto.cpp
new file mode 100644
index 0000000..4daa85e
--- /dev/null
+++ b/Plugins/listeningto/listeningto.cpp
@@ -0,0 +1,1301 @@
+/*
+Copyright (C) 2006-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "commons.h"
+
+
+// Prototypes ///////////////////////////////////////////////////////////////////////////
+
+// Service called by the main menu
+#define MS_LISTENINGTO_MAINMENU "ListeningTo/MainMenu"
+
+// Service called by toptoolbar
+#define MS_LISTENINGTO_TTB "ListeningTo/TopToolBar"
+
+// Services called by hotkeys
+#define MS_LISTENINGTO_HOTKEYS_ENABLE "ListeningTo/HotkeysEnable"
+#define MS_LISTENINGTO_HOTKEYS_DISABLE "ListeningTo/HotkeysDisable"
+#define MS_LISTENINGTO_HOTKEYS_TOGGLE "ListeningTo/HotkeysToggle"
+
+#define ICON_NAME "LISTENING_TO_ICON"
+
+
+PLUGININFOEX pluginInfo={
+ sizeof(PLUGININFOEX),
+#ifdef UNICODE
+ "ListeningTo (Unicode)",
+#else
+ "ListeningTo",
+#endif
+ PLUGIN_MAKE_VERSION(0,3,0,0),
+ "Handle listening information to/for contacts",
+ "Ricardo Pescuma Domenecci",
+ "",
+ "© 2006-2009 Ricardo Pescuma Domenecci",
+ "http://pescuma.org/miranda/listeningto",
+ UNICODE_AWARE,
+ 0, //doesn't replace anything built-in
+#ifdef UNICODE
+ { 0xf981f3f5, 0x35a, 0x444f, { 0x98, 0x92, 0xca, 0x72, 0x2c, 0x19, 0x5a, 0xda } } // {F981F3F5-035A-444f-9892-CA722C195ADA}
+#else
+ { 0xa4a8ff7a, 0xc48a, 0x4d2a, { 0xb5, 0xa9, 0x46, 0x46, 0x84, 0x43, 0x26, 0x3d } } // {A4A8FF7A-C48A-4d2a-B5A9-46468443263D}
+#endif
+};
+
+
+HINSTANCE hInst;
+PLUGINLINK *pluginLink;
+struct MM_INTERFACE mmi;
+struct UTF8_INTERFACE utfi;
+
+static std::vector<HANDLE> hHooks;
+static std::vector<HANDLE> hServices;
+static HANDLE hEnableStateChangedEvent = NULL;
+HANDLE hExtraIcon = NULL;
+static HANDLE hMainMenuGroup = NULL;
+
+static HANDLE hTTB = NULL;
+static char *metacontacts_proto = NULL;
+BOOL loaded = FALSE;
+static UINT hTimer = 0;
+static HANDLE hExtraImage = NULL;
+static DWORD lastInfoSetTime = 0;
+
+std::vector<ProtocolInfo> proto_itens;
+
+
+int ModulesLoaded(WPARAM wParam, LPARAM lParam);
+int PreShutdown(WPARAM wParam, LPARAM lParam);
+int PreBuildContactMenu(WPARAM wParam,LPARAM lParam);
+int TopToolBarLoaded(WPARAM wParam, LPARAM lParam);
+int ClistExtraListRebuild(WPARAM wParam, LPARAM lParam);
+int SettingChanged(WPARAM wParam,LPARAM lParam);
+
+int MainMenuClicked(WPARAM wParam, LPARAM lParam);
+BOOL ListeningToEnabled(char *proto, BOOL ignoreGlobal = FALSE);
+int ListeningToEnabled(WPARAM wParam, LPARAM lParam);
+int EnableListeningTo(WPARAM wParam,LPARAM lParam);
+int GetTextFormat(WPARAM wParam,LPARAM lParam);
+int GetParsedFormat(WPARAM wParam,LPARAM lParam);
+int GetOverrideContactOption(WPARAM wParam,LPARAM lParam);
+int GetUnknownText(WPARAM wParam,LPARAM lParam);
+int SetNewSong(WPARAM wParam,LPARAM lParam);
+void SetExtraIcon(HANDLE hContact, BOOL set);
+void SetListeningInfos(LISTENINGTOINFO *lti);
+int HotkeysEnable(WPARAM wParam,LPARAM lParam);
+int HotkeysDisable(WPARAM wParam,LPARAM lParam);
+int HotkeysToggle(WPARAM wParam,LPARAM lParam);
+
+TCHAR* VariablesParseInfo(ARGUMENTSINFO *ai);
+TCHAR* VariablesParseType(ARGUMENTSINFO *ai);
+TCHAR* VariablesParseArtist(ARGUMENTSINFO *ai);
+TCHAR* VariablesParseAlbum(ARGUMENTSINFO *ai);
+TCHAR* VariablesParseTitle(ARGUMENTSINFO *ai);
+TCHAR* VariablesParseTrack(ARGUMENTSINFO *ai);
+TCHAR* VariablesParseYear(ARGUMENTSINFO *ai);
+TCHAR* VariablesParseGenre(ARGUMENTSINFO *ai);
+TCHAR* VariablesParseLength(ARGUMENTSINFO *ai);
+TCHAR* VariablesParsePlayer(ARGUMENTSINFO *ai);
+
+
+#define XSTATUS_MUSIC 11
+
+#define UNKNOWN(_X_) ( _X_ == NULL || _X_[0] == _T('\0') ? opts.unknown : _X_ )
+
+
+
+// Functions ////////////////////////////////////////////////////////////////////////////
+
+
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ hInst = hinstDLL;
+ return TRUE;
+}
+
+
+extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+ pluginInfo.cbSize = sizeof(PLUGININFO);
+ return (PLUGININFO*) &pluginInfo;
+}
+
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ pluginInfo.cbSize = sizeof(PLUGININFOEX);
+ return &pluginInfo;
+}
+
+
+static const MUUID interfaces[] = { MIID_LISTENINGTO, MIID_LAST };
+extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+/*
+BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
+{
+ // Find the windows
+ char class_name[1024];
+ if (GetClassNameA(hwnd, class_name, sizeof(class_name)))
+ {
+ class_name[sizeof(class_name)-1] = '\0';
+OutputDebugStringA(class_name);
+OutputDebugStringA(" -> ");
+ GetWindowTextA(hwnd, class_name, 1024);
+OutputDebugStringA(class_name);
+OutputDebugStringA("\n");
+ }
+
+ return TRUE;
+}
+*/
+
+extern "C" int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+// EnumWindows(EnumWindowsProc, 0);
+
+ pluginLink = link;
+
+ mir_getMMI(&mmi);
+ mir_getUTFI(&utfi);
+
+ CHECK_VERSION("Listening To")
+
+ CoInitialize(NULL);
+
+ // Services
+ hServices.push_back( CreateServiceFunction(MS_LISTENINGTO_ENABLED, ListeningToEnabled) );
+ hServices.push_back( CreateServiceFunction(MS_LISTENINGTO_ENABLE, EnableListeningTo) );
+ hServices.push_back( CreateServiceFunction(MS_LISTENINGTO_GETTEXTFORMAT, GetTextFormat) );
+ hServices.push_back( CreateServiceFunction(MS_LISTENINGTO_GETPARSEDTEXT, GetParsedFormat) );
+ hServices.push_back( CreateServiceFunction(MS_LISTENINGTO_OVERRIDECONTACTOPTION, GetOverrideContactOption) );
+ hServices.push_back( CreateServiceFunction(MS_LISTENINGTO_GETUNKNOWNTEXT, GetUnknownText) );
+ hServices.push_back( CreateServiceFunction(MS_LISTENINGTO_MAINMENU, MainMenuClicked) );
+ hServices.push_back( CreateServiceFunction(MS_LISTENINGTO_SET_NEW_SONG, SetNewSong) );
+ hServices.push_back( CreateServiceFunction(MS_LISTENINGTO_HOTKEYS_ENABLE, HotkeysEnable) );
+ hServices.push_back( CreateServiceFunction(MS_LISTENINGTO_HOTKEYS_DISABLE, HotkeysDisable) );
+ hServices.push_back( CreateServiceFunction(MS_LISTENINGTO_HOTKEYS_TOGGLE, HotkeysToggle) );
+
+ // Hooks
+ hHooks.push_back( HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded) );
+ hHooks.push_back( HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown) );
+ hHooks.push_back( HookEvent(ME_DB_CONTACT_SETTINGCHANGED, SettingChanged) );
+
+ hEnableStateChangedEvent = CreateHookableEvent(ME_LISTENINGTO_ENABLE_STATE_CHANGED);
+
+ InitMusic();
+ InitOptions();
+
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ CoUninitialize();
+
+ return 0;
+}
+
+
+int ProtoServiceExists(const char *szModule, const char *szService)
+{
+ char str[MAXMODULELABELLENGTH];
+ strcpy(str,szModule);
+ strcat(str,szService);
+ return ServiceExists(str);
+}
+
+void UpdateGlobalStatusMenus()
+{
+ BOOL enabled = ListeningToEnabled(NULL, TRUE);
+
+ CLISTMENUITEM clmi = {0};
+ clmi.cbSize = sizeof(clmi);
+ clmi.flags = CMIM_FLAGS
+ | (enabled ? CMIF_CHECKED : 0)
+ | (opts.enable_sending ? 0 : CMIF_GRAYED);
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto_itens[0].hMenu, (LPARAM) &clmi);
+
+ if (hTTB != NULL)
+ CallService(MS_TTB_SETBUTTONSTATE, (WPARAM) hTTB, (LPARAM) (enabled ? TTBST_PUSHED : TTBST_RELEASED));
+}
+
+
+struct compareFunc : std::binary_function<const ProtocolInfo, const ProtocolInfo, bool>
+{
+ bool operator()(const ProtocolInfo &one, const ProtocolInfo &two) const
+ {
+ return lstrcmp(one.account, two.account) < 0;
+ }
+};
+
+
+void RebuildMenu()
+{
+ std::sort(proto_itens.begin(), proto_itens.end(), compareFunc());
+
+ for (unsigned int i = 1; i < proto_itens.size(); i++)
+ {
+ ProtocolInfo *info = &proto_itens[i];
+
+ if (info->hMenu != NULL)
+ CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM) info->hMenu, 0);
+
+ TCHAR text[512];
+ mir_sntprintf(text, MAX_REGS(text), TranslateT("Send to %s"), info->account);
+
+ CLISTMENUITEM mi = {0};
+ mi.cbSize = sizeof(mi);
+ mi.position = 100000 + i;
+ mi.pszPopupName = (char *) hMainMenuGroup;
+ mi.popupPosition = 500080000 + i;
+ mi.pszService = MS_LISTENINGTO_MAINMENU;
+ mi.ptszName = text;
+ mi.flags = CMIF_CHILDPOPUP | CMIF_TCHAR
+ | (ListeningToEnabled(info->proto, TRUE) ? CMIF_CHECKED : 0)
+ | (opts.enable_sending ? 0 : CMIF_GRAYED);
+
+ info->hMenu = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi);
+ }
+
+ UpdateGlobalStatusMenus();
+}
+
+void RegisterProtocol(char *proto, TCHAR *account)
+{
+ if (!ProtoServiceExists(proto, PS_SET_LISTENINGTO) &&
+ !ProtoServiceExists(proto, PS_ICQ_SETCUSTOMSTATUSEX))
+ return;
+
+ int id = proto_itens.size();
+ proto_itens.resize(id+1);
+
+ strncpy(proto_itens[id].proto, proto, MAX_REGS(proto_itens[id].proto));
+ proto_itens[id].proto[MAX_REGS(proto_itens[id].proto)-1] = 0;
+
+ lstrcpyn(proto_itens[id].account, account, MAX_REGS(proto_itens[id].account));
+
+ proto_itens[id].hMenu = NULL;
+ proto_itens[id].old_xstatus = 0;
+ proto_itens[id].old_xstatus_name[0] = _T('\0');
+ proto_itens[id].old_xstatus_message[0] = _T('\0');
+}
+
+
+int AccListChanged(WPARAM wParam, LPARAM lParam)
+{
+ PROTOACCOUNT *proto = (PROTOACCOUNT *) lParam;
+ if (proto == NULL || proto->type != PROTOTYPE_PROTOCOL)
+ return 0;
+
+ ProtocolInfo *info = GetProtoInfo(proto->szModuleName);
+ if (info != NULL)
+ {
+ if (wParam == PRAC_UPGRADED || wParam == PRAC_CHANGED)
+ {
+ lstrcpyn(info->account, proto->tszAccountName, MAX_REGS(info->account));
+
+ TCHAR text[512];
+ mir_sntprintf(text, MAX_REGS(text), TranslateT("Send to %s"), info->account);
+
+ CLISTMENUITEM clmi = {0};
+ clmi.cbSize = sizeof(clmi);
+ clmi.flags = CMIM_NAME | CMIF_TCHAR;
+ clmi.ptszName = text;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) info->hMenu, (LPARAM) &clmi);
+ }
+ else if (wParam == PRAC_REMOVED || (wParam == PRAC_CHECKED && !proto->bIsEnabled))
+ {
+ CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM) info->hMenu, 0);
+
+ for(std::vector<ProtocolInfo>::iterator it = proto_itens.begin(); it != proto_itens.end(); ++it)
+ {
+ if (&(*it) == info)
+ {
+ proto_itens.erase(it);
+ break;
+ }
+ }
+
+ RebuildMenu();
+ }
+ }
+ else
+ {
+ if (wParam == PRAC_ADDED || (wParam == PRAC_CHECKED && proto->bIsEnabled))
+ {
+ RegisterProtocol(proto->szModuleName, proto->tszAccountName);
+ RebuildMenu();
+ }
+ }
+
+ return 0;
+}
+
+
+// Called when all the modules are loaded
+int ModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ EnableDisablePlayers();
+
+ if (ServiceExists(MS_MC_GETPROTOCOLNAME))
+ metacontacts_proto = (char *) CallService(MS_MC_GETPROTOCOLNAME, 0, 0);
+
+ // add our modules to the KnownModules list
+ CallService("DBEditorpp/RegisterSingleModule", (WPARAM) MODULE_NAME, 0);
+
+ IcoLib_Register(ICON_NAME, _T("Contact List"), _T("Listening to"), IDI_LISTENINGTO);
+
+ // Extra icon support
+ hExtraIcon = ExtraIcon_Register(MODULE_NAME, "Listening to music", ICON_NAME);
+ if (hExtraIcon != NULL)
+ {
+ HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact != NULL)
+ {
+ char *proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (proto != NULL)
+ {
+ DBVARIANT dbv = {0};
+ if (!DBGetContactSettingTString(hContact, proto, "ListeningTo", &dbv))
+ {
+ if (dbv.ptszVal != NULL && dbv.ptszVal[0] != 0)
+ SetExtraIcon(hContact, TRUE);
+
+ DBFreeVariant(&dbv);
+ }
+ }
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+ }
+ else if (hExtraIcon == NULL && ServiceExists(MS_CLIST_EXTRA_ADD_ICON))
+ {
+ hHooks.push_back( HookEvent(ME_CLIST_EXTRA_LIST_REBUILD, ClistExtraListRebuild) );
+ }
+
+
+ // updater plugin support
+ if(ServiceExists(MS_UPDATE_REGISTER))
+ {
+ Update upd = {0};
+ char szCurrentVersion[30];
+
+ upd.cbSize = sizeof(upd);
+ upd.szComponentName = pluginInfo.shortName;
+
+ upd.szUpdateURL = UPDATER_AUTOREGISTER;
+
+ upd.szBetaVersionURL = "http://pescuma.org/miranda/listeningto_version.txt";
+ upd.szBetaChangelogURL = "http://pescuma.org/miranda/listeningto#Changelog";
+ upd.pbBetaVersionPrefix = (BYTE *)"ListeningTo ";
+ upd.cpbBetaVersionPrefix = strlen((char *)upd.pbBetaVersionPrefix);
+#ifdef UNICODE
+ upd.szBetaUpdateURL = "http://pescuma.org/miranda/listeningtoW.zip";
+#else
+ upd.szBetaUpdateURL = "http://pescuma.org/miranda/listeningto.zip";
+#endif
+
+ upd.pbVersion = (BYTE *)CreateVersionStringPlugin((PLUGININFO*) &pluginInfo, szCurrentVersion);
+ upd.cpbVersion = strlen((char *)upd.pbVersion);
+
+ CallService(MS_UPDATE_REGISTER, 0, (LPARAM)&upd);
+ }
+
+ {
+ CLISTMENUITEM mi = {0};
+ mi.cbSize = sizeof(mi);
+
+ // Add main menu item
+ mi.position = 500080000;
+ mi.pszPopupName = (char*) -1;
+ mi.pszName = "Listening to";
+ mi.flags = CMIF_ROOTPOPUP;
+ mi.hIcon = IcoLib_LoadIcon(ICON_NAME);
+
+ hMainMenuGroup = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) &mi);
+
+ IcoLib_ReleaseIcon(mi.hIcon);
+
+ mi.pszPopupName = (char *) hMainMenuGroup;
+ mi.popupPosition = 500080000;
+ mi.position = 0;
+ mi.pszService = MS_LISTENINGTO_MAINMENU;
+ mi.hIcon = NULL;
+
+ // Add all protos
+ mi.pszName = Translate("Send to all protocols");
+ mi.flags = CMIF_CHILDPOPUP
+ | (ListeningToEnabled(NULL, TRUE) ? CMIF_CHECKED : 0)
+ | (opts.enable_sending ? 0 : CMIF_GRAYED);
+ proto_itens.resize(1);
+ proto_itens[0].hMenu = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi);
+ proto_itens[0].proto[0] = 0;
+ proto_itens[0].account[0] = 0;
+ proto_itens[0].old_xstatus = 0;
+ proto_itens[0].old_xstatus_name[0] = _T('\0');
+ proto_itens[0].old_xstatus_message[0] = _T('\0');
+ }
+
+ // Add each proto
+
+ if (ServiceExists(MS_PROTO_ENUMACCOUNTS))
+ {
+ PROTOACCOUNT **protos;
+ int count;
+ CallService(MS_PROTO_ENUMACCOUNTS, (WPARAM)&count, (LPARAM)&protos);
+
+ for (int i = 0; i < count; i++)
+ {
+ if (protos[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+ if (!protos[i]->bIsEnabled)
+ continue;
+
+ RegisterProtocol(protos[i]->szModuleName, protos[i]->tszAccountName);
+ }
+
+ hHooks.push_back( HookEvent(ME_PROTO_ACCLISTCHANGED, AccListChanged) );
+ }
+ else
+ {
+ PROTOCOLDESCRIPTOR **protos;
+ int count;
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&count, (LPARAM)&protos);
+
+ for (int i = 0; i < count; i++)
+ {
+ if (protos[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+
+ char name[128];
+ CallProtoService(protos[i]->szName, PS_GETNAME, sizeof(name), (LPARAM)name);
+
+ TCHAR *acc = mir_a2t(name);
+ RegisterProtocol(protos[i]->szName, acc);
+ mir_free(acc);
+ }
+ }
+
+ RebuildMenu();
+
+ hHooks.push_back( HookEvent(ME_TTB_MODULELOADED, TopToolBarLoaded) );
+
+ // Variables support
+ if (ServiceExists(MS_VARS_REGISTERTOKEN))
+ {
+ TOKENREGISTER tr = {0};
+ tr.cbSize = sizeof(TOKENREGISTER);
+ tr.memType = TR_MEM_MIRANDA;
+ tr.flags = TRF_FREEMEM | TRF_PARSEFUNC | TRF_FIELD | TRF_TCHAR;
+
+ tr.tszTokenString = _T("listening_info");
+ tr.parseFunctionT = VariablesParseInfo;
+ tr.szHelpText = "Listening info\tListening info as set in the options";
+ CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM) &tr);
+
+ tr.tszTokenString = _T("listening_type");
+ tr.parseFunctionT = VariablesParseType;
+ tr.szHelpText = "Listening info\tMedia type: Music, Video, etc";
+ CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM) &tr);
+
+ tr.tszTokenString = _T("listening_artist");
+ tr.parseFunctionT = VariablesParseArtist;
+ tr.szHelpText = "Listening info\tArtist name";
+ CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM) &tr);
+
+ tr.tszTokenString = _T("listening_album");
+ tr.parseFunctionT = VariablesParseAlbum;
+ tr.szHelpText = "Listening info\tAlbum name";
+ CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM) &tr);
+
+ tr.tszTokenString = _T("listening_title");
+ tr.parseFunctionT = VariablesParseTitle;
+ tr.szHelpText = "Listening info\tSong name";
+ CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM) &tr);
+
+ tr.tszTokenString = _T("listening_track");
+ tr.parseFunctionT = VariablesParseTrack;
+ tr.szHelpText = "Listening info\tTrack number";
+ CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM) &tr);
+
+ tr.tszTokenString = _T("listening_year");
+ tr.parseFunctionT = VariablesParseYear;
+ tr.szHelpText = "Listening info\tSong year";
+ CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM) &tr);
+
+ tr.tszTokenString = _T("listening_genre");
+ tr.parseFunctionT = VariablesParseGenre;
+ tr.szHelpText = "Listening info\tSong genre";
+ CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM) &tr);
+
+ tr.tszTokenString = _T("listening_length");
+ tr.parseFunctionT = VariablesParseLength;
+ tr.szHelpText = "Listening info\tSong length";
+ CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM) &tr);
+
+ tr.tszTokenString = _T("listening_player");
+ tr.parseFunctionT = VariablesParsePlayer;
+ tr.szHelpText = "Listening info\tPlayer name";
+ CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM) &tr);
+ }
+
+ // Hotkeys support
+ if (ServiceExists(MS_HOTKEY_REGISTER))
+ {
+ HOTKEYDESC hkd = {0};
+ hkd.cbSize = sizeof(hkd);
+ hkd.pszSection = Translate("Listening to");
+
+ hkd.pszService = MS_LISTENINGTO_HOTKEYS_ENABLE;
+ hkd.pszName = "ListeningTo/EnableAll";
+ hkd.pszDescription = Translate("Send to all protocols");
+ CallService(MS_HOTKEY_REGISTER, 0, (LPARAM)&hkd);
+
+ hkd.pszService = MS_LISTENINGTO_HOTKEYS_DISABLE;
+ hkd.pszName = "ListeningTo/DisableAll";
+ hkd.pszDescription = Translate("Don't send to any protocols");
+ CallService(MS_HOTKEY_REGISTER, 0, (LPARAM)&hkd);
+
+ hkd.pszService = MS_LISTENINGTO_HOTKEYS_TOGGLE;
+ hkd.pszName = "ListeningTo/ToggleAll";
+ hkd.pszDescription = Translate("Toggle send to all protocols");
+ CallService(MS_HOTKEY_REGISTER, 0, (LPARAM)&hkd);
+ }
+
+ SetListeningInfos(NULL);
+ StartTimer();
+
+ loaded = TRUE;
+
+ return 0;
+}
+
+
+int PreShutdown(WPARAM wParam, LPARAM lParam)
+{
+ loaded = FALSE;
+
+ if (hTimer != NULL)
+ {
+ KillTimer(NULL, hTimer);
+ hTimer = NULL;
+ }
+
+ DeInitOptions();
+
+ DestroyHookableEvent(hEnableStateChangedEvent);
+
+ int i;
+ for(i = 0; i < hHooks.size(); i++)
+ UnhookEvent(hHooks[i]);
+
+ for(i = 0; i < hServices.size(); i++)
+ DestroyServiceFunction(hServices[i]);
+
+ FreeMusic();
+
+ return 0;
+}
+
+
+int TopToolBarClick(WPARAM wParam, LPARAM lParam)
+{
+ BOOL enabled = !ListeningToEnabled(NULL, TRUE);
+
+ EnableListeningTo(NULL, enabled);
+
+ return 0;
+}
+
+
+// Toptoolbar hook to put an icon in the toolbar
+int TopToolBarLoaded(WPARAM wParam, LPARAM lParam)
+{
+ BOOL enabled = ListeningToEnabled(NULL, TRUE);
+
+ hServices.push_back( CreateServiceFunction(MS_LISTENINGTO_TTB, TopToolBarClick) );
+
+ TTBButton ttb = {0};
+ ttb.cbSize = sizeof(ttb);
+ ttb.hbBitmapUp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_TTB_UP_DISABLED));
+ ttb.hbBitmapDown = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_TTB_UP_ENABLED));
+ ttb.pszServiceUp = MS_LISTENINGTO_TTB;
+ ttb.pszServiceDown = MS_LISTENINGTO_TTB;
+ ttb.dwFlags = TTBBF_VISIBLE | TTBBF_SHOWTOOLTIP | (enabled ? TTBBF_PUSHED : 0);
+ ttb.name = Translate("Enable/Disable sending Listening To info (to all protocols)");
+
+ hTTB = (HANDLE)CallService(MS_TTB_ADDBUTTON, (WPARAM)&ttb, 0);
+
+ return 0;
+}
+
+
+int MainMenuClicked(WPARAM wParam, LPARAM lParam)
+{
+ if (!loaded)
+ return -1;
+
+ int pos = wParam == 0 ? 0 : wParam - 500080000;
+
+ if (pos >= proto_itens.size() || pos < 0)
+ return 0;
+
+ EnableListeningTo((WPARAM) proto_itens[pos].proto, (LPARAM) !ListeningToEnabled(proto_itens[pos].proto, TRUE));
+ return 0;
+}
+
+
+BOOL ListeningToEnabled(char *proto, BOOL ignoreGlobal)
+{
+ if (!ignoreGlobal && !opts.enable_sending)
+ return FALSE;
+
+ if (proto == NULL || proto[0] == 0)
+ {
+ // Check all protocols
+ BOOL enabled = TRUE;
+
+ for (unsigned int i = 1; i < proto_itens.size(); ++i)
+ {
+ if (!ListeningToEnabled(proto_itens[i].proto, TRUE))
+ {
+ enabled = FALSE;
+ break;
+ }
+ }
+
+ return enabled;
+ }
+ else
+ {
+ char setting[256];
+ mir_snprintf(setting, sizeof(setting), "%sEnabled", proto);
+ return (BOOL) DBGetContactSettingByte(NULL, MODULE_NAME, setting, FALSE);
+ }
+}
+
+
+int ListeningToEnabled(WPARAM wParam, LPARAM lParam)
+{
+ if (!loaded)
+ return -1;
+
+ return ListeningToEnabled((char *)wParam) ;
+}
+
+
+ProtocolInfo *GetProtoInfo(char *proto)
+{
+ for (unsigned int i = 1; i < proto_itens.size(); i++)
+ if (strcmp(proto, proto_itens[i].proto) == 0)
+ return &proto_itens[i];
+
+ return NULL;
+}
+
+void SetListeningInfo(char *proto, LISTENINGTOINFO *lti)
+{
+// m_log(_T("SetListeningInfo"), _T("proto=%S lti=%d title=%s"),
+// proto, (int) lti, lti == NULL ? _T("") : lti->ptszTitle);
+
+ if (proto == NULL)
+ return;
+
+ if (!ListeningToEnabled(proto))
+ {
+ lti = NULL;
+// m_log(_T("SetListeningInfo"), _T("DISABLED -> lti = NULL"));
+ }
+
+
+ if (ProtoServiceExists(proto, PS_SET_LISTENINGTO))
+ {
+ CallProtoService(proto, PS_SET_LISTENINGTO, 0, (LPARAM) lti);
+ }
+ else if (ProtoServiceExists(proto, PS_ICQ_SETCUSTOMSTATUSEX))
+ {
+ if (opts.xstatus_set == IGNORE_XSTATUS)
+ return;
+
+ int status;
+ ICQ_CUSTOM_STATUS ics = {0};
+ ics.cbSize = sizeof(ICQ_CUSTOM_STATUS);
+ ics.status = &status;
+
+ // Set or reset?
+ if (lti == NULL)
+ {
+ // Reset -> only if is still in music xstatus
+ ics.flags = CSSF_MASK_STATUS;
+ if (CallProtoService(proto, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM) &ics) || status != XSTATUS_MUSIC)
+ {
+ if (opts.xstatus_set == SET_XSTATUS)
+ {
+ ProtocolInfo *pi = GetProtoInfo(proto);
+ if (pi != NULL)
+ {
+ pi->old_xstatus = 0;
+ pi->old_xstatus_name[0] = _T('\0');
+ pi->old_xstatus_message[0] = _T('\0');
+ }
+ }
+ return;
+ }
+
+ if (opts.xstatus_set == CHECK_XSTATUS_MUSIC)
+ {
+ // Set text to nothing
+ TCHAR *fr[] = {
+ _T("listening"), opts.nothing
+ };
+
+ Buffer<TCHAR> name;
+ ReplaceTemplate(&name, NULL, opts.xstatus_name, fr, MAX_REGS(fr));
+ Buffer<TCHAR> msg;
+ ReplaceTemplate(&msg, NULL, opts.xstatus_message, fr, MAX_REGS(fr));
+
+ ics.flags = CSSF_TCHAR | CSSF_MASK_STATUS | CSSF_MASK_NAME | CSSF_MASK_MESSAGE;
+ ics.ptszName = name.str;
+ ics.ptszMessage = msg.str;
+
+ CallProtoService(proto, PS_ICQ_SETCUSTOMSTATUSEX, 0, (LPARAM) &ics);
+ }
+ else if (opts.xstatus_set == CHECK_XSTATUS)
+ {
+ status = 0;
+ ics.flags = CSSF_MASK_STATUS;
+
+ CallProtoService(proto, PS_ICQ_SETCUSTOMSTATUSEX, 0, (LPARAM) &ics);
+ }
+ else
+ {
+ // Set to old text
+ ProtocolInfo *pi = GetProtoInfo(proto);
+ if (pi != NULL)
+ {
+ ics.flags = CSSF_TCHAR | CSSF_MASK_STATUS | CSSF_MASK_NAME | CSSF_MASK_MESSAGE;
+ ics.status = &pi->old_xstatus;
+ ics.ptszName = pi->old_xstatus_name;
+ ics.ptszMessage = pi->old_xstatus_message;
+ }
+ else
+ {
+ status = 0;
+ ics.flags = CSSF_MASK_STATUS;
+ }
+
+ CallProtoService(proto, PS_ICQ_SETCUSTOMSTATUSEX, 0, (LPARAM) &ics);
+
+ if (pi != NULL)
+ {
+ pi->old_xstatus = 0;
+ pi->old_xstatus_name[0] = _T('\0');
+ pi->old_xstatus_message[0] = _T('\0');
+ }
+ }
+ }
+ else
+ {
+ // Set it
+ if (opts.xstatus_set == CHECK_XSTATUS_MUSIC)
+ {
+ ics.flags = CSSF_MASK_STATUS;
+ if (CallProtoService(proto, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM) &ics) || status != XSTATUS_MUSIC)
+ return;
+ }
+ else if (opts.xstatus_set == CHECK_XSTATUS)
+ {
+ ics.flags = CSSF_MASK_STATUS;
+ if (!CallProtoService(proto, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM) &ics) && status != XSTATUS_MUSIC && status != 0)
+ return;
+ }
+ else
+ {
+ // Store old data
+ ics.flags = CSSF_MASK_STATUS;
+ if (!CallProtoService(proto, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM) &ics) && status != XSTATUS_MUSIC)
+ {
+ ProtocolInfo *pi = GetProtoInfo(proto);
+ if (pi != NULL)
+ {
+ ics.flags = CSSF_TCHAR | CSSF_MASK_STATUS | CSSF_MASK_NAME | CSSF_MASK_MESSAGE;
+ ics.status = &pi->old_xstatus;
+ ics.ptszName = pi->old_xstatus_name;
+ ics.ptszMessage = pi->old_xstatus_message;
+
+ CallProtoService(proto, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM) &ics);
+ }
+ }
+ }
+
+ TCHAR *fr[] = {
+ _T("listening"), (TCHAR *) GetParsedFormat(0, (WPARAM) lti),
+ _T("artist"), UNKNOWN(lti->ptszArtist),
+ _T("album"), UNKNOWN(lti->ptszAlbum),
+ _T("title"), UNKNOWN(lti->ptszTitle),
+ _T("track"), UNKNOWN(lti->ptszTrack),
+ _T("year"), UNKNOWN(lti->ptszYear),
+ _T("genre"), UNKNOWN(lti->ptszGenre),
+ _T("length"), UNKNOWN(lti->ptszLength),
+ _T("player"), UNKNOWN(lti->ptszPlayer),
+ _T("type"), UNKNOWN(lti->ptszType)
+ };
+
+ Buffer<TCHAR> name;
+ ReplaceTemplate(&name, NULL, opts.xstatus_name, fr, MAX_REGS(fr));
+ Buffer<TCHAR> msg;
+ ReplaceTemplate(&msg, NULL, opts.xstatus_message, fr, MAX_REGS(fr));
+
+ status = XSTATUS_MUSIC;
+ ics.flags = CSSF_TCHAR | CSSF_MASK_STATUS | CSSF_MASK_NAME | CSSF_MASK_MESSAGE;
+ ics.status = &status;
+ ics.ptszName = name.str;
+ ics.ptszMessage = msg.str;
+
+ CallProtoService(proto, PS_ICQ_SETCUSTOMSTATUSEX, 0, (LPARAM) &ics);
+
+ mir_free(fr[1]);
+ }
+ }
+}
+
+
+int EnableListeningTo(WPARAM wParam,LPARAM lParam)
+{
+ if (!loaded)
+ return -1;
+
+ char *proto = (char *)wParam;
+
+ if (proto == NULL || proto[0] == 0)
+ {
+ // For all protocols
+ for (unsigned int i = 1; i < proto_itens.size(); ++i)
+ {
+ EnableListeningTo((WPARAM) proto_itens[i].proto, lParam);
+ }
+ }
+ else
+ {
+ if (!ProtoServiceExists(proto, PS_SET_LISTENINGTO) &&
+ !ProtoServiceExists(proto, PS_ICQ_SETCUSTOMSTATUSEX))
+ return 0;
+
+ char setting[256];
+ mir_snprintf(setting, sizeof(setting), "%sEnabled", proto);
+ DBWriteContactSettingByte(NULL, MODULE_NAME, setting, (BOOL) lParam);
+
+ // Modify menu info
+ ProtocolInfo *info = GetProtoInfo(proto);
+ if (info != NULL)
+ {
+ CLISTMENUITEM clmi = {0};
+ clmi.cbSize = sizeof(clmi);
+ clmi.flags = CMIM_FLAGS
+ | (lParam ? CMIF_CHECKED : 0)
+ | (opts.enable_sending ? 0 : CMIF_GRAYED);
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) info->hMenu, (LPARAM) &clmi);
+
+ if (!opts.enable_sending || !lParam)
+ SetListeningInfo(proto, NULL);
+ else
+ SetListeningInfo(proto, GetListeningInfo());
+ }
+
+ // Set all protos info
+ UpdateGlobalStatusMenus();
+ }
+
+ StartTimer();
+
+ NotifyEventHooks(hEnableStateChangedEvent, wParam, lParam);
+
+ return 0;
+}
+
+
+int HotkeysEnable(WPARAM wParam,LPARAM lParam)
+{
+ return EnableListeningTo(lParam, TRUE);
+}
+
+
+int HotkeysDisable(WPARAM wParam,LPARAM lParam)
+{
+ return EnableListeningTo(lParam, FALSE);
+}
+
+
+int HotkeysToggle(WPARAM wParam,LPARAM lParam)
+{
+ return EnableListeningTo(lParam, !ListeningToEnabled((char *)lParam, TRUE));
+}
+
+
+int GetTextFormat(WPARAM wParam,LPARAM lParam)
+{
+ if (!loaded)
+ return NULL;
+
+ return (int) mir_tstrdup(opts.templ);
+}
+
+
+int GetParsedFormat(WPARAM wParam,LPARAM lParam)
+{
+ if (!loaded)
+ return NULL;
+
+ LISTENINGTOINFO *lti = (LISTENINGTOINFO *) lParam;
+
+ if (lti == NULL)
+ return NULL;
+
+ TCHAR *fr[] = {
+ _T("artist"), UNKNOWN(lti->ptszArtist),
+ _T("album"), UNKNOWN(lti->ptszAlbum),
+ _T("title"), UNKNOWN(lti->ptszTitle),
+ _T("track"), UNKNOWN(lti->ptszTrack),
+ _T("year"), UNKNOWN(lti->ptszYear),
+ _T("genre"), UNKNOWN(lti->ptszGenre),
+ _T("length"), UNKNOWN(lti->ptszLength),
+ _T("player"), UNKNOWN(lti->ptszPlayer),
+ _T("type"), UNKNOWN(lti->ptszType)
+ };
+
+ Buffer<TCHAR> ret;
+ ReplaceTemplate(&ret, NULL, opts.templ, fr, MAX_REGS(fr));
+ return (int) ret.detach();
+}
+
+
+int GetOverrideContactOption(WPARAM wParam,LPARAM lParam)
+{
+ return (int) opts.override_contact_template;
+}
+
+
+int GetUnknownText(WPARAM wParam,LPARAM lParam)
+{
+ return (int) opts.unknown;
+}
+
+
+void SetListeningInfos(LISTENINGTOINFO *lti)
+{
+ for (unsigned int i = 1; i < proto_itens.size(); ++i)
+ {
+ SetListeningInfo(proto_itens[i].proto, lti);
+ }
+}
+
+static void CALLBACK GetInfoTimer(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
+{
+ if (hTimer != NULL)
+ {
+ KillTimer(NULL, hTimer);
+ hTimer = NULL;
+ }
+
+ // Check if we can set it now...
+ DWORD now = GetTickCount();
+ if (now < lastInfoSetTime + MIN_TIME_BEETWEEN_SETS)
+ {
+ hTimer = SetTimer(NULL, NULL, lastInfoSetTime + MIN_TIME_BEETWEEN_SETS - now, GetInfoTimer);
+ return;
+ }
+ lastInfoSetTime = GetTickCount(); // TODO Move this to inside the if that really sets
+
+ if (!opts.enable_sending)
+ {
+// m_log(_T("GetInfoTimer"), _T("!opts.enable_sending"));
+ SetListeningInfos(NULL);
+ return;
+ }
+
+ // Set it
+ int changed = ChangedListeningInfo();
+ if (changed < 0)
+ {
+// m_log(_T("GetInfoTimer"), _T("changed < 0"));
+ SetListeningInfos(NULL);
+ }
+ else if (changed > 0)
+ {
+// m_log(_T("GetInfoTimer"), _T("changed > 0"));
+ SetListeningInfos(GetListeningInfo());
+ }
+
+ StartTimer();
+}
+
+void StartTimer()
+{
+ // See if any protocol want Listening info
+ BOOL want = FALSE;
+
+ if (opts.enable_sending)
+ {
+ if (!players[WATRACK]->enabled)
+ {
+ // See if any player needs it
+ BOOL needPoll = FALSE;
+ int i;
+ for (i = FIRST_PLAYER; i < NUM_PLAYERS; i++)
+ {
+ if (players[i]->needPoll)
+ {
+ needPoll = TRUE;
+ break;
+ }
+ }
+
+ if (needPoll)
+ {
+ // Now see protocols
+ for (unsigned int i = 1; i < proto_itens.size(); ++i)
+ {
+ if (ListeningToEnabled(proto_itens[i].proto))
+ {
+ want = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (want)
+ {
+ if (hTimer == NULL)
+ hTimer = SetTimer(NULL, NULL, opts.time_to_pool * 1000, GetInfoTimer);
+ }
+ else
+ {
+ if (hTimer != NULL)
+ {
+ KillTimer(NULL, hTimer);
+ hTimer = NULL;
+
+ // To be sure that no one was left behind
+// m_log(_T("StartTimer"), _T("To be sure that no one was left behind"));
+ SetListeningInfos(NULL);
+ }
+ }
+}
+
+void HasNewListeningInfo()
+{
+ if (hTimer != NULL)
+ {
+ KillTimer(NULL, hTimer);
+ hTimer = NULL;
+ }
+
+ hTimer = SetTimer(NULL, NULL, 100, GetInfoTimer);
+}
+
+
+int ClistExtraListRebuild(WPARAM wParam, LPARAM lParam)
+{
+ HICON hIcon = IcoLib_LoadIcon(ICON_NAME);
+
+ hExtraImage = (HANDLE) CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM) hIcon, 0);
+
+ IcoLib_ReleaseIcon(hIcon);
+
+ return 0;
+}
+
+void SetExtraIcon(HANDLE hContact, BOOL set)
+{
+ if (hExtraIcon != NULL)
+ {
+ ExtraIcon_SetIcon(hExtraIcon, hContact, set ? ICON_NAME : NULL);
+ }
+ else if (opts.show_adv_icon && hExtraImage != NULL)
+ {
+ IconExtraColumn iec;
+ iec.cbSize = sizeof(iec);
+ iec.hImage = set ? hExtraImage : (HANDLE)-1;
+ if (opts.adv_icon_slot < 2)
+ {
+ iec.ColumnType = opts.adv_icon_slot + EXTRA_ICON_ADV1;
+ }
+ else
+ {
+ int first = CallService(MS_CLUI_GETCAPS, 0, CLUIF2_USEREXTRASTART);
+ iec.ColumnType = opts.adv_icon_slot - 2 + first;
+ }
+
+ CallService(MS_CLIST_EXTRA_SET_ICON, (WPARAM)hContact, (LPARAM)&iec);
+ }
+}
+
+int SettingChanged(WPARAM wParam,LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE) wParam;
+ if (hContact == NULL)
+ return 0;
+
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam;
+ if (strcmp(cws->szSetting, "ListeningTo") != 0)
+ return 0;
+
+ char *proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (proto == NULL)
+ return 0;
+
+ if (strcmp(cws->szModule, proto) != 0)
+ return 0;
+
+ if (cws->value.type == DBVT_DELETED || cws->value.ptszVal == NULL || cws->value.ptszVal[0] == 0)
+ SetExtraIcon(hContact, FALSE);
+ else
+ SetExtraIcon(hContact, TRUE);
+
+ return 0;
+}
+
+
+int SetNewSong(WPARAM wParam,LPARAM lParam)
+{
+ if (lParam == NULL)
+ return -1;
+
+ if (lParam == LISTENINGTO_ANSI)
+ {
+ CharToWchar data((char *) wParam);
+ ((GenericPlayer *) players[GENERIC])->NewData(data, wcslen(data));
+ }
+ else
+ {
+ WCHAR *data = (WCHAR *) wParam;
+ ((GenericPlayer *) players[GENERIC])->NewData(data, wcslen(data));
+ }
+
+
+ return 0;
+}
+
+
+TCHAR* VariablesParseInfo(ARGUMENTSINFO *ai)
+{
+ if (ai->cbSize < sizeof(ARGUMENTSINFO))
+ return NULL;
+
+ LISTENINGTOINFO *lti = GetListeningInfo();
+ if (lti == NULL)
+ {
+ ai->flags = AIF_FALSE;
+ return mir_tstrdup(_T(""));
+ }
+
+ TCHAR *fr[] = {
+ _T("artist"), UNKNOWN(lti->ptszArtist),
+ _T("album"), UNKNOWN(lti->ptszAlbum),
+ _T("title"), UNKNOWN(lti->ptszTitle),
+ _T("track"), UNKNOWN(lti->ptszTrack),
+ _T("year"), UNKNOWN(lti->ptszYear),
+ _T("genre"), UNKNOWN(lti->ptszGenre),
+ _T("length"), UNKNOWN(lti->ptszLength),
+ _T("player"), UNKNOWN(lti->ptszPlayer),
+ _T("type"), UNKNOWN(lti->ptszType)
+ };
+
+ Buffer<TCHAR> ret;
+ ReplaceTemplate(&ret, NULL, opts.templ, fr, MAX_REGS(fr));
+ return ret.detach();
+}
+
+#define VARIABLES_PARSE_BODY(__field__) \
+ if (ai->cbSize < sizeof(ARGUMENTSINFO)) \
+ return NULL; \
+ \
+ LISTENINGTOINFO *lti = GetListeningInfo(); \
+ if (lti == NULL) \
+ { \
+ ai->flags = AIF_FALSE; \
+ return mir_tstrdup(_T("")); \
+ } \
+ else if (IsEmpty(lti->__field__)) \
+ { \
+ ai->flags = AIF_FALSE; \
+ return mir_tstrdup(opts.unknown); \
+ } \
+ else \
+ { \
+ ai->flags = AIF_DONTPARSE; \
+ TCHAR *ret = mir_tstrdup(lti->__field__); \
+ return ret; \
+ }
+
+
+TCHAR* VariablesParseType(ARGUMENTSINFO *ai)
+{
+ VARIABLES_PARSE_BODY(ptszType);
+}
+
+TCHAR* VariablesParseArtist(ARGUMENTSINFO *ai)
+{
+ VARIABLES_PARSE_BODY(ptszArtist);
+}
+
+TCHAR* VariablesParseAlbum(ARGUMENTSINFO *ai)
+{
+ VARIABLES_PARSE_BODY(ptszAlbum);
+}
+
+TCHAR* VariablesParseTitle(ARGUMENTSINFO *ai)
+{
+ VARIABLES_PARSE_BODY(ptszTitle);
+}
+
+TCHAR* VariablesParseTrack(ARGUMENTSINFO *ai)
+{
+ VARIABLES_PARSE_BODY(ptszTrack);
+}
+
+TCHAR* VariablesParseYear(ARGUMENTSINFO *ai)
+{
+ VARIABLES_PARSE_BODY(ptszYear);
+}
+
+TCHAR* VariablesParseGenre(ARGUMENTSINFO *ai)
+{
+ VARIABLES_PARSE_BODY(ptszGenre);
+}
+
+TCHAR* VariablesParseLength(ARGUMENTSINFO *ai)
+{
+ VARIABLES_PARSE_BODY(ptszLength);
+}
+
+TCHAR* VariablesParsePlayer(ARGUMENTSINFO *ai)
+{
+ VARIABLES_PARSE_BODY(ptszPlayer);
+}
+
+
diff --git a/Plugins/listeningto/listeningto.dsp b/Plugins/listeningto/listeningto.dsp
new file mode 100644
index 0000000..bed963d
--- /dev/null
+++ b/Plugins/listeningto/listeningto.dsp
@@ -0,0 +1,327 @@
+# Microsoft Developer Studio Project File - Name="listeningto" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=listeningto - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "listeningto.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "listeningto.mak" CFG="listeningto - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "listeningto - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "listeningto - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "listeningto - Win32 Unicode Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "listeningto - Win32 Unicode Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "listeningto - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O1 /YX /FD /c
+# SUBTRACT BASE CPP /Fr
+# ADD CPP /nologo /G4 /MT /W3 /GX /O2 /Ob0 /I "../../include" /I "sdk" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Fr /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 user32.lib shell32.lib wininet.lib gdi32.lib /nologo /base:"0x67100000" /dll /machine:I386 /filealign:0x200
+# SUBTRACT BASE LINK32 /pdb:none /map
+# ADD LINK32 kernel32.lib user32.lib ole32.lib oleaut32.lib /nologo /base:"0x3EC20000" /dll /map /machine:I386 /out:"..\..\bin\release\Plugins\listeningto.dll" /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT LINK32 /profile /pdb:none
+
+!ELSEIF "$(CFG)" == "listeningto - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /MT /W3 /GX /O2 /Ob0 /I "../../include" /FR /YX /FD /c
+# ADD CPP /nologo /G4 /MTd /W3 /GX /ZI /Od /I "../../include" /I "sdk" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..bin\release\Plugins\listeningto.dll" /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT BASE LINK32 /profile /pdb:none
+# ADD LINK32 kernel32.lib user32.lib ole32.lib oleaut32.lib /nologo /base:"0x3EC20000" /dll /incremental:yes /debug /machine:I386 /out:"..\..\bin\debug\Plugins\listeningto.dll" /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT LINK32 /profile /pdb:none
+
+!ELSEIF "$(CFG)" == "listeningto - Win32 Unicode Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "listeningto___Win32_Unicode_Debug"
+# PROP BASE Intermediate_Dir "listeningto___Win32_Unicode_Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Unicode_Debug"
+# PROP Intermediate_Dir "Unicode_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /MTd /W3 /GX /ZI /Od /I "../../include" /FR /YX /FD /c
+# ADD CPP /nologo /G4 /MTd /W3 /GX /ZI /Od /I "../../include" /I "sdk" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /D "_USRDLL" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x32100000" /dll /incremental:yes /debug /machine:I386 /out:"..\..\bin\debug\Plugins\listeningto.dll" /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT BASE LINK32 /profile /pdb:none
+# ADD LINK32 kernel32.lib user32.lib ole32.lib oleaut32.lib /nologo /base:"0x3EC20000" /dll /incremental:yes /debug /machine:I386 /out:"..\..\bin\debug unicode\Plugins\listeningtoW.dll" /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT LINK32 /profile /pdb:none
+
+!ELSEIF "$(CFG)" == "listeningto - Win32 Unicode Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "listeningto___Win32_Unicode_Release"
+# PROP BASE Intermediate_Dir "listeningto___Win32_Unicode_Release"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Unicode_Release"
+# PROP Intermediate_Dir "Unicode_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /MT /W3 /GX /O2 /Ob0 /I "../../include" /Fr /YX /FD /c
+# ADD CPP /nologo /G4 /MT /W3 /GX /O2 /Ob0 /I "../../include" /I "sdk" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /D "_USRDLL" /Fr /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x32100000" /dll /map /machine:I386 /out:"..\..\bin\release\Plugins\listeningto.dll" /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT BASE LINK32 /profile /pdb:none
+# ADD LINK32 kernel32.lib user32.lib ole32.lib oleaut32.lib /nologo /base:"0x3EC20000" /dll /map /machine:I386 /out:"..\..\bin\release unicode\Plugins\listeningtoW.dll" /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT LINK32 /profile /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "listeningto - Win32 Release"
+# Name "listeningto - Win32 Debug"
+# Name "listeningto - Win32 Unicode Debug"
+# Name "listeningto - Win32 Unicode Release"
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\commons.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\m_listeningto.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\utils\mir_buffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\utils\mir_icons.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\utils\mir_memory.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\utils\mir_options.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\music.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\res\listening_to.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\ttb_disabled.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\ttb_enabled.bmp
+# End Source File
+# End Group
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\listeningto.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\utils\mir_icons.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\utils\mir_options.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\music.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.cpp
+# End Source File
+# End Group
+# Begin Group "Players"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\players\foobar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\players\foobar.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\players\generic.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\players\generic.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\players\itunes.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\players\itunes.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\players\player.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\players\player.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\players\watrack.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\players\watrack.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\players\winamp.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\players\winamp.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\players\wmp.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\players\wmp.h
+# End Source File
+# End Group
+# Begin Group "Docs"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Docs\langpack_listeningto.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\Docs\listeningto_changelog.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\Docs\listeningto_readme.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\Docs\listeningto_version.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\Docs\readme_players.txt
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/Plugins/listeningto/listeningto.dsw b/Plugins/listeningto/listeningto.dsw
new file mode 100644
index 0000000..ed56a68
--- /dev/null
+++ b/Plugins/listeningto/listeningto.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "listeningto"=".\listeningto.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/Plugins/listeningto/m_listeningto.h b/Plugins/listeningto/m_listeningto.h
new file mode 100644
index 0000000..e529a31
--- /dev/null
+++ b/Plugins/listeningto/m_listeningto.h
@@ -0,0 +1,79 @@
+/*
+Copyright (C) 2006 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __M_LISTENINGTO_H__
+# define __M_LISTENINGTO_H__
+
+
+#define MIID_LISTENINGTO { 0x1fc1efa, 0xaa9f, 0x461b, { 0x92, 0x69, 0xaf, 0x66, 0x6b, 0x89, 0x31, 0xee } }
+
+
+// To be used by other plugins to send listening info to miranda
+#define MIRANDA_WINDOWCLASS _T("Miranda.ListeningTo")
+#define MIRANDA_DW_PROTECTION 0x8754
+
+#define LISTENINGTO_ANSI 1
+#define LISTENINGTO_UNICODE 2
+
+#ifdef UNICODE
+# define LISTENINGTO_TCHAR LISTENINGTO_UNICODE
+#else
+# define LISTENINGTO_TCHAR LISTENINGTO_ANSI
+#endif
+
+
+/*
+Return TRUE if sending listening to is enabled for this protocol
+
+wParam: char * - protocol name or NULL for all protocols
+lParam: ignored
+*/
+#define MS_LISTENINGTO_ENABLED "ListeningTo/Enabled"
+
+
+/*
+Enable/disable sending listening to this protocol
+
+wParam: char * - protocol name or NULL for all protocols
+lParam: BOOL - TRUE to enable, FALSE to disable
+*/
+#define MS_LISTENINGTO_ENABLE "ListeningTo/Enable"
+
+
+/*
+Notification fired when enable state changed
+
+wParam: char * - protocol name or NULL for all protocols
+lParam: BOOL - enabled
+*/
+#define ME_LISTENINGTO_ENABLE_STATE_CHANGED "ListeningTo/EnableStateChanged"
+
+
+/*
+Provide new info about a song change to listening to
+
+wParam: WCHAR * or char * - song data, in format "<Status 0-stoped 1-playing>\\0<Player>\\0<Type>\\0<Title>\\0<Artist>\\0<Album>\\0<Track>\\0<Year>\\0<Genre>\\0<Length (secs)>\\0<Radio Station>\\0"
+lParam: format of wParam: one of LISTENINGTO_ANSI or LISTENINGTO_UNICODE . Anything else will be handled as unicode
+*/
+#define MS_LISTENINGTO_SET_NEW_SONG "ListeningTo/SetNewSong"
+
+
+
+#endif // __M_LISTENINGTO_H__
diff --git a/Plugins/listeningto/music.cpp b/Plugins/listeningto/music.cpp
new file mode 100644
index 0000000..4d93ac2
--- /dev/null
+++ b/Plugins/listeningto/music.cpp
@@ -0,0 +1,171 @@
+/*
+Copyright (C) 2006 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "commons.h"
+
+
+Player *players[NUM_PLAYERS];
+static LISTENINGTOINFO current = {0};
+
+
+void InitMusic()
+{
+ players[WATRACK] = new WATrack();
+ players[GENERIC] = new GenericPlayer();
+ players[WMP] = new WindowsMediaPlayer();
+ players[WINAMP] = new Winamp();
+ players[ITUNES] = new ITunes();
+ players[FOOBAR] = new Foobar();
+}
+
+
+void FreeMusic()
+{
+ for(int i = 0; i < NUM_PLAYERS; i++)
+ {
+ delete players[i];
+ players[i] = NULL;
+ }
+}
+
+
+void EnableDisablePlayers()
+{
+ for(int i = 0; i < NUM_PLAYERS; i++)
+ players[i]->EnableDisable();
+}
+
+
+void FreeListeningInfo(LISTENINGTOINFO *lti)
+{
+ lti->cbSize = 0;
+ lti->dwFlags = 0;
+ MIR_FREE(lti->ptszArtist);
+ MIR_FREE(lti->ptszAlbum);
+ MIR_FREE(lti->ptszTitle);
+ MIR_FREE(lti->ptszTrack);
+ MIR_FREE(lti->ptszYear);
+ MIR_FREE(lti->ptszGenre);
+ MIR_FREE(lti->ptszLength);
+ MIR_FREE(lti->ptszPlayer);
+ MIR_FREE(lti->ptszType);
+}
+
+void CopyListeningInfo(LISTENINGTOINFO *dest, const LISTENINGTOINFO * const src)
+{
+ FreeListeningInfo(dest);
+
+ dest->cbSize = src->cbSize;
+ dest->dwFlags = src->dwFlags;
+ dest->ptszArtist = mir_tstrdup(src->ptszArtist);
+ dest->ptszAlbum = mir_tstrdup(src->ptszAlbum);
+ dest->ptszTitle = mir_tstrdup(src->ptszTitle);
+ dest->ptszTrack = mir_tstrdup(src->ptszTrack);
+ dest->ptszYear = mir_tstrdup(src->ptszYear);
+ dest->ptszGenre = mir_tstrdup(src->ptszGenre);
+ dest->ptszLength = mir_tstrdup(src->ptszLength);
+ dest->ptszPlayer = mir_tstrdup(src->ptszPlayer);
+ dest->ptszType = mir_tstrdup(src->ptszType);
+}
+
+BOOL Equals(const LISTENINGTOINFO *lti1, const LISTENINGTOINFO *lti2)
+{
+ if (lti1->cbSize != lti2->cbSize)
+ return FALSE;
+
+ return lstrcmpi(lti1->ptszArtist, lti2->ptszArtist) == 0
+ && lstrcmpi(lti1->ptszAlbum, lti2->ptszAlbum) == 0
+ && lstrcmpi(lti1->ptszTitle, lti2->ptszTitle) == 0
+ && lstrcmpi(lti1->ptszTrack, lti2->ptszTrack) == 0
+ && lstrcmpi(lti1->ptszYear, lti2->ptszYear) == 0
+ && lstrcmpi(lti1->ptszGenre, lti2->ptszGenre) == 0
+ && lstrcmpi(lti1->ptszLength, lti2->ptszLength) == 0
+ && lstrcmpi(lti1->ptszPlayer, lti2->ptszPlayer) == 0
+ && lstrcmpi(lti1->ptszType, lti2->ptszType) == 0;
+}
+
+
+int ChangedListeningInfo()
+{
+// m_log(_T("ChangedListeningInfo"), _T("Start"));
+
+ BOOL changed = FALSE;
+ BOOL playing = FALSE;
+
+ int first = (players[WATRACK]->enabled ? WATRACK : GENERIC);
+ int last = (players[WATRACK]->enabled ? WATRACK + 1 : NUM_PLAYERS);
+ for (int i = first; i < last; i++)
+ {
+ if (!players[i]->enabled)
+ continue;
+
+ LISTENINGTOINFO lti = {0};
+ if (!players[i]->GetListeningInfo(&lti))
+ continue;
+
+ if (!IsTypeEnabled(&lti))
+ {
+ FreeListeningInfo(&lti);
+ continue;
+ }
+
+ playing = TRUE;
+
+// m_log(_T("ChangedListeningInfo"), _T("Has : %s : %d"), players[i]->name, lti.cbSize);
+
+ if (Equals(&current, &lti))
+ {
+// m_log(_T("ChangedListeningInfo"), _T("Is equals"));
+ FreeListeningInfo(&lti);
+ }
+ else
+ {
+// m_log(_T("ChangedListeningInfo"), _T("Is different"));
+
+ FreeListeningInfo(&current);
+
+ memmove(&current, &lti, sizeof(current));
+
+ changed = 1;
+ }
+
+ break;
+ }
+
+ if (!playing && current.cbSize != 0)
+ {
+ FreeListeningInfo(&current);
+ changed = 1;
+ }
+
+ if (!changed)
+ return 0;
+ else
+ return current.cbSize == 0 ? -1 : 1;
+}
+
+
+LISTENINGTOINFO * GetListeningInfo()
+{
+ if (current.cbSize == 0)
+ return NULL;
+
+ return &current;
+}
diff --git a/Plugins/listeningto/music.h b/Plugins/listeningto/music.h
new file mode 100644
index 0000000..76efd41
--- /dev/null
+++ b/Plugins/listeningto/music.h
@@ -0,0 +1,68 @@
+/*
+Copyright (C) 2006 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __MUSIC_H__
+# define __MUSIC_H__
+
+
+#include "commons.h"
+
+
+// Players
+#include "players\\player.h"
+#include "players\\watrack.h"
+#include "players\\generic.h"
+#include "players\\winamp.h"
+#include "players\\foobar.h"
+#include "players\\itunes.h"
+#include "players\\wmp.h"
+
+
+// First non polling ones
+#define WATRACK 0
+#define GENERIC 1
+
+#define FIRST_PLAYER 2
+#define WMP 2
+#define WINAMP 3
+#define ITUNES 4
+#define FOOBAR 5
+#define NUM_PLAYERS 6
+
+extern Player *players[NUM_PLAYERS];
+
+
+void InitMusic();
+void FreeMusic();
+void EnableDisablePlayers();
+
+
+int ChangedListeningInfo();
+LISTENINGTOINFO * GetListeningInfo();
+
+
+// Helper functions to players
+void FreeListeningInfo(LISTENINGTOINFO *lti);
+void CopyListeningInfo(LISTENINGTOINFO *dest, const LISTENINGTOINFO * const src);
+
+
+
+
+#endif // __MUSIC_H__
diff --git a/Plugins/listeningto/options.cpp b/Plugins/listeningto/options.cpp
new file mode 100644
index 0000000..fa10efb
--- /dev/null
+++ b/Plugins/listeningto/options.cpp
@@ -0,0 +1,349 @@
+/*
+Copyright (C) 2006 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "commons.h"
+
+
+
+// Prototypes /////////////////////////////////////////////////////////////////////////////////////
+
+HANDLE hOptHook = NULL;
+
+Options opts;
+
+extern std::vector<ProtocolInfo> proto_itens;
+extern HANDLE hExtraIcon;
+
+BOOL ListeningToEnabled(char *proto, BOOL ignoreGlobal = FALSE);
+
+
+
+static BOOL CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static BOOL CALLBACK PlayersDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static BOOL CALLBACK FormatDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+
+static OptPageControl optionsControls[] = {
+ { &opts.enable_sending, CONTROL_CHECKBOX, IDC_ENABLE_SEND, "EnableSend", TRUE },
+ { &opts.enable_music, CONTROL_CHECKBOX, IDC_ENABLE_MUSIC, "EnableMusic", TRUE },
+ { &opts.enable_radio, CONTROL_CHECKBOX, IDC_ENABLE_RADIO, "EnableRadio", TRUE },
+ { &opts.enable_video, CONTROL_CHECKBOX, IDC_ENABLE_VIDEO, "EnableVideo", TRUE },
+ { &opts.enable_others, CONTROL_CHECKBOX, IDC_ENABLE_OTHERS, "EnableOthers", TRUE },
+ { &opts.xstatus_set, CONTROL_RADIO, IDC_SET_XSTATUS, "XStatusSet", 0, SET_XSTATUS },
+ { &opts.xstatus_set, CONTROL_RADIO, IDC_CHECK_XSTATUS, "XStatusSet", 0, CHECK_XSTATUS },
+ { &opts.xstatus_set, CONTROL_RADIO, IDC_CHECK_XSTATUS_MUSIC, "XStatusSet", 0, CHECK_XSTATUS_MUSIC },
+ { &opts.xstatus_set, CONTROL_RADIO, IDC_IGNORE_XSTATUS, "XStatusSet", 0, IGNORE_XSTATUS },
+ { &opts.override_contact_template, CONTROL_CHECKBOX, IDC_OVERRIDE_CONTACTS_TEMPLATE, "OverrideContactsTemplate", FALSE},
+ { &opts.show_adv_icon, CONTROL_CHECKBOX, IDC_SHOW_ADV_ICON, "ShowAdvancedIcon", FALSE},
+ { &opts.adv_icon_slot, CONTROL_COMBO, IDC_ADV_ICON, "AdvancedIconSlot", 1}
+};
+
+static UINT optionsExpertControls[] = {
+ IDC_XSTATUS_G, IDC_XSTATUS_L, IDC_SET_XSTATUS, IDC_CHECK_XSTATUS, IDC_CHECK_XSTATUS_MUSIC, IDC_IGNORE_XSTATUS,
+ IDC_CONTACTS_G, IDC_SHOW_ADV_ICON, IDC_ADV_ICON
+};
+
+static OptPageControl formatControls[] = {
+ { &opts.templ, CONTROL_TEXT, IDC_TEMPLATE, "Template", (DWORD) _T("%title% - %artist%") },
+ { &opts.unknown, CONTROL_TEXT, IDC_UNKNOWN, "Unknown", (DWORD) _T("<Unknown>"), 0, 0, 128 },
+ { &opts.xstatus_name, CONTROL_TEXT, IDC_XSTATUS_NAME, "XStatusName", (DWORD) _T("Listening to") },
+ { &opts.xstatus_message, CONTROL_TEXT, IDC_XSTATUS_MESSAGE, "XStatusMessage", (DWORD) _T("%listening%") },
+ { &opts.nothing, CONTROL_TEXT, IDC_NOTHING, "Nothing", (DWORD) _T("<Nothing>"), 0, 0, 128 }
+};
+
+static OptPageControl playersControls[] = {
+ { NULL, CONTROL_CHECKBOX, IDC_WATRACK, "GetInfoFromWATrack", FALSE },
+ { &opts.time_to_pool, CONTROL_SPIN, IDC_POLL_TIMER, "TimeToPool", (WORD) 5, IDC_POLL_TIMER_SPIN, (WORD) 1, (WORD) 255 },
+ { NULL, CONTROL_CHECKBOX, IDC_WINAMP, "EnableWinamp", TRUE },
+ { NULL, CONTROL_CHECKBOX, IDC_ITUNES, "EnableITunes", TRUE },
+ { NULL, CONTROL_CHECKBOX, IDC_WMP, "EnableWMP", TRUE },
+ { NULL, CONTROL_CHECKBOX, IDC_FOOBAR, "EnableFoobar", TRUE },
+ { &opts.enable_other_players, CONTROL_CHECKBOX, IDC_OTHER, "EnableOtherPlayers", TRUE },
+ { &opts.enable_code_injection, CONTROL_CHECKBOX, IDC_CODE_INJECTION, "EnableCodeInjection", TRUE }
+};
+
+
+
+
+// Functions //////////////////////////////////////////////////////////////////////////////////////
+
+
+int InitOptionsCallback(WPARAM wParam,LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp;
+ ZeroMemory(&odp,sizeof(odp));
+ odp.cbSize=sizeof(odp);
+ odp.position=0;
+ odp.hInstance=hInst;
+ odp.ptszGroup = TranslateT("Status");
+ odp.ptszTitle = TranslateT("Listening info");
+
+ odp.ptszTab = TranslateT("General");
+ odp.pfnDlgProc = OptionsDlgProc;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS);
+ odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR;
+ odp.expertOnlyControls = optionsExpertControls;
+ odp.nExpertOnlyControls = MAX_REGS(optionsExpertControls);
+ odp.nIDBottomSimpleControl = IDC_LISTENING_G;
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ odp.ptszTab = TranslateT("Format");
+ odp.pfnDlgProc = FormatDlgProc;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_FORMAT);
+ odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR | ODPF_EXPERTONLY;
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ odp.ptszTab = TranslateT("Players");
+ odp.pfnDlgProc = PlayersDlgProc;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_PLAYERS);
+ odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR | ODPF_EXPERTONLY;
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ return 0;
+}
+
+
+void InitOptions()
+{
+ playersControls[0].var = &players[WATRACK]->enabled;
+ playersControls[2].var = &players[WINAMP]->enabled;
+ playersControls[3].var = &players[ITUNES]->enabled;
+ playersControls[4].var = &players[WMP]->enabled;
+ playersControls[5].var = &players[FOOBAR]->enabled;
+
+ LoadOptions();
+
+ hOptHook = HookEvent(ME_OPT_INITIALISE, InitOptionsCallback);
+}
+
+
+void DeInitOptions()
+{
+ UnhookEvent(hOptHook);
+}
+
+
+void LoadOptions()
+{
+ LoadOpts(optionsControls, MAX_REGS(optionsControls), MODULE_NAME);
+ LoadOpts(formatControls, MAX_REGS(formatControls), MODULE_NAME);
+ LoadOpts(playersControls, MAX_REGS(playersControls), MODULE_NAME);
+}
+
+
+BOOL IsTypeEnabled(LISTENINGTOINFO *lti)
+{
+ if (lti == NULL)
+ return TRUE;
+
+#ifdef UNICODE
+ if (lti->dwFlags & LTI_UNICODE)
+ {
+ if (lstrcmpi(lti->ptszType, _T("Music")) == 0)
+ return opts.enable_music;
+ else if (lstrcmpi(lti->ptszType, _T("Radio")) == 0)
+ return opts.enable_radio;
+ else if (lstrcmpi(lti->ptszType, _T("Video")) == 0)
+ return opts.enable_video;
+ else
+ return opts.enable_others;
+ }
+ else
+#endif
+ {
+ if (strcmpi(lti->pszType, "Music") == 0)
+ return opts.enable_music;
+ else if (strcmpi(lti->pszType, "Radio") == 0)
+ return opts.enable_radio;
+ else if (strcmpi(lti->pszType, "Video") == 0)
+ return opts.enable_video;
+ else
+ return opts.enable_others;
+ }
+}
+
+
+static void OptionsEnableDisableCtrls(HWND hwndDlg)
+{
+ BOOL enabled = IsDlgButtonChecked(hwndDlg, IDC_ENABLE_SEND);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_MUSIC), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_RADIO), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_VIDEO), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_OTHERS), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_MENU), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_XSTATUS_G), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_XSTATUS_L), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SET_XSTATUS), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK_XSTATUS), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK_XSTATUS_MUSIC), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IGNORE_XSTATUS), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CONTACTS_G), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_OVERRIDE_CONTACTS_TEMPLATE), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOW_ADV_ICON), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ADV_ICON), enabled);
+}
+
+
+static BOOL CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ BOOL ret;
+ if (msg != WM_INITDIALOG)
+ ret = SaveOptsDlgProc(optionsControls, MAX_REGS(optionsControls), MODULE_NAME, hwndDlg, msg, wParam, lParam);
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ if (hExtraIcon != NULL)
+ {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_SHOW_ADV_ICON), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_ADV_ICON), SW_HIDE);
+ }
+ else
+ {
+ // Init combo
+ int total = 0, first = 0;
+ if (ServiceExists(MS_CLUI_GETCAPS))
+ {
+ total = CallService(MS_CLUI_GETCAPS, 0, CLUIF2_EXTRACOLUMNCOUNT);
+ first = CallService(MS_CLUI_GETCAPS, 0, CLUIF2_USEREXTRASTART);
+ }
+
+ SendDlgItemMessage(hwndDlg, IDC_ADV_ICON, CB_ADDSTRING, 0, (LPARAM) _T("1"));
+ SendDlgItemMessage(hwndDlg, IDC_ADV_ICON, CB_ADDSTRING, 0, (LPARAM) _T("2"));
+
+ if (total > 0)
+ {
+ TCHAR tmp[10];
+ for (int i = first; i <= total; i++)
+ SendDlgItemMessage(hwndDlg, IDC_ADV_ICON, CB_ADDSTRING, 0, (LPARAM) _itot(i - first + 3, tmp, 10));
+ }
+ }
+
+ ret = SaveOptsDlgProc(optionsControls, MAX_REGS(optionsControls), MODULE_NAME, hwndDlg, msg, wParam, lParam);
+ OptionsEnableDisableCtrls(hwndDlg);
+
+ break;
+ }
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_ENABLE_SEND:
+ {
+ if (HIWORD(wParam) == BN_CLICKED)
+ OptionsEnableDisableCtrls(hwndDlg);
+
+ break;
+ }
+ }
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ LPNMHDR lpnmhdr = (LPNMHDR)lParam;
+
+ if (lpnmhdr->idFrom == 0 && lpnmhdr->code == PSN_APPLY)
+ {
+ RebuildMenu();
+ StartTimer();
+ }
+
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+int playerDlgs[] = {
+ WINAMP, IDC_WINAMP,
+ WMP, IDC_WMP,
+ ITUNES, IDC_ITUNES,
+ FOOBAR, IDC_FOOBAR
+};
+
+
+static void PlayersEnableDisableCtrls(HWND hwndDlg)
+{
+ BOOL watrack_found = ServiceExists(MS_WAT_GETMUSICINFO);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_WATRACK), watrack_found);
+
+ BOOL enabled = !IsDlgButtonChecked(hwndDlg, IDC_WATRACK) || !watrack_found;
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PLAYERS_L), enabled);
+
+ BOOL needPoll = FALSE;
+ for (int i = 0; i < MAX_REGS(playerDlgs); i += 2)
+ {
+ EnableWindow(GetDlgItem(hwndDlg, playerDlgs[i+1]), enabled);
+ if (players[playerDlgs[i]]->needPoll && IsDlgButtonChecked(hwndDlg, playerDlgs[i+1]))
+ needPoll = TRUE;
+ }
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_OTHER), enabled);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_POLL_TIMER_L), enabled && needPoll);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_POLL_TIMER), enabled && needPoll);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_POLL_TIMER_SPIN), enabled && needPoll);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_POLL_TIMER_S_L), enabled && needPoll);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CODE_INJECTION), enabled);
+}
+
+static BOOL CALLBACK PlayersDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ BOOL ret = SaveOptsDlgProc(playersControls, MAX_REGS(playersControls), MODULE_NAME, hwndDlg, msg, wParam, lParam);
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ PlayersEnableDisableCtrls(hwndDlg);
+
+ break;
+ }
+ case WM_COMMAND:
+ {
+ if (HIWORD(wParam) == BN_CLICKED)
+ PlayersEnableDisableCtrls(hwndDlg);
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ LPNMHDR lpnmhdr = (LPNMHDR)lParam;
+
+ if (lpnmhdr->idFrom == 0 && lpnmhdr->code == PSN_APPLY)
+ {
+ EnableDisablePlayers();
+ StartTimer();
+ }
+
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static BOOL CALLBACK FormatDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ return SaveOptsDlgProc(formatControls, MAX_REGS(formatControls), MODULE_NAME, hwndDlg, msg, wParam, lParam);
+}
+
diff --git a/Plugins/listeningto/options.h b/Plugins/listeningto/options.h
new file mode 100644
index 0000000..b0848e8
--- /dev/null
+++ b/Plugins/listeningto/options.h
@@ -0,0 +1,88 @@
+/*
+Copyright (C) 2006 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __OPTIONS_H__
+# define __OPTIONS_H__
+
+
+#include "commons.h"
+
+#include <windows.h>
+
+
+#define POPUP_ACTION_DONOTHING 0
+#define POPUP_ACTION_CLOSEPOPUP 1
+#define POPUP_ACTION_OPENHISTORY 2
+
+#define POPUP_DELAY_DEFAULT 0
+#define POPUP_DELAY_CUSTOM 1
+#define POPUP_DELAY_PERMANENT 2
+
+#define SET_XSTATUS 0
+#define CHECK_XSTATUS 1
+#define CHECK_XSTATUS_MUSIC 2
+#define IGNORE_XSTATUS 3
+
+
+struct Options {
+ BOOL enable_sending;
+ BOOL enable_music;
+ BOOL enable_radio;
+ BOOL enable_video;
+ BOOL enable_others;
+
+ TCHAR templ[1024];
+ TCHAR unknown[128];
+
+ BOOL override_contact_template;
+ BOOL show_adv_icon;
+ int adv_icon_slot;
+
+ BOOL get_info_from_watrack;
+ BOOL enable_other_players;
+ BOOL enable_code_injection;
+ int time_to_pool;
+
+ WORD xstatus_set;
+ TCHAR xstatus_name[1024];
+ TCHAR xstatus_message[1024];
+ TCHAR nothing[128];
+};
+
+extern Options opts;
+
+
+// Initializations needed by options
+void InitOptions();
+
+// Deinitializations needed by options
+void DeInitOptions();
+
+
+// Loads the options from DB
+// It don't need to be called, except in some rare cases
+void LoadOptions();
+
+
+
+BOOL IsTypeEnabled(LISTENINGTOINFO *lti);
+
+
+#endif // __OPTIONS_H__
diff --git a/Plugins/listeningto/players/foo_mlt/foo_mlt.cpp b/Plugins/listeningto/players/foo_mlt/foo_mlt.cpp
new file mode 100644
index 0000000..42f86f7
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foo_mlt.cpp
@@ -0,0 +1,337 @@
+#include "foobar2000/SDK/foobar2000.h"
+#include "foobar2000/helpers/helpers.h"
+#include "..\..\m_listeningto.h"
+#include <windows.h>
+#include <process.h>
+
+
+using namespace pfc;
+
+
+// Globals //////////////////////////////////////////////////////////////////////////////
+
+
+#define MIRANDA_DW_PROTECTION 0x8754
+
+#define DATA_SIZE 1024
+
+UINT timer = 0;
+WCHAR lastSongData[DATA_SIZE] = L"";
+
+
+// Functions ////////////////////////////////////////////////////////////////////////////
+
+
+BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
+{
+ // Find the windows
+ TCHAR class_name[256];
+ if (GetClassName(hwnd, class_name, 256))
+ {
+ class_name[255] = _T('\0');
+
+ if (lstrcmpi(MIRANDA_WINDOWCLASS, class_name) == 0)
+ {
+ COPYDATASTRUCT *cds = (COPYDATASTRUCT *) lParam;
+ SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) cds);
+ }
+ }
+
+ return TRUE;
+}
+
+inline void SendData(WCHAR *text)
+{
+ static WCHAR lastMsg[DATA_SIZE] = L"";
+
+ if (wcscmp(lastMsg, text) == 0)
+ return;
+
+ // Prepare the struct
+ COPYDATASTRUCT cds;
+ cds.dwData = MIRANDA_DW_PROTECTION;
+ cds.lpData = text;
+ cds.cbData = (wcslen(text) + 1) * sizeof(WCHAR);
+
+ EnumWindows(EnumWindowsProc, (LPARAM) &cds);
+
+ wcsncpy(lastMsg, text, DATA_SIZE);
+ lastMsg[DATA_SIZE-1] = L'\0';
+}
+
+
+void Concat(WCHAR *data, size_t &size, const char *str, size_t len = 0)
+{
+ if (size < 3 * sizeof(WCHAR))
+ return;
+
+ if (str != NULL)
+ {
+ if (len == 0)
+ len = strlen(str);
+
+ if (size >= len + 3)
+ {
+ size -= MultiByteToWideChar(CP_UTF8, 0, str, len * sizeof(char), &data[DATA_SIZE - size], size * sizeof(WCHAR));
+ data[DATA_SIZE - size] = L'\0';
+ }
+ }
+
+ wcscat(data, L"\\0");
+ size -= 2;
+}
+
+
+void Concat(WCHAR *data, size_t &size)
+{
+ if (size < 3 * sizeof(WCHAR))
+ return;
+
+ wcscat(data, L"\\0");
+ size -= 2;
+}
+
+
+void Concat(WCHAR *data, size_t &size, const WCHAR *str, size_t len = 0)
+{
+ if (size < 3 * sizeof(WCHAR))
+ return;
+
+ if (str != NULL)
+ {
+ if (len == 0)
+ len = wcslen(str);
+
+ if (size >= len + 3)
+ {
+ wcscpy(&data[DATA_SIZE - size], str);
+ size -= len;
+ data[DATA_SIZE - size] = L'\0';
+ }
+ }
+
+ wcscat(data, L"\\0");
+ size -= 2;
+}
+
+
+void GetMetadata(const file_info *info, char *field, WCHAR *data, size_t &size)
+{
+ const char *val = info->meta_get(field, 0);
+ if (val != NULL && val[0] != '\0')
+ {
+ Concat(data, size, val);
+ }
+ else
+ {
+ Concat(data, size);
+ }
+}
+
+
+void KillTimer(UINT id = 0)
+{
+ if (id != 0)
+ {
+ KillTimer(NULL, id);
+ }
+ if (timer != 0)
+ {
+ if (timer != id)
+ KillTimer(NULL, timer);
+ timer = 0;
+ }
+}
+
+
+void CALLBACK SendEmptyData(HWND hWnd = 0, UINT nMsg = 0, UINT nIDEvent = 0, DWORD dwTime = 0)
+{
+ KillTimer(nIDEvent);
+
+ // L"<Status 0-stoped 1-playing>\\0<Player>\\0<Type>\\0<Title>\\0<Artist>\\0<Album>\\0<Track>\\0<Year>\\0<Genre>\\0<Length (secs)>\\0\\0"
+ SendData(L"0\\0foobar2000\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0");
+}
+
+
+void SetTimer()
+{
+ KillTimer();
+ timer = SetTimer(NULL, 1, 1000, SendEmptyData);
+}
+
+
+BOOL IsRadio(metadb_handle_ptr p_track)
+{
+ const char *filename = p_track->get_path();
+ return (filename != NULL && strstr(filename, "://") != 0 && strncmp(filename, "file://", 7) != 0);
+}
+
+
+void SendDataMusic(const char *filename, const file_info *info)
+{
+ WCHAR data[DATA_SIZE];
+ size_t size = DATA_SIZE;
+ data[0] = L'\0';
+
+ // L"<Status 0-stoped 1-playing>\\0<Player>\\0<Type>\\0<Title>\\0<Artist>\\0<Album>\\0<Track>\\0<Year>\\0<Genre>\\0<Length (secs)>\\0\\0"
+ Concat(data, size, "1");
+ Concat(data, size, "foobar2000");
+ Concat(data, size, "Music");
+
+ const char *val = info->meta_get("TITLE", 0);
+ if (val != NULL && val[0] != '\0')
+ {
+ Concat(data, size, val);
+ }
+ else if (filename != NULL && filename[0] != '\0')
+ {
+ const char *name = strrchr(filename, '\\');
+ if (name == NULL)
+ strrchr(filename, '/');
+
+ if (name == NULL)
+ {
+ Concat(data, size);
+ }
+ else
+ {
+ const char *dot = strrchr(name, '.');
+ Concat(data, size, name + 1, dot == NULL ? 0 : dot - name - 1);
+ }
+ }
+ else
+ {
+ Concat(data, size);
+ }
+
+ GetMetadata(info, "ARTIST", data, size);
+ GetMetadata(info, "ALBUM", data, size);
+ GetMetadata(info, "TRACKNUMBER", data, size);
+ GetMetadata(info, "DATE", data, size);
+ GetMetadata(info, "GENRE", data, size);
+
+ int len = (int) info->get_length();
+ if (len > 0)
+ {
+ char tmp[10];
+ Concat(data, size, itoa(len, tmp, 10));
+ }
+ else
+ {
+ Concat(data, size);
+ }
+
+ Concat(data, size);
+
+ SendData(data);
+ wcsncpy(lastSongData, data, DATA_SIZE);
+ lastSongData[DATA_SIZE-1] = L'\0';
+}
+
+void SendDataRadio(const file_info *info, const file_info *info2)
+{
+ WCHAR data[DATA_SIZE];
+ size_t size = DATA_SIZE;
+ data[0] = L'\0';
+
+ // L"<Status 0-stoped 1-playing>\\0<Player>\\0<Type>\\0<Title>\\0<Artist>\\0<Album>\\0<Track>\\0<Year>\\0<Genre>\\0<Length (secs)>\\0<Station name>\\0"
+ Concat(data, size, "1");
+ Concat(data, size, "foobar2000");
+ Concat(data, size, "Radio");
+
+ GetMetadata(info, "TITLE", data, size);
+ GetMetadata(info, "ARTIST", data, size);
+ GetMetadata(info, "ALBUM", data, size);
+ GetMetadata(info, "TRACKNUMBER", data, size);
+ GetMetadata(info, "DATE", data, size);
+ GetMetadata(info2, "GENRE", data, size);
+
+ int len = (int) info->get_length();
+ if (len > 0)
+ {
+ char tmp[10];
+ Concat(data, size, itoa(len, tmp, 10));
+ }
+ else
+ {
+ Concat(data, size);
+ }
+
+ // Station name
+ GetMetadata(info2, "TITLE", data, size);
+
+ SendData(data);
+ wcsncpy(lastSongData, data, DATA_SIZE);
+ lastSongData[DATA_SIZE-1] = L'\0';
+}
+
+
+// Foobar ////////////////////////////////////////////////////////////////////////////
+
+class play_callback_miranda : public play_callback_static
+{
+ virtual void on_playback_starting(play_control::t_track_command p_command, bool p_paused) {}
+ virtual void on_playback_new_track(metadb_handle_ptr p_track)
+ {
+ KillTimer();
+ if (IsRadio(p_track))
+ return;
+
+ in_metadb_sync_fromhandle l_sync(p_track);
+
+ const file_info *info;
+ if (p_track->get_info_locked(info))
+ SendDataMusic(p_track->get_path(), info);
+ }
+ virtual void on_playback_stop(play_control::t_stop_reason p_reason)
+ {
+ SetTimer();
+ }
+ virtual void on_playback_seek(double p_time) {}
+ virtual void on_playback_pause(bool p_state)
+ {
+ if (p_state)
+ {
+ SetTimer();
+ }
+ else
+ {
+ KillTimer();
+ if (lastSongData[0] != L'\0')
+ SendData(lastSongData);
+ }
+ }
+ virtual void on_playback_edited(metadb_handle_ptr p_track) {}
+ virtual void on_playback_dynamic_info(const file_info & info) {}
+ virtual void on_playback_dynamic_info_track(const file_info & info)
+ {
+ metadb_handle_ptr p_track;
+ static_api_ptr_t<play_control>()->get_now_playing(p_track);
+ if (p_track.is_valid())
+ {
+ if (IsRadio(p_track))
+ {
+ in_metadb_sync_fromhandle l_sync(p_track);
+
+ const file_info *info2;
+ if (!p_track->get_info_locked(info2))
+ return;
+
+ SendDataRadio(&info, info2);
+ }
+ p_track.release();
+ }
+ }
+ virtual void on_playback_time(double p_time) {}
+ virtual void on_volume_change(float p_new_val) {};
+
+ virtual unsigned get_flags()
+ {
+ return flag_on_playback_new_track | flag_on_playback_pause | flag_on_playback_stop | flag_on_playback_dynamic_info_track;
+ }
+};
+
+
+static play_callback_static_factory_t<play_callback_miranda> miranda_callback_factory;
+
+DECLARE_COMPONENT_VERSION("Miranda ListeningTo foobar2000 Plugin", "1.0", 0)
diff --git a/Plugins/listeningto/players/foo_mlt/foo_mlt.dsp b/Plugins/listeningto/players/foo_mlt/foo_mlt.dsp
new file mode 100644
index 0000000..faf6f58
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foo_mlt.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="foo_mlt" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=FOO_MLT - WIN32 DEBUG
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "foo_mlt.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "foo_mlt.mak" CFG="FOO_MLT - WIN32 DEBUG"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "foo_mlt - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "foo_mlt - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "foo_mlt - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "foo_mlt_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "foo_mlt_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\..\..\bin\release\Plugins\listeningto\foo_mlt.dll"
+
+!ELSEIF "$(CFG)" == "foo_mlt - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "foo_mlt_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x416 /d "_DEBUG"
+# ADD RSC /l 0x416 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib /nologo /dll /debug /machine:I386 /out:"..\..\..\..\bin\debug unicode\Plugins\listeningto\foo_mlt.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "foo_mlt - Win32 Release"
+# Name "foo_mlt - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\foo_mlt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\foo_mlt.def
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/Plugins/listeningto/players/foo_mlt/foo_mlt.sln b/Plugins/listeningto/players/foo_mlt/foo_mlt.sln
new file mode 100644
index 0000000..c315965
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foo_mlt.sln
@@ -0,0 +1,50 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "foo_mlt", "foo_mlt.vcproj", "{94734E61-D980-4A5F-AAAA-65105755CE24}"
+ ProjectSection(ProjectDependencies) = postProject
+ {E8091321-D79D-4575-86EF-064EA1A4A20D} = {E8091321-D79D-4575-86EF-064EA1A4A20D}
+ {EBFFFB4E-261D-44D3-B89C-957B31A0BF9C} = {EBFFFB4E-261D-44D3-B89C-957B31A0BF9C}
+ {EE47764E-A202-4F85-A767-ABDAB4AFF35F} = {EE47764E-A202-4F85-A767-ABDAB4AFF35F}
+ {71AD2674-065B-48F5-B8B0-E1F9D3892081} = {71AD2674-065B-48F5-B8B0-E1F9D3892081}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "foobar2000_SDK", "foobar2000\SDK\foobar2000_SDK.vcproj", "{E8091321-D79D-4575-86EF-064EA1A4A20D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "foobar2000_sdk_helpers", "foobar2000\helpers\foobar2000_sdk_helpers.vcproj", "{EE47764E-A202-4F85-A767-ABDAB4AFF35F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "foobar2000_component_client", "foobar2000\foobar2000_component_client\foobar2000_component_client.vcproj", "{71AD2674-065B-48F5-B8B0-E1F9D3892081}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pfc", "pfc\pfc.vcproj", "{EBFFFB4E-261D-44D3-B89C-957B31A0BF9C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug Unicode|Win32 = Debug Unicode|Win32
+ Release Unicode|Win32 = Release Unicode|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {94734E61-D980-4A5F-AAAA-65105755CE24}.Debug Unicode|Win32.ActiveCfg = Debug|Win32
+ {94734E61-D980-4A5F-AAAA-65105755CE24}.Debug Unicode|Win32.Build.0 = Debug|Win32
+ {94734E61-D980-4A5F-AAAA-65105755CE24}.Release Unicode|Win32.ActiveCfg = Release|Win32
+ {94734E61-D980-4A5F-AAAA-65105755CE24}.Release Unicode|Win32.Build.0 = Release|Win32
+ {E8091321-D79D-4575-86EF-064EA1A4A20D}.Debug Unicode|Win32.ActiveCfg = Debug|Win32
+ {E8091321-D79D-4575-86EF-064EA1A4A20D}.Debug Unicode|Win32.Build.0 = Debug|Win32
+ {E8091321-D79D-4575-86EF-064EA1A4A20D}.Release Unicode|Win32.ActiveCfg = Release|Win32
+ {E8091321-D79D-4575-86EF-064EA1A4A20D}.Release Unicode|Win32.Build.0 = Release|Win32
+ {EE47764E-A202-4F85-A767-ABDAB4AFF35F}.Debug Unicode|Win32.ActiveCfg = Debug|Win32
+ {EE47764E-A202-4F85-A767-ABDAB4AFF35F}.Debug Unicode|Win32.Build.0 = Debug|Win32
+ {EE47764E-A202-4F85-A767-ABDAB4AFF35F}.Release Unicode|Win32.ActiveCfg = Release|Win32
+ {EE47764E-A202-4F85-A767-ABDAB4AFF35F}.Release Unicode|Win32.Build.0 = Release|Win32
+ {71AD2674-065B-48F5-B8B0-E1F9D3892081}.Debug Unicode|Win32.ActiveCfg = Debug|Win32
+ {71AD2674-065B-48F5-B8B0-E1F9D3892081}.Debug Unicode|Win32.Build.0 = Debug|Win32
+ {71AD2674-065B-48F5-B8B0-E1F9D3892081}.Release Unicode|Win32.ActiveCfg = Release|Win32
+ {71AD2674-065B-48F5-B8B0-E1F9D3892081}.Release Unicode|Win32.Build.0 = Release|Win32
+ {EBFFFB4E-261D-44D3-B89C-957B31A0BF9C}.Debug Unicode|Win32.ActiveCfg = Debug|Win32
+ {EBFFFB4E-261D-44D3-B89C-957B31A0BF9C}.Debug Unicode|Win32.Build.0 = Debug|Win32
+ {EBFFFB4E-261D-44D3-B89C-957B31A0BF9C}.Release Unicode|Win32.ActiveCfg = Release|Win32
+ {EBFFFB4E-261D-44D3-B89C-957B31A0BF9C}.Release Unicode|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Plugins/listeningto/players/foo_mlt/foo_mlt.vcproj b/Plugins/listeningto/players/foo_mlt/foo_mlt.vcproj
new file mode 100644
index 0000000..9560309
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foo_mlt.vcproj
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="foo_mlt"
+ ProjectGUID="{94734E61-D980-4A5F-AAAA-65105755CE24}"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/foo_mlt.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;UNICODE;_UNICODE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release/foo_mlt.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1046"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="foobar2000\shared\shared.lib"
+ OutputFile="..\..\..\..\bin\release\Plugins\listeningto\foo_mlt.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ ModuleDefinitionFile=""
+ ProgramDatabaseFile=".\Release/foo_mlt.pdb"
+ ImportLibrary=".\Release/foo_mlt.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release/foo_mlt.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/foo_mlt.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;UNICODE;_UNICODE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ PrecompiledHeaderFile=".\Debug/foo_mlt.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1046"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="foobar2000\shared\shared.lib"
+ OutputFile="C:\Program Files\foobar2000\components\foo_mlt.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ ModuleDefinitionFile=""
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug/foo_mlt.pdb"
+ ImportLibrary=".\Debug/foo_mlt.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Debug/foo_mlt.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="foo_mlt.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/abort_callback.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/abort_callback.cpp
new file mode 100644
index 0000000..affc69f
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/abort_callback.cpp
@@ -0,0 +1,17 @@
+#include "foobar2000.h"
+
+void abort_callback::check() const {
+ if (is_aborting()) throw exception_aborted();
+}
+
+void abort_callback::sleep(double p_timeout_seconds) const {
+ if (!sleep_ex(p_timeout_seconds)) throw exception_aborted();
+}
+
+bool abort_callback::sleep_ex(double p_timeout_seconds) const {
+#ifdef _WIN32
+ return !win32_event::g_wait_for(get_abort_event(),p_timeout_seconds);
+#else
+#error PORTME
+#endif
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/abort_callback.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/abort_callback.h
new file mode 100644
index 0000000..7e65f4e
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/abort_callback.h
@@ -0,0 +1,72 @@
+#ifndef _foobar2000_sdk_abort_callback_h_
+#define _foobar2000_sdk_abort_callback_h_
+
+namespace foobar2000_io {
+
+PFC_DECLARE_EXCEPTION(exception_aborted,pfc::exception,"User abort");
+
+#ifdef _WIN32
+typedef HANDLE abort_callback_event;
+#else
+#error PORTME
+#endif
+
+//! This class is used to signal underlying worker code whether user has decided to abort a potentially time-consuming operation. It is commonly required by all file related operations. Code that receives an abort_callback object should periodically check it and abort any operations being performed if it is signaled, typically giving io_result_aborted return code (see: t_io_result). \n
+//! See abort_callback_impl for implementation.
+class NOVTABLE abort_callback
+{
+public:
+ //! Returns whether user has requested the operation to be aborted.
+ virtual bool is_aborting() const = 0;
+
+ //! Retrieves event object that can be used with some OS calls. The even object becomes signaled when abort is triggered. On win32, this is equivalent to win32 event handle (see: CreateEvent).
+ virtual abort_callback_event get_abort_event() const = 0;
+
+ //! Checks if user has requested the operation to be aborted, and throws exception_aborted if so.
+ void check() const;
+
+ //! For compatibility with old code.
+ inline void check_e() const {check();}
+
+
+ //! Sleeps p_timeout_seconds or less when aborted, throws exception_aborted on abort.
+ void sleep(double p_timeout_seconds) const;
+ //! Sleeps p_timeout_seconds or less when aborted, returns true when execution should continue, false when not.
+ bool sleep_ex(double p_timeout_seconds) const;
+protected:
+ abort_callback() {}
+ ~abort_callback() {}
+};
+
+
+
+//! Implementation of abort_callback interface.
+class abort_callback_impl : public abort_callback {
+public:
+ abort_callback_impl() : m_aborting(false) {
+ m_event.create(true,false);
+ }
+ inline void abort() {set_state(true);}
+ inline void reset() {set_state(false);}
+
+ void set_state(bool p_state) {m_aborting = p_state; m_event.set_state(p_state);}
+
+ bool is_aborting() const {return m_aborting;}
+
+ abort_callback_event get_abort_event() const {return m_event.get();}
+
+private:
+ abort_callback_impl(const abort_callback_impl &) {throw pfc::exception_not_implemented();}
+ const abort_callback_impl & operator=(const abort_callback_impl&) {throw pfc::exception_not_implemented();}
+
+ volatile bool m_aborting;
+#ifdef WIN32
+ win32_event m_event;
+#endif
+};
+
+}
+
+using namespace foobar2000_io;
+
+#endif //_foobar2000_sdk_abort_callback_h_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/advconfig.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/advconfig.h
new file mode 100644
index 0000000..78519b0
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/advconfig.h
@@ -0,0 +1,164 @@
+#ifndef _FOOBAR2000_SDK_ADVCONFIG_H_
+#define _FOOBAR2000_SDK_ADVCONFIG_H_
+
+class advconfig_entry : public service_base {
+public:
+ virtual void get_name(pfc::string_base & p_out) = 0;
+ virtual GUID get_guid() = 0;
+ virtual GUID get_parent() = 0;
+ virtual void reset() = 0;
+ virtual double get_sort_priority() = 0;
+
+ static const GUID guid_root;
+ static const GUID guid_branch_tagging,guid_branch_decoding,guid_branch_tools,guid_branch_playback,guid_branch_display;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(advconfig_entry);
+};
+
+class advconfig_branch : public advconfig_entry {
+public:
+ FB2K_MAKE_SERVICE_INTERFACE(advconfig_branch,advconfig_entry);
+};
+
+class advconfig_entry_checkbox : public advconfig_entry {
+public:
+ virtual bool get_state() = 0;
+ virtual void set_state(bool p_state) = 0;
+ virtual bool is_radio() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(advconfig_entry_checkbox,advconfig_entry);
+};
+
+class advconfig_entry_string : public advconfig_entry {
+public:
+ virtual void get_state(pfc::string_base & p_out) = 0;
+ virtual void set_state(const char * p_string,t_size p_length = infinite) = 0;
+ virtual t_uint32 get_flags() = 0;
+
+ enum {
+ flag_is_integer = 1 << 0,
+ flag_is_signed = 1 << 1,
+ };
+
+ FB2K_MAKE_SERVICE_INTERFACE(advconfig_entry_string,advconfig_entry);
+};
+
+
+class advconfig_branch_impl : public advconfig_branch {
+public:
+ advconfig_branch_impl(const char * p_name,const GUID & p_guid,const GUID & p_parent,double p_priority) : m_name(p_name), m_guid(p_guid), m_parent(p_parent), m_priority(p_priority) {}
+ void get_name(pfc::string_base & p_out) {p_out = m_name;}
+ GUID get_guid() {return m_guid;}
+ GUID get_parent() {return m_parent;}
+ void reset() {}
+ double get_sort_priority() {return m_priority;}
+private:
+ pfc::string8 m_name;
+ GUID m_guid,m_parent;
+ const double m_priority;
+};
+
+template<bool p_is_radio = false>
+class advconfig_entry_checkbox_impl : public advconfig_entry_checkbox {
+public:
+ advconfig_entry_checkbox_impl(const char * p_name,const GUID & p_guid,const GUID & p_parent,double p_priority,bool p_initialstate)
+ : m_name(p_name), m_initialstate(p_initialstate), m_state(p_guid,p_initialstate), m_parent(p_parent), m_priority(p_priority) {}
+
+ void get_name(pfc::string_base & p_out) {p_out = m_name;}
+ GUID get_guid() {return m_state.get_guid();}
+ GUID get_parent() {return m_parent;}
+ void reset() {m_state = m_initialstate;}
+ bool get_state() {return m_state;}
+ void set_state(bool p_state) {m_state = p_state;}
+ bool is_radio() {return p_is_radio;}
+ double get_sort_priority() {return m_priority;}
+private:
+ pfc::string8 m_name;
+ const bool m_initialstate;
+ cfg_bool m_state;
+ GUID m_parent;
+ const double m_priority;
+};
+
+class advconfig_branch_factory : public service_factory_single_t<advconfig_branch_impl> {
+public:
+ advconfig_branch_factory(const char * p_name,const GUID & p_guid,const GUID & p_parent,double p_priority)
+ : service_factory_single_t<advconfig_branch_impl>(p_name,p_guid,p_parent,p_priority) {}
+};
+
+template<bool p_is_radio>
+class advconfig_checkbox_factory_t : public service_factory_single_t<advconfig_entry_checkbox_impl<p_is_radio> > {
+public:
+ advconfig_checkbox_factory_t(const char * p_name,const GUID & p_guid,const GUID & p_parent,double p_priority,bool p_initialstate)
+ : service_factory_single_t<advconfig_entry_checkbox_impl<p_is_radio> >(p_name,p_guid,p_parent,p_priority,p_initialstate) {}
+};
+
+typedef advconfig_checkbox_factory_t<false> advconfig_checkbox_factory;
+typedef advconfig_checkbox_factory_t<true> advconfig_radio_factory;
+
+class advconfig_entry_string_impl : public advconfig_entry_string {
+public:
+ advconfig_entry_string_impl(const char * p_name,const GUID & p_guid,const GUID & p_parent,double p_priority,const char * p_initialstate)
+ : m_name(p_name), m_parent(p_parent), m_priority(p_priority), m_initialstate(p_initialstate), m_state(p_guid,p_initialstate) {}
+ void get_name(pfc::string_base & p_out) {p_out = m_name;}//{p_out = pfc::string_formatter() << m_name << " : " << m_state;}
+ GUID get_guid() {return m_state.get_guid();}
+ GUID get_parent() {return m_parent;}
+ void reset() {core_api::ensure_main_thread();m_state = m_initialstate;}
+ double get_sort_priority() {return m_priority;}
+ void get_state(pfc::string_base & p_out) {core_api::ensure_main_thread();p_out = m_state;}
+ void set_state(const char * p_string,t_size p_length = infinite) {core_api::ensure_main_thread();m_state.set_string(p_string,p_length);}
+ t_uint32 get_flags() {return 0;}
+private:
+ const pfc::string8 m_initialstate, m_name;
+ cfg_string m_state;
+ const double m_priority;
+ const GUID m_parent;
+};
+
+class advconfig_string_factory : public service_factory_single_t<advconfig_entry_string_impl> {
+public:
+ advconfig_string_factory(const char * p_name,const GUID & p_guid,const GUID & p_parent,double p_priority,const char * p_initialstate)
+ : service_factory_single_t<advconfig_entry_string_impl>(p_name,p_guid,p_parent,p_priority,p_initialstate) {}
+};
+
+
+class advconfig_entry_integer_impl : public advconfig_entry_string {
+public:
+ advconfig_entry_integer_impl(const char * p_name,const GUID & p_guid,const GUID & p_parent,double p_priority,t_uint64 p_initialstate,t_uint64 p_min,t_uint64 p_max)
+ : m_name(p_name), m_parent(p_parent), m_priority(p_priority), m_initval(p_initialstate), m_min(p_min), m_max(p_max), m_state(p_guid,p_initialstate) {}
+ void get_name(pfc::string_base & p_out) {p_out = m_name;}
+ GUID get_guid() {return m_state.get_guid();}
+ GUID get_parent() {return m_parent;}
+ void reset() {m_state = m_initval;}
+ double get_sort_priority() {return m_priority;}
+ void get_state(pfc::string_base & p_out) {p_out = pfc::format_uint(m_state.get_value());}
+ void set_state(const char * p_string,t_size p_length) {m_state = pfc::clip_t<t_uint64>(pfc::atoui64_ex(p_string,p_length),m_min,m_max);}
+ t_uint32 get_flags() {return advconfig_entry_string::flag_is_integer;}
+
+ t_uint64 get_state_int() const {return m_state;}
+private:
+ cfg_int_t<t_uint64> m_state;
+ const double m_priority;
+ const t_uint64 m_initval, m_min, m_max;
+ const GUID m_parent;
+ const pfc::string8 m_name;
+};
+
+class advconfig_integer_factory : public service_factory_single_t<advconfig_entry_integer_impl> {
+public:
+ advconfig_integer_factory(const char * p_name,const GUID & p_guid,const GUID & p_parent,double p_priority,t_uint64 p_initialstate,t_uint64 p_min,t_uint64 p_max)
+ : service_factory_single_t<advconfig_entry_integer_impl>(p_name,p_guid,p_parent,p_priority,p_initialstate,p_min,p_max) {}
+};
+
+
+class advconfig_entry_enum : public advconfig_entry {
+public:
+ virtual t_size get_value_count() = 0;
+ virtual void enum_value(pfc::string_base & p_out,t_size p_index) = 0;
+ virtual t_size get_state() = 0;
+ virtual void set_state(t_size p_value) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(advconfig_entry_enum,advconfig_entry);
+};
+
+#endif //_FOOBAR2000_SDK_ADVCONFIG_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/app_close_blocker.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/app_close_blocker.cpp
new file mode 100644
index 0000000..6611e0b
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/app_close_blocker.cpp
@@ -0,0 +1,12 @@
+#include "foobar2000.h"
+
+bool app_close_blocker::g_query()
+{
+ service_ptr_t<app_close_blocker> ptr;
+ service_enum_t<app_close_blocker> e;
+ while(e.next(ptr))
+ {
+ if (!ptr->query()) return false;
+ }
+ return true;
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/app_close_blocker.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/app_close_blocker.h
new file mode 100644
index 0000000..2669ea5
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/app_close_blocker.h
@@ -0,0 +1,18 @@
+#ifndef _APP_CLOSE_BLOCKER_H_
+#define _APP_CLOSE_BLOCKER_H_
+
+
+//! This service is used to signal whether something is currently preventing main window from being closed and app from being shut down.
+class NOVTABLE app_close_blocker : public service_base
+{
+public:
+ //! Checks whether this service is currently preventing main window from being closed and app from being shut down.
+ virtual bool query() = 0;
+
+ //! Static helper function, checks whether any of registered app_close_blocker services is currently preventing main window from being closed and app from being shut down.
+ static bool g_query();
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(app_close_blocker);
+};
+
+#endif //_APP_CLOSE_BLOCKER_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_chunk.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_chunk.cpp
new file mode 100644
index 0000000..43e887b
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_chunk.cpp
@@ -0,0 +1,290 @@
+#include "foobar2000.h"
+
+void audio_chunk::set_data(const audio_sample * src,t_size samples,unsigned nch,unsigned srate,unsigned channel_config)
+{
+ t_size size = samples * nch;
+ set_data_size(size);
+ if (src)
+ pfc::memcpy_t(get_data(),src,size);
+ else
+ pfc::memset_t(get_data(),(audio_sample)0,size);
+ set_sample_count(samples);
+ set_channels(nch,channel_config);
+ set_srate(srate);
+}
+
+static bool check_exclusive(unsigned val, unsigned mask)
+{
+ return (val&mask)!=0 && (val&mask)!=mask;
+}
+
+namespace {
+
+ template<class T,bool b_swap,bool b_signed,bool b_pad> class msvc6_sucks_v2 { public:
+ inline static void do_fixedpoint_convert(const void * source,unsigned bps,t_size count,audio_sample* buffer)
+ {
+ const char * src = (const char *) source;
+ unsigned bytes = bps>>3;
+ t_size n;
+ T max = ((T)1)<<(bps-1);
+
+ T negmask = - max;
+
+ ASSUME(bytes<=sizeof(T));
+
+ const double div = 1.0 / (double)(1<<(bps-1));
+ for(n=0;n<count;n++) {
+ T temp;
+ if (b_pad)
+ {
+ temp = 0;
+ memcpy(&temp,src,bytes);
+ if (b_swap) pfc::byteswap_raw(&temp,bytes);
+ }
+ else
+ {
+ temp = * reinterpret_cast<const T*>(src);
+ if (b_swap) temp = pfc::byteswap_t(temp);
+ }
+
+
+
+ if (!b_signed) temp ^= max;
+
+ if (b_pad)
+ {
+ if (temp & max) temp |= negmask;
+ }
+
+ if (b_pad)
+ src += bytes;
+ else
+ src += sizeof(T);
+
+
+ buffer[n] = (audio_sample) ( (double)temp * div );
+ }
+ }
+ };
+
+ template <class T,bool b_pad> class msvc6_sucks { public:
+ inline static void do_fixedpoint_convert(bool b_swap,bool b_signed,const void * source,unsigned bps,t_size count,audio_sample* buffer)
+ {
+ if (sizeof(T)==1)
+ {
+ if (b_signed)
+ {
+ msvc6_sucks_v2<T,false,true,b_pad>::do_fixedpoint_convert(source,bps,count,buffer);
+ }
+ else
+ {
+ msvc6_sucks_v2<T,false,false,b_pad>::do_fixedpoint_convert(source,bps,count,buffer);
+ }
+ }
+ else if (b_swap)
+ {
+ if (b_signed)
+ {
+ msvc6_sucks_v2<T,true,true,b_pad>::do_fixedpoint_convert(source,bps,count,buffer);
+ }
+ else
+ {
+ msvc6_sucks_v2<T,true,false,b_pad>::do_fixedpoint_convert(source,bps,count,buffer);
+ }
+ }
+ else
+ {
+ if (b_signed)
+ {
+ msvc6_sucks_v2<T,false,true,b_pad>::do_fixedpoint_convert(source,bps,count,buffer);
+ }
+ else
+ {
+ msvc6_sucks_v2<T,false,false,b_pad>::do_fixedpoint_convert(source,bps,count,buffer);
+ }
+ }
+ }
+ };
+
+
+};
+
+
+void audio_chunk::set_data_fixedpoint_ex(const void * source,t_size size,unsigned srate,unsigned nch,unsigned bps,unsigned flags,unsigned p_channel_config)
+{
+ assert( check_exclusive(flags,FLAG_SIGNED|FLAG_UNSIGNED) );
+ assert( check_exclusive(flags,FLAG_LITTLE_ENDIAN|FLAG_BIG_ENDIAN) );
+
+ bool need_swap = !!(flags & FLAG_BIG_ENDIAN);
+ if (pfc::byte_order_is_big_endian) need_swap = !need_swap;
+
+ t_size count = size / (bps/8);
+ set_data_size(count);
+ audio_sample * buffer = get_data();
+ bool b_signed = !!(flags & FLAG_SIGNED);
+
+ switch(bps)
+ {
+ case 8:
+ msvc6_sucks<t_int8,false>::do_fixedpoint_convert(need_swap,b_signed,source,bps,count,buffer);
+ break;
+ case 16:
+ if (!need_swap && b_signed) audio_math::convert_from_int16((const t_int16*)source,count,buffer,1.0);
+ else msvc6_sucks<t_int16,false>::do_fixedpoint_convert(need_swap,b_signed,source,bps,count,buffer);
+ break;
+ case 24:
+ msvc6_sucks<t_int32,true>::do_fixedpoint_convert(need_swap,b_signed,source,bps,count,buffer);
+ break;
+ case 32:
+ if (!need_swap && b_signed) audio_math::convert_from_int32((const t_int32*)source,count,buffer,1.0);
+ else msvc6_sucks<t_int32,false>::do_fixedpoint_convert(need_swap,b_signed,source,bps,count,buffer);
+ break;
+ default:
+ //unknown size, cant convert
+ pfc::memset_t(buffer,(audio_sample)0,count);
+ break;
+ }
+ set_sample_count(count/nch);
+ set_srate(srate);
+ set_channels(nch,p_channel_config);
+}
+
+template<class t_float>
+static void process_float_multi(audio_sample * p_out,const t_float * p_in,const t_size p_count)
+{
+ t_size n;
+ for(n=0;n<p_count;n++)
+ p_out[n] = (audio_sample)p_in[n];
+}
+
+template<class t_float>
+static void process_float_multi_swap(audio_sample * p_out,const t_float * p_in,const t_size p_count)
+{
+ t_size n;
+ for(n=0;n<p_count;n++) {
+ p_out[n] = (audio_sample) pfc::byteswap_t(p_in[n]);
+ }
+}
+
+void audio_chunk::set_data_floatingpoint_ex(const void * ptr,t_size size,unsigned srate,unsigned nch,unsigned bps,unsigned flags,unsigned p_channel_config)
+{
+ assert(bps==32 || bps==64);
+ assert( check_exclusive(flags,FLAG_LITTLE_ENDIAN|FLAG_BIG_ENDIAN) );
+ assert( ! (flags & (FLAG_SIGNED|FLAG_UNSIGNED) ) );
+
+ bool use_swap = pfc::byte_order_is_big_endian ? !!(flags & FLAG_LITTLE_ENDIAN) : !!(flags & FLAG_BIG_ENDIAN);
+
+ const t_size count = size / (bps/8);
+ set_data_size(count);
+ audio_sample * out = get_data();
+
+ if (bps == 32)
+ {
+ if (use_swap)
+ process_float_multi_swap(out,reinterpret_cast<const float*>(ptr),count);
+ else
+ process_float_multi(out,reinterpret_cast<const float*>(ptr),count);
+ }
+ else if (bps == 64)
+ {
+ if (use_swap)
+ process_float_multi_swap(out,reinterpret_cast<const double*>(ptr),count);
+ else
+ process_float_multi(out,reinterpret_cast<const double*>(ptr),count);
+ }
+ else throw exception_io_data("invalid bit depth");
+
+ set_sample_count(count/nch);
+ set_srate(srate);
+ set_channels(nch,p_channel_config);
+}
+
+bool audio_chunk::is_valid() const
+{
+ unsigned nch = get_channels();
+ if (nch==0 || nch>256) return false;
+ unsigned srate = get_srate();
+ if (srate<1000 || srate>1000000) return false;
+ t_size samples = get_sample_count();
+ if (samples==0 || samples >= 0x80000000 / (sizeof(audio_sample) * nch) ) return false;
+ t_size size = get_data_size();
+ if (samples * nch > size) return false;
+ if (!get_data()) return false;
+ return true;
+}
+
+
+void audio_chunk::pad_with_silence_ex(t_size samples,unsigned hint_nch,unsigned hint_srate) {
+ if (is_empty())
+ {
+ if (hint_srate && hint_nch) {
+ return set_data(0,samples,hint_nch,hint_srate);
+ } else throw exception_io_data();
+ }
+ else
+ {
+ if (hint_srate && hint_srate != get_srate()) samples = MulDiv_Size(samples,get_srate(),hint_srate);
+ if (samples > get_sample_count())
+ {
+ t_size old_size = get_sample_count() * get_channels();
+ t_size new_size = samples * get_channels();
+ set_data_size(new_size);
+ pfc::memset_t(get_data() + old_size,(audio_sample)0,new_size - old_size);
+ set_sample_count(samples);
+ }
+ }
+}
+
+void audio_chunk::pad_with_silence(t_size samples) {
+ if (samples > get_sample_count())
+ {
+ t_size old_size = get_sample_count() * get_channels();
+ t_size new_size = samples * get_channels();
+ set_data_size(new_size);
+ pfc::memset_t(get_data() + old_size,(audio_sample)0,new_size - old_size);
+ set_sample_count(samples);
+ }
+}
+
+void audio_chunk::insert_silence_fromstart(t_size samples) {
+ t_size old_size = get_sample_count() * get_channels();
+ t_size delta = samples * get_channels();
+ t_size new_size = old_size + delta;
+ set_data_size(new_size);
+ audio_sample * ptr = get_data();
+ pfc::memmove_t(ptr+delta,ptr,old_size);
+ pfc::memset_t(ptr,(audio_sample)0,delta);
+ set_sample_count(get_sample_count() + samples);
+}
+
+t_size audio_chunk::skip_first_samples(t_size samples_delta)
+{
+ t_size samples_old = get_sample_count();
+ if (samples_delta >= samples_old)
+ {
+ set_sample_count(0);
+ set_data_size(0);
+ return samples_old;
+ }
+ else
+ {
+ t_size samples_new = samples_old - samples_delta;
+ unsigned nch = get_channels();
+ audio_sample * ptr = get_data();
+ pfc::memmove_t(ptr,ptr+nch*samples_delta,nch*samples_new);
+ set_sample_count(samples_new);
+ set_data_size(nch*samples_new);
+ return samples_delta;
+ }
+}
+
+audio_sample audio_chunk::get_peak(audio_sample peak) const
+{
+ return pfc::max_t<audio_sample>(peak,audio_math::calculate_peak(get_data(),get_sample_count() * get_channels() ));
+}
+
+void audio_chunk::scale(audio_sample p_value)
+{
+ audio_sample * ptr = get_data();
+ audio_math::scale(ptr,get_sample_count() * get_channels(),ptr,p_value);
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_chunk.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_chunk.h
new file mode 100644
index 0000000..60803a2
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_chunk.h
@@ -0,0 +1,254 @@
+#ifndef _AUDIO_CHUNK_H_
+#define _AUDIO_CHUNK_H_
+
+//! Interface to container of a chunk of audio data. See audio_chunk_impl for an implementation.
+class NOVTABLE audio_chunk {
+public:
+
+ //! Channel map flag declarations. Note that order of interleaved channel data in the stream is same as order of these flags.
+ enum
+ {
+ channel_front_left = 1<<0,
+ channel_front_right = 1<<1,
+ channel_front_center = 1<<2,
+ channel_lfe = 1<<3,
+ channel_back_left = 1<<4,
+ channel_back_right = 1<<5,
+ channel_front_center_left = 1<<6,
+ channel_front_center_right = 1<<7,
+ channel_back_center = 1<<8,
+ channel_side_left = 1<<9,
+ channel_side_right = 1<<10,
+ channel_top_center = 1<<11,
+ channel_top_front_left = 1<<12,
+ channel_top_front_center = 1<<13,
+ channel_top_front_right = 1<<14,
+ channel_top_back_left = 1<<15,
+ channel_top_back_center = 1<<16,
+ channel_top_back_right = 1<<17,
+
+ channel_config_mono = channel_front_center,
+ channel_config_stereo = channel_front_left | channel_front_right,
+ channel_config_5point1 = channel_front_left | channel_front_right | channel_back_left | channel_back_right | channel_front_center | channel_lfe,
+
+ defined_channel_count = 18,
+ };
+
+ //! Helper function; guesses default channel map for specified channel count.
+ static unsigned g_guess_channel_config(unsigned count);
+
+#ifdef _WIN32
+ //! Helper function; translates audio_chunk channel map to WAVEFORMATEXTENSIBLE channel map.
+ static DWORD g_channel_config_to_wfx(unsigned p_config);
+ //! Helper function; translates WAVEFORMATEXTENSIBLE channel map to audio_chunk channel map.
+ static unsigned g_channel_config_from_wfx(DWORD p_wfx);
+#endif
+
+ //! Extracts flag describing Nth channel from specified map. Usable to figure what specific channel in a stream means.
+ static unsigned g_extract_channel_flag(unsigned p_config,unsigned p_index);
+ //! Counts channels specified by channel map.
+ static unsigned g_count_channels(unsigned p_config);
+ //! Calculates index of a channel specified by p_flag in a stream where channel map is described by p_config.
+ static unsigned g_channel_index_from_flag(unsigned p_config,unsigned p_flag);
+
+
+
+ //! Retrieves audio data buffer pointer (non-const version). Returned pointer is for temporary use only; it is valid until next set_data_size call, or until the object is destroyed. \n
+ //! Size of returned buffer is equal to get_data_size() return value (in audio_samples). Amount of actual data may be smaller, depending on sample count and channel count. Conditions where sample count * channel count are greater than data size should not be possible.
+ virtual audio_sample * get_data() = 0;
+ //! Retrieves audio data buffer pointer (const version). Returned pointer is for temporary use only; it is valid until next set_data_size call, or until the object is destroyed. \n
+ //! Size of returned buffer is equal to get_data_size() return value (in audio_samples). Amount of actual data may be smaller, depending on sample count and channel count. Conditions where sample count * channel count are greater than data size should not be possible.
+ virtual const audio_sample * get_data() const = 0;
+ //! Retrieves size of allocated buffer space, in audio_samples.
+ virtual t_size get_data_size() const = 0;
+ //! Resizes audio data buffer to specified size. Throws std::bad_alloc on failure.
+ virtual void set_data_size(t_size p_new_size) = 0;
+
+ //! Retrieves sample rate of contained audio data.
+ virtual unsigned get_srate() const = 0;
+ //! Sets sample rate of contained audio data.
+ virtual void set_srate(unsigned val) = 0;
+ //! Retrieves channel count of contained audio data.
+ virtual unsigned get_channels() const = 0;
+ //! Retrieves channel map of contained audio data. Conditions where number of channels specified by channel map don't match get_channels() return value should not be possible.
+ virtual unsigned get_channel_config() const = 0;
+ //! Sets channel count / channel map.
+ virtual void set_channels(unsigned p_count,unsigned p_config) = 0;
+
+ //! Retrieves number of valid samples in the buffer. \n
+ //! Note that a "sample" means a unit of interleaved PCM data representing states of each channel at given point of time, not a single PCM value. \n
+ //! For an example, duration of contained audio data is equal to sample count / sample rate, while actual size of contained data is equal to sample count * channel count.
+ virtual t_size get_sample_count() const = 0;
+
+ //! Sets number of valid samples in the buffer. WARNING: sample count * channel count should never be above allocated buffer size.
+ virtual void set_sample_count(t_size val) = 0;
+
+ //! Helper, same as get_srate().
+ inline unsigned get_sample_rate() const {return get_srate();}
+ //! Helper, same as set_srate().
+ inline void set_sample_rate(unsigned val) {set_srate(val);}
+
+ //! Helper; sets channel count to specified value and uses default channel map for this channel count.
+ void set_channels(unsigned val) {set_channels(val,g_guess_channel_config(val));}
+
+
+ //! Helper; resizes audio data buffer when it's current size is smaller than requested.
+ inline void grow_data_size(t_size p_requested) {if (p_requested > get_data_size()) set_data_size(p_requested);}
+
+
+ //! Retrieves duration of contained audio data, in seconds.
+ inline double get_duration() const
+ {
+ double rv = 0;
+ t_size srate = get_srate (), samples = get_sample_count();
+ if (srate>0 && samples>0) rv = (double)samples/(double)srate;
+ return rv;
+ }
+
+ //! Returns whether the chunk is empty (contains no audio data).
+ inline bool is_empty() const {return get_channels()==0 || get_srate()==0 || get_sample_count()==0;}
+
+ //! Returns whether the chunk contents are valid (for bug check purposes).
+ bool is_valid() const;
+
+ //! Returns actual amount of audio data contained in the buffer (sample count * channel count). Must not be greater than data size (see get_data_size()).
+ inline t_size get_data_length() const {return get_sample_count() * get_channels();}
+
+ //! Resets all audio_chunk data.
+ inline void reset() {
+ set_sample_count(0);
+ set_srate(0);
+ set_channels(0);
+ set_data_size(0);
+ }
+
+ //! Helper, sets chunk data to contents of specified buffer, with specified number of channels / sample rate / channel map.
+ void set_data(const audio_sample * src,t_size samples,unsigned nch,unsigned srate,unsigned channel_config);
+
+ //! Helper, sets chunk data to contents of specified buffer, with specified number of channels / sample rate, using default channel map for specified channel count.
+ inline void set_data(const audio_sample * src,t_size samples,unsigned nch,unsigned srate) {set_data(src,samples,nch,srate,g_guess_channel_config(nch));}
+
+ //! Helper, sets chunk data to contents of specified buffer, using default win32/wav conventions for signed/unsigned switch.
+ inline void set_data_fixedpoint(const void * ptr,t_size bytes,unsigned srate,unsigned nch,unsigned bps,unsigned channel_config) {
+ set_data_fixedpoint_ex(ptr,bytes,srate,nch,bps,(bps==8 ? FLAG_UNSIGNED : FLAG_SIGNED) | flags_autoendian(), channel_config);
+ }
+
+ inline void set_data_fixedpoint_unsigned(const void * ptr,t_size bytes,unsigned srate,unsigned nch,unsigned bps,unsigned channel_config) {
+ return set_data_fixedpoint_ex(ptr,bytes,srate,nch,bps,FLAG_UNSIGNED | flags_autoendian(), channel_config);
+ }
+
+ inline void set_data_fixedpoint_signed(const void * ptr,t_size bytes,unsigned srate,unsigned nch,unsigned bps,unsigned channel_config) {
+ return set_data_fixedpoint_ex(ptr,bytes,srate,nch,bps,FLAG_SIGNED | flags_autoendian(), channel_config);
+ }
+
+ enum
+ {
+ FLAG_LITTLE_ENDIAN = 1,
+ FLAG_BIG_ENDIAN = 2,
+ FLAG_SIGNED = 4,
+ FLAG_UNSIGNED = 8,
+ };
+
+ inline static unsigned flags_autoendian() {
+ return pfc::byte_order_is_big_endian ? FLAG_BIG_ENDIAN : FLAG_LITTLE_ENDIAN;
+ }
+
+ void set_data_fixedpoint_ex(const void * ptr,t_size bytes,unsigned p_sample_rate,unsigned p_channels,unsigned p_bits_per_sample,unsigned p_flags,unsigned p_channel_config);//p_flags - see FLAG_* above
+
+ void set_data_floatingpoint_ex(const void * ptr,t_size bytes,unsigned p_sample_rate,unsigned p_channels,unsigned p_bits_per_sample,unsigned p_flags,unsigned p_channel_config);//signed/unsigned flags dont apply
+
+ inline void set_data_32(const float * src,t_size samples,unsigned nch,unsigned srate) {return set_data(src,samples,nch,srate);}
+
+ void pad_with_silence_ex(t_size samples,unsigned hint_nch,unsigned hint_srate);
+ void pad_with_silence(t_size samples);
+ void insert_silence_fromstart(t_size samples);
+ t_size skip_first_samples(t_size samples);
+
+
+ //! Helper, calculates peak value of data in the chunk. The optional parameter specifies initial peak value, to simplify calling code.
+ audio_sample get_peak(audio_sample p_peak = 0) const;
+
+ //! Helper function; scales entire chunk content by specified value.
+ void scale(audio_sample p_value);
+
+ //! Helper; copies content of another audio chunk to this chunk.
+ void copy(const audio_chunk & p_source) {
+ set_data(p_source.get_data(),p_source.get_sample_count(),p_source.get_channels(),p_source.get_srate(),p_source.get_channel_config());
+ }
+
+ const audio_chunk & operator=(const audio_chunk & p_source) {
+ copy(p_source);
+ return *this;
+ }
+protected:
+ audio_chunk() {}
+ ~audio_chunk() {}
+};
+
+//! Implementation of audio_chunk. Takes pfc allocator template as template parameter.
+template<template<typename> class t_alloc = pfc::alloc_standard>
+class audio_chunk_impl_t : public audio_chunk {
+ typedef audio_chunk_impl_t<t_alloc> t_self;
+ pfc::array_t<audio_sample,t_alloc> m_data;
+ unsigned m_srate,m_nch,m_setup;
+ t_size m_samples;
+public:
+ audio_chunk_impl_t() : m_srate(0), m_nch(0), m_samples(0), m_setup(0) {}
+ audio_chunk_impl_t(const audio_sample * src,unsigned samples,unsigned nch,unsigned srate) : m_srate(0), m_nch(0), m_samples(0)
+ {set_data(src,samples,nch,srate);}
+ audio_chunk_impl_t(const audio_chunk & p_source) : m_srate(0), m_nch(0), m_samples(0), m_setup(0) {copy(p_source);}
+ audio_chunk_impl_t(const t_self & p_source) : m_srate(0), m_nch(0), m_samples(0), m_setup(0) {copy(p_source);}
+
+ virtual audio_sample * get_data() {return m_data.get_ptr();}
+ virtual const audio_sample * get_data() const {return m_data.get_ptr();}
+ virtual t_size get_data_size() const {return m_data.get_size();}
+ virtual void set_data_size(t_size new_size) {m_data.set_size(new_size);}
+
+ virtual unsigned get_srate() const {return m_srate;}
+ virtual void set_srate(unsigned val) {m_srate=val;}
+ virtual unsigned get_channels() const {return m_nch;}
+ virtual unsigned get_channel_config() const {return m_setup;}
+ virtual void set_channels(unsigned val,unsigned setup) {m_nch = val;m_setup = setup;}
+ void set_channels(unsigned val) {set_channels(val,g_guess_channel_config(val));}
+
+ virtual t_size get_sample_count() const {return m_samples;}
+ virtual void set_sample_count(t_size val) {m_samples = val;}
+
+ const t_self & operator=(const audio_chunk & p_source) {copy(p_source);return *this;}
+ const t_self & operator=(const t_self & p_source) {copy(p_source);return *this;}
+};
+
+typedef audio_chunk_impl_t<> audio_chunk_impl;
+typedef audio_chunk_impl audio_chunk_i;//for compatibility
+
+//! Implements const methods of audio_chunk only, referring to an external buffer. For temporary use only (does not maintain own storage), e.g.: somefunc( audio_chunk_temp_impl(mybuffer,....) );
+class audio_chunk_temp_impl : public audio_chunk {
+public:
+ audio_chunk_temp_impl(const audio_sample * p_data,t_size p_samples,t_uint32 p_sample_rate,t_uint32 p_channels,t_uint32 p_channel_config) :
+ m_data(p_data), m_samples(p_samples), m_sample_rate(p_sample_rate), m_channels(p_channels), m_channel_config(p_channel_config)
+ {
+ PFC_ASSERT(is_valid());
+ }
+
+ audio_sample * get_data() {throw pfc::exception_not_implemented();}
+ const audio_sample * get_data() const {return m_data;}
+ t_size get_data_size() const {return m_samples * m_channels;}
+ void set_data_size(t_size p_new_size) {throw pfc::exception_not_implemented();}
+
+ unsigned get_srate() const {return m_sample_rate;}
+ void set_srate(unsigned val) {throw pfc::exception_not_implemented();}
+ unsigned get_channels() const {return m_channels;}
+ unsigned get_channel_config() const {return m_channel_config;}
+ void set_channels(unsigned p_count,unsigned p_config) {throw pfc::exception_not_implemented();}
+
+ t_size get_sample_count() const {return m_samples;}
+
+ void set_sample_count(t_size val) {throw pfc::exception_not_implemented();}
+
+private:
+ t_size m_samples;
+ t_uint32 m_sample_rate,m_channels,m_channel_config;
+ const audio_sample * m_data;
+};
+
+#endif //_AUDIO_CHUNK_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_chunk_channel_config.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_chunk_channel_config.cpp
new file mode 100644
index 0000000..16caed4
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_chunk_channel_config.cpp
@@ -0,0 +1,131 @@
+#include "foobar2000.h"
+
+#ifdef _WIN32
+#include <ks.h>
+#include <ksmedia.h>
+
+#if 0
+#define SPEAKER_FRONT_LEFT 0x1
+#define SPEAKER_FRONT_RIGHT 0x2
+#define SPEAKER_FRONT_CENTER 0x4
+#define SPEAKER_LOW_FREQUENCY 0x8
+#define SPEAKER_BACK_LEFT 0x10
+#define SPEAKER_BACK_RIGHT 0x20
+#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
+#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
+#define SPEAKER_BACK_CENTER 0x100
+#define SPEAKER_SIDE_LEFT 0x200
+#define SPEAKER_SIDE_RIGHT 0x400
+#define SPEAKER_TOP_CENTER 0x800
+#define SPEAKER_TOP_FRONT_LEFT 0x1000
+#define SPEAKER_TOP_FRONT_CENTER 0x2000
+#define SPEAKER_TOP_FRONT_RIGHT 0x4000
+#define SPEAKER_TOP_BACK_LEFT 0x8000
+#define SPEAKER_TOP_BACK_CENTER 0x10000
+#define SPEAKER_TOP_BACK_RIGHT 0x20000
+#endif
+
+static struct {DWORD m_wfx; unsigned m_native; } const g_translation_table[] =
+{
+ {SPEAKER_FRONT_LEFT, audio_chunk::channel_front_left},
+ {SPEAKER_FRONT_RIGHT, audio_chunk::channel_front_right},
+ {SPEAKER_FRONT_CENTER, audio_chunk::channel_front_center},
+ {SPEAKER_LOW_FREQUENCY, audio_chunk::channel_lfe},
+ {SPEAKER_BACK_LEFT, audio_chunk::channel_back_left},
+ {SPEAKER_BACK_RIGHT, audio_chunk::channel_back_right},
+ {SPEAKER_FRONT_LEFT_OF_CENTER, audio_chunk::channel_front_center_left},
+ {SPEAKER_FRONT_RIGHT_OF_CENTER, audio_chunk::channel_front_center_right},
+ {SPEAKER_BACK_CENTER, audio_chunk::channel_back_center},
+ {SPEAKER_SIDE_LEFT, audio_chunk::channel_side_left},
+ {SPEAKER_SIDE_RIGHT, audio_chunk::channel_side_right},
+ {SPEAKER_TOP_CENTER, audio_chunk::channel_top_center},
+ {SPEAKER_TOP_FRONT_LEFT, audio_chunk::channel_top_front_left},
+ {SPEAKER_TOP_FRONT_CENTER, audio_chunk::channel_top_front_center},
+ {SPEAKER_TOP_FRONT_RIGHT, audio_chunk::channel_top_front_right},
+ {SPEAKER_TOP_BACK_LEFT, audio_chunk::channel_top_back_left},
+ {SPEAKER_TOP_BACK_CENTER, audio_chunk::channel_top_back_center},
+ {SPEAKER_TOP_BACK_RIGHT, audio_chunk::channel_top_back_right},
+};
+
+
+DWORD audio_chunk::g_channel_config_to_wfx(unsigned p_config)
+{
+ DWORD ret = 0;
+ unsigned n;
+ for(n=0;n<tabsize(g_translation_table);n++)
+ {
+ if (p_config & g_translation_table[n].m_native) ret |= g_translation_table[n].m_wfx;
+ }
+ return ret;
+}
+
+unsigned audio_chunk::g_channel_config_from_wfx(DWORD p_wfx)
+{
+ unsigned ret = 0;
+ unsigned n;
+ for(n=0;n<tabsize(g_translation_table);n++)
+ {
+ if (p_wfx & g_translation_table[n].m_wfx) ret |= g_translation_table[n].m_native;
+ }
+ return ret;
+}
+
+#endif
+
+
+static unsigned g_audio_channel_config_table[] =
+{
+ 0,
+ audio_chunk::channel_config_mono,
+ audio_chunk::channel_config_stereo,
+ audio_chunk::channel_front_left | audio_chunk::channel_front_right | audio_chunk::channel_lfe,
+ audio_chunk::channel_front_left | audio_chunk::channel_front_right | audio_chunk::channel_back_left | audio_chunk::channel_back_right,
+ audio_chunk::channel_front_left | audio_chunk::channel_front_right | audio_chunk::channel_back_left | audio_chunk::channel_back_right | audio_chunk::channel_lfe,
+ audio_chunk::channel_config_5point1,
+ audio_chunk::channel_front_left | audio_chunk::channel_front_right | audio_chunk::channel_back_left | audio_chunk::channel_back_right | audio_chunk::channel_lfe | audio_chunk::channel_front_center_right | audio_chunk::channel_front_center_left,
+ audio_chunk::channel_front_left | audio_chunk::channel_front_right | audio_chunk::channel_back_left | audio_chunk::channel_back_right | audio_chunk::channel_front_center | audio_chunk::channel_lfe | audio_chunk::channel_front_center_right | audio_chunk::channel_front_center_left,
+};
+
+
+unsigned audio_chunk::g_guess_channel_config(unsigned count)
+{
+ if (count >= tabsize(g_audio_channel_config_table)) return 0;
+ return g_audio_channel_config_table[count];
+}
+
+
+unsigned audio_chunk::g_channel_index_from_flag(unsigned p_config,unsigned p_flag) {
+ unsigned index = 0;
+ for(unsigned walk = 0; walk < 32; walk++) {
+ unsigned query = 1 << walk;
+ if (p_flag & query) return index;
+ if (p_config & query) index++;
+ }
+ return infinite;
+}
+
+unsigned audio_chunk::g_extract_channel_flag(unsigned p_config,unsigned p_index)
+{
+ unsigned toskip = p_index;
+ unsigned flag = 1;
+ while(flag)
+ {
+ if (p_config & flag)
+ {
+ if (toskip == 0) break;
+ toskip--;
+ }
+ flag <<= 1;
+ }
+ return flag;
+}
+
+unsigned audio_chunk::g_count_channels(unsigned p_config)
+{
+ unsigned ret = 0;
+ while(p_config) {
+ ret += (p_config & 1);
+ p_config >>= 1;
+ }
+ return ret;
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_postprocessor.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_postprocessor.h
new file mode 100644
index 0000000..10cde01
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/audio_postprocessor.h
@@ -0,0 +1,30 @@
+#ifndef _CVT_FLOAT_TO_LINEAR_H_
+#define _CVT_FLOAT_TO_LINEAR_H_
+
+//! This class handles conversion of audio data (audio_chunk) to various linear PCM types, with optional dithering.
+
+class NOVTABLE audio_postprocessor : public service_base
+{
+public:
+ //! Processes one chunk of audio data.
+ //! @param p_chunk Chunk of audio data to process.
+ //! @param p_output Receives output linear signed PCM data.
+ //! @param p_out_bps Desired bit depth of output.
+ //! @param p_out_bps_physical Desired physical word width of output. Must be either 8, 16, 24 or 32, greater or equal to p_out_bps. This is typically set to same value as p_out_bps.
+ //! @param p_dither Indicates whether dithering should be used. Note that dithering is CPU-heavy.
+ //! @param p_prescale Value to scale all audio samples by when converting. Set to 1.0 to do nothing.
+
+ virtual void run(const audio_chunk & p_chunk,
+ mem_block_container & p_output,
+ t_uint32 p_out_bps,
+ t_uint32 p_out_bps_physical,
+ bool p_dither,
+ audio_sample p_prescale
+ ) = 0;
+
+
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(audio_postprocessor);
+};
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/cfg_var.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/cfg_var.cpp
new file mode 100644
index 0000000..884a96b
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/cfg_var.cpp
@@ -0,0 +1,70 @@
+#include "foobar2000.h"
+
+
+
+cfg_var * cfg_var::list=0;
+
+
+static int cfg_var_guid_compare(const cfg_var * p_var1,const cfg_var * p_var2)
+{
+ return pfc::guid_compare(p_var1->get_guid(),p_var2->get_guid());
+}
+
+static int cfg_var_guid_compare_search(const cfg_var * p_var1,const GUID & p_var2)
+{
+ return pfc::guid_compare(p_var1->get_guid(),p_var2);
+}
+
+void cfg_var::config_read_file(stream_reader * p_stream,abort_callback & p_abort)
+{
+ for(;;)
+ {
+ GUID guid;
+ t_uint32 size;
+
+ if (p_stream->read(&guid,sizeof(guid),p_abort) != sizeof(guid)) break;
+ guid = pfc::byteswap_if_be_t(guid);
+ p_stream->read_lendian_t(size,p_abort);
+
+ bool found = false;
+ cfg_var * ptr;
+ for(ptr = list; ptr; ptr=ptr->next) {
+ if (ptr->get_guid() == guid) {
+ stream_reader_limited_ref wrapper(p_stream,size);
+ try {
+ ptr->set_data_raw(&wrapper,size,p_abort);
+ } catch(exception_io_data const & ) {}
+ wrapper.flush_remaining(p_abort);
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ p_stream->skip_object(size,p_abort);
+ }
+}
+
+void cfg_var::config_write_file(stream_writer * p_stream,abort_callback & p_abort) {
+ cfg_var * ptr;
+ pfc::array_t<t_uint8,pfc::alloc_fast_aggressive> temp;
+ for(ptr = list; ptr; ptr=ptr->next) {
+ temp.set_size(0);
+ ptr->get_data_raw(&stream_writer_buffer_append_ref_t<pfc::array_t<t_uint8,pfc::alloc_fast_aggressive> >(temp),p_abort);
+ p_stream->write_lendian_t(ptr->get_guid(),p_abort);
+ p_stream->write_lendian_t(pfc::downcast_guarded<t_uint32>(temp.get_size()),p_abort);
+ if (temp.get_size() > 0) {
+ p_stream->write_object(temp.get_ptr(),temp.get_size(),p_abort);
+ }
+ }
+}
+
+
+void cfg_string::get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {
+ p_stream->write_object(get_ptr(),length(),p_abort);
+}
+
+void cfg_string::set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
+ pfc::string8_fastalloc temp;
+ p_stream->read_string_raw(temp,p_abort);
+ set_string(temp);
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/cfg_var.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/cfg_var.h
new file mode 100644
index 0000000..de1d05f
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/cfg_var.h
@@ -0,0 +1,118 @@
+#ifndef _FOOBAR2000_SDK_CFG_VAR_H_
+#define _FOOBAR2000_SDK_CFG_VAR_H_
+
+//! Base class for configuration variable classes; provides self-registration mechaisms and methods to set/retrieve configuration data; those methods are automatically called for all registered instances by backend when configuration file is being read or written.\n
+//! Note that cfg_var class and its derivatives may be only instantiated statically (as static objects or members of other static objects), NEVER dynamically (operator new, local variables, members of objects instantiated as such).
+class NOVTABLE cfg_var {
+protected:
+ //! @param p_guid GUID of the variable, used to identify variable implementations owning specific configuration file entries when reading the configuration file back. You must generate a new GUID every time you declare a new cfg_var.
+ cfg_var(const GUID & p_guid) : m_guid(p_guid) {PFC_ASSERT(!core_api::are_services_available());/*imperfect check for nonstatic instantiation*/next=list;list=this;};
+ ~cfg_var() {PFC_ASSERT(!core_api::are_services_available());/*imperfect check for nonstatic instantiation*/}
+public:
+ //! Retrieves state of the variable. Called only from main thread, when writing configuration file.
+ //! @param p_stream Stream receiving state of the variable.
+ virtual void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) = 0;
+ //! Sets state of the variable. Called only from main thread, when reading configuration file.
+ //! @param p_stream Stream containing new state of the variable.
+ //! @param p_sizehint Number of bytes contained in the stream; reading past p_sizehint bytes will fail (EOF).
+ virtual void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) = 0;
+
+ //! For internal use only, do not call.
+ inline const GUID & get_guid() const {return m_guid;}
+
+ //! For internal use only, do not call.
+ static void config_read_file(stream_reader * p_stream,abort_callback & p_abort);
+ //! For internal use only, do not call.
+ static void config_write_file(stream_writer * p_stream,abort_callback & p_abort);
+private:
+ GUID m_guid;
+ static cfg_var * list;
+ cfg_var * next;
+
+ cfg_var(const cfg_var& ) {throw pfc::exception_not_implemented();}
+ const cfg_var & operator=(const cfg_var& ) {throw pfc::exception_not_implemented();}
+};
+
+//! Generic integer config variable class. Template parameter can be used to specify integer type to use.\n
+//! Note that cfg_var class and its derivatives may be only instantiated statically (as static objects or members of other static objects), NEVER dynamically (operator new, local variables, members of objects instantiated as such).
+template<typename t_inttype>
+class cfg_int_t : public cfg_var {
+private:
+ t_inttype m_val;
+protected:
+ void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {p_stream->write_lendian_t(m_val,p_abort);}
+ void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
+ t_inttype temp;
+ p_stream->read_lendian_t(temp,p_abort);//alter member data only on success, this will throw an exception when something isn't right
+ m_val = temp;
+ }
+
+public:
+ //! @param p_guid GUID of the variable, used to identify variable implementations owning specific configuration file entries when reading the configuration file back. You must generate a new GUID every time you declare a new cfg_var.
+ //! @param p_default Default value of the variable.
+ explicit inline cfg_int_t(const GUID & p_guid,t_inttype p_default) : cfg_var(p_guid), m_val(p_default) {}
+
+ inline const cfg_int_t<t_inttype> & operator=(const cfg_int_t<t_inttype> & p_val) {m_val=p_val.m_val;return *this;}
+ inline t_inttype operator=(t_inttype p_val) {m_val=p_val;return m_val;}
+
+ inline operator t_inttype() const {return m_val;}
+
+ inline t_inttype get_value() const {return m_val;}
+};
+
+typedef cfg_int_t<t_int32> cfg_int;
+typedef cfg_int_t<t_uint32> cfg_uint;
+//! Since relevant byteswapping functions also understand GUIDs, this can be abused to declare a cfg_guid.
+typedef cfg_int_t<GUID> cfg_guid;
+typedef cfg_int_t<bool> cfg_bool;
+
+//! String config variable. Stored in the stream with int32 header containing size in bytes, followed by non-null-terminated UTF-8 data.\n
+//! Note that cfg_var class and its derivatives may be only instantiated statically (as static objects or members of other static objects), NEVER dynamically (operator new, local variables, members of objects instantiated as such).
+class cfg_string : public cfg_var, public pfc::string8
+{
+protected:
+ void get_data_raw(stream_writer * p_stream,abort_callback & p_abort);
+ void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort);
+
+public:
+ //! @param p_guid GUID of the variable, used to identify variable implementations owning specific configuration file entries when reading the configuration file back. You must generate a new GUID every time you declare a new cfg_var.
+ //! @param p_defaultval Default/initial value of the variable.
+ explicit inline cfg_string(const GUID & p_guid,const char * p_defaultval) : cfg_var(p_guid), pfc::string8(p_defaultval) {}
+
+ inline const cfg_string& operator=(const cfg_string & p_val) {set_string(p_val);return *this;}
+ inline const cfg_string& operator=(const char* p_val) {set_string(p_val);return *this;}
+
+ inline operator const char * () const {return get_ptr();}
+
+};
+
+//! Struct config variable template. Warning: not endian safe, should be used only for nonportable code.\n
+//! Note that cfg_var class and its derivatives may be only instantiated statically (as static objects or members of other static objects), NEVER dynamically (operator new, local variables, members of objects instantiated as such).
+template<typename t_struct>
+class cfg_struct_t : public cfg_var {
+private:
+ t_struct m_val;
+protected:
+
+ void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {p_stream->write_object(&m_val,sizeof(m_val),p_abort);}
+ void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
+ t_struct temp;
+ p_stream->read_object(&temp,sizeof(temp),p_abort);
+ m_val = temp;
+ }
+public:
+ //! @param p_guid GUID of the variable, used to identify variable implementations owning specific configuration file entries when reading the configuration file back. You must generate a new GUID every time you declare a new cfg_var.
+ inline cfg_struct_t(const GUID & p_guid,const t_struct & p_val) : cfg_var(p_guid), m_val(p_val) {}
+ //! @param p_guid GUID of the variable, used to identify variable implementations owning specific configuration file entries when reading the configuration file back. You must generate a new GUID every time you declare a new cfg_var.
+ inline cfg_struct_t(const GUID & p_guid,int filler) : cfg_var(p_guid) {memset(&m_val,filler,sizeof(t_struct));}
+
+ inline const cfg_struct_t<t_struct> & operator=(const cfg_struct_t<t_struct> & p_val) {m_val = p_val.get_value();return *this;}
+ inline const cfg_struct_t<t_struct> & operator=(const t_struct & p_val) {m_val = p_val;return *this;}
+
+ inline const t_struct& get_value() const {return m_val;}
+ inline t_struct& get_value() {return m_val;}
+ inline operator t_struct() const {return m_val;}
+};
+
+
+#endif
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/chapterizer.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/chapterizer.cpp
new file mode 100644
index 0000000..e933088
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/chapterizer.cpp
@@ -0,0 +1,24 @@
+#include "foobar2000.h"
+
+void chapter_list::copy(const chapter_list & p_source)
+{
+ t_size n, count = p_source.get_chapter_count();
+ set_chapter_count(count);
+ for(n=0;n<count;n++)
+ set_info(n,p_source.get_info(n));
+}
+
+bool chapterizer::g_find(service_ptr_t<chapterizer> & p_out,const char * p_path,abort_callback & p_abort)
+{
+ service_ptr_t<chapterizer> ptr;
+ service_enum_t<chapterizer> e;
+ while(e.next(ptr))
+ {
+ if (ptr->is_our_file(p_path,p_abort))
+ {
+ p_out = ptr;
+ return true;
+ }
+ }
+ return false;
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/chapterizer.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/chapterizer.h
new file mode 100644
index 0000000..1197567
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/chapterizer.h
@@ -0,0 +1,74 @@
+//! Interface for object storing list of chapters.
+class NOVTABLE chapter_list
+{
+public:
+ //! Returns number of chapters.
+ virtual t_size get_chapter_count() const = 0;
+ //! Queries description of specified chapter.
+ //! @param p_chapter Index of chapter to query, greater or equal zero and less than get_chapter_count() value. If p_chapter value is out of valid range, results are undefined (e.g. crash).
+ //! @returns reference to file_info object describing specified chapter (length part of file_info indicates distance between beginning of this chapter and next chapter mark). Returned reference value for temporary use only, becomes invalid after any non-const operation on the chapter_list object.
+ virtual const file_info & get_info(t_size p_chapter) const = 0;
+
+ //! Sets number of chapters.
+ virtual void set_chapter_count(t_size p_count) = 0;
+ //! Modifies description of specified chapter.
+ //! @param p_chapter_index Index of chapter to modify, greater or equal zero and less than get_chapter_count() value. If p_chapter value is out of valid range, results are undefined (e.g. crash).
+ //! @param p_info New chapter description. Note that length part of file_info is used to calculate chapter marks.
+ virtual void set_info(t_size p_chapter,const file_info & p_info) = 0;
+
+ //! Copies contents of specified chapter_list object to this object.
+ void copy(const chapter_list & p_source);
+
+ inline const chapter_list & operator=(const chapter_list & p_source) {copy(p_source); return *this;}
+
+protected:
+ chapter_list() {}
+ ~chapter_list() {}
+};
+
+//! Implements chapter_list.
+class chapter_list_impl : public chapter_list
+{
+public:
+ chapter_list_impl(const chapter_list_impl & p_source) {copy(p_source);}
+ chapter_list_impl(const chapter_list & p_source) {copy(p_source);}
+ chapter_list_impl() {}
+
+ const chapter_list_impl & operator=(const chapter_list_impl & p_source) {copy(p_source); return *this;}
+ const chapter_list_impl & operator=(const chapter_list & p_source) {copy(p_source); return *this;}
+
+ t_size get_chapter_count() const {return m_infos.get_size();}
+ const file_info & get_info(t_size p_chapter) const {return m_infos[p_chapter];}
+
+ void set_chapter_count(t_size p_count) {m_infos.set_size(p_count);}
+ void set_info(t_size p_chapter,const file_info & p_info) {m_infos[p_chapter] = p_info;}
+private:
+ pfc::array_t<file_info_impl> m_infos;
+};
+
+
+//! This service implements chapter list editing operations for various file formats, e.g. for MP4 chapters or CD images with embedded cuesheets. Used by converter "encode single file with chapters" feature.
+class NOVTABLE chapterizer : public service_base
+{
+public:
+ //! Tests whether specified path is supported by this implementation.
+ //! @param p_path Path of file to examine.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual bool is_our_file(const char * p_path,abort_callback & p_abort) = 0;
+
+ //! Writes new chapter list to specified file.
+ //! @param p_path Path of file to modify.
+ //! @param p_list New chapter list to write.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void set_chapters(const char * p_path,chapter_list const & p_list,abort_callback & p_abort) = 0;
+ //! Retrieves chapter list from specified file.
+ //! @param p_path Path of file to examine.
+ //! @param p_list Object receiving chapter list.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void get_chapters(const char * p_path,chapter_list & p_list,abort_callback & p_abort) = 0;
+
+ //! Static helper, tries to find chapterizer interface that supports specified file.
+ static bool g_find(service_ptr_t<chapterizer> & p_out,const char * p_path,abort_callback & p_abort);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(chapterizer);
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/commandline.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/commandline.cpp
new file mode 100644
index 0000000..60ef4c4
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/commandline.cpp
@@ -0,0 +1,27 @@
+#include "foobar2000.h"
+
+void commandline_handler_metadb_handle::on_file(const char * url)
+{
+
+ abort_callback_impl blah;
+
+ {
+ playlist_loader_callback_impl callback(blah);
+
+ bool fail = false;
+ try {
+ playlist_loader::g_process_path_ex(url,callback);
+ } catch(std::exception const & e) {
+ console::formatter() << "Unhandled exception in playlist loader: " << e;
+ fail = true;
+ } catch(...) {
+ console::formatter() << "Unhandled exception in playlist loader";
+ fail = true;
+ }
+
+ if (!fail) {
+ t_size n,m=callback.get_count();
+ for(n=0;n<m;n++) on_file(callback.get_item(n));
+ }
+ }
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/commandline.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/commandline.h
new file mode 100644
index 0000000..fd970bf
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/commandline.h
@@ -0,0 +1,50 @@
+#ifndef _FOOBAR2000_SDK_COMMANDLINE_H_
+#define _FOOBAR2000_SDK_COMMANDLINE_H_
+
+#include "service.h"
+
+class NOVTABLE commandline_handler : public service_base
+{
+public:
+ enum result
+ {
+ RESULT_NOT_OURS,//not our command
+ RESULT_PROCESSED,//command processed
+ RESULT_PROCESSED_EXPECT_FILES,//command processed, we want to takeover file urls after this command
+ };
+ virtual result on_token(const char * token)=0;
+ virtual void on_file(const char * url) {};//optional
+ virtual void on_files_done() {};//optional
+ virtual bool want_directories() {return false;}
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(commandline_handler);
+};
+
+class commandline_handler_metadb_handle : public commandline_handler//helper
+{
+protected:
+ virtual void on_file(const char * url);
+ virtual bool want_directories() {return true;}
+public:
+ virtual result on_token(const char * token)=0;
+ virtual void on_files_done() {};
+
+ virtual void on_file(const metadb_handle_ptr & ptr)=0;
+};
+
+/*
+
+how commandline_handler is used:
+
+ scenario #1:
+ creation => on_token() => deletion
+ scenario #2:
+ creation => on_token() returning RESULT_PROCESSED_EXPECT_FILES => on_file(), on_file().... => on_files_done() => deletion
+*/
+
+template<typename T>
+class commandline_handler_factory_t : public service_factory_t<T> {};
+
+
+
+#endif //_FOOBAR2000_SDK_COMMANDLINE_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/completion_notify.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/completion_notify.cpp
new file mode 100644
index 0000000..0a183a8
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/completion_notify.cpp
@@ -0,0 +1,25 @@
+#include "foobar2000.h"
+
+namespace {
+ class main_thread_callback_myimpl : public main_thread_callback {
+ public:
+ void callback_run() {
+ m_notify->on_completion(m_code);
+ }
+
+ main_thread_callback_myimpl(completion_notify_ptr p_notify,unsigned p_code) : m_notify(p_notify), m_code(p_code) {}
+ private:
+ completion_notify_ptr m_notify;
+ unsigned m_code;
+ };
+}
+
+void completion_notify::g_signal_completion_async(completion_notify_ptr p_notify,unsigned p_code) {
+ if (p_notify.is_valid()) {
+ static_api_ptr_t<main_thread_callback_manager>()->add_callback(new service_impl_t<main_thread_callback_myimpl>(p_notify,p_code));
+ }
+}
+
+void completion_notify::on_completion_async(unsigned p_code) {
+ static_api_ptr_t<main_thread_callback_manager>()->add_callback(new service_impl_t<main_thread_callback_myimpl>(this,p_code));
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/completion_notify.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/completion_notify.h
new file mode 100644
index 0000000..c78071c
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/completion_notify.h
@@ -0,0 +1,48 @@
+//! Generic service for receiving notifications about async operation completion. Used by various other services.
+class completion_notify : public service_base {
+public:
+ //! Called when an async operation has been completed. Note that on_completion is always called from main thread. You can use on_completion_async() helper if you need to signal completion while your context is in another thread.\n
+ //! IMPLEMENTATION WARNING: If process being completed creates a window taking caller's window as parent, you must not destroy the parent window inside on_completion(). If you need to do so, use PostMessage() or main_thread_callback to delay the deletion.
+ //! @param p_code Context-specific status code. Possible values depend on the operation being performed.
+ virtual void on_completion(unsigned p_code) = 0;
+
+ //! Helper. Queues a notification, using main_thread_callback.
+ void on_completion_async(unsigned p_code);
+
+ //! Helper. Checks for null ptr and calls on_completion_async when the ptr is not null.
+ static void g_signal_completion_async(service_ptr_t<completion_notify> p_notify,unsigned p_code);
+
+ FB2K_MAKE_SERVICE_INTERFACE(completion_notify,service_base);
+};
+
+//! Helper implementation.
+class completion_notify_orphanable : public completion_notify {
+public:
+ virtual void orphan() = 0;
+};
+
+//! Helper implementation.
+//! IMPLEMENTATION WARNING: If process being completed creates a window taking caller's window as parent, you must not destroy the parent window inside on_task_completion(). If you need to do so, use PostMessage() or main_thread_callback to delay the deletion.
+template<typename t_receiver>
+class completion_notify_impl : public completion_notify_orphanable {
+public:
+ void on_completion(unsigned p_code) {
+ if (m_receiver != NULL) {
+ m_receiver->on_task_completion(m_taskid,p_code);
+ }
+ }
+ void setup(t_receiver * p_receiver, unsigned p_task_id) {m_receiver = p_receiver; m_taskid = p_task_id;}
+ void orphan() {m_receiver = NULL; m_taskid = 0;}
+private:
+ t_receiver * m_receiver;
+ unsigned m_taskid;
+};
+
+template<typename t_receiver>
+service_ptr_t<completion_notify_orphanable> completion_notify_create(t_receiver * p_receiver,unsigned p_taskid) {
+ service_ptr_t<completion_notify_impl<t_receiver> > instance = new service_impl_t<completion_notify_impl<t_receiver> >();
+ instance->setup(p_receiver,p_taskid);
+ return instance;
+}
+
+typedef service_ptr_t<completion_notify> completion_notify_ptr; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/component.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/component.h
new file mode 100644
index 0000000..ecc069d
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/component.h
@@ -0,0 +1,44 @@
+#ifndef _COMPONENT_H_
+#define _COMPONENT_H_
+
+#include "foobar2000.h"
+
+class NOVTABLE foobar2000_client
+{
+public:
+ typedef service_factory_base* pservice_factory_base;
+
+ enum {FOOBAR2000_CLIENT_VERSION_COMPATIBLE = 70, FOOBAR2000_CLIENT_VERSION = 72}; //changes everytime global compatibility is broken
+ virtual t_uint32 FB2KAPI get_version() = 0;
+ virtual pservice_factory_base FB2KAPI get_service_list() = 0;
+
+ virtual void FB2KAPI get_config(stream_writer * p_stream,abort_callback & p_abort) = 0;
+ virtual void FB2KAPI set_config(stream_reader * p_stream,abort_callback & p_abort) = 0;
+ virtual void FB2KAPI set_library_path(const char * path,const char * name) = 0;
+ virtual void FB2KAPI services_init(bool val) = 0;
+ virtual bool is_debug() = 0;
+protected:
+ foobar2000_client() {}
+ ~foobar2000_client() {}
+};
+
+class NOVTABLE foobar2000_api
+{
+public:
+ virtual service_class_ref FB2KAPI service_enum_find_class(const GUID & p_guid) = 0;
+ virtual bool FB2KAPI service_enum_create(service_ptr_t<service_base> & p_out,service_class_ref p_class,t_size p_index) = 0;
+ virtual t_size FB2KAPI service_enum_get_count(service_class_ref p_class) = 0;
+ virtual HWND FB2KAPI get_main_window()=0;
+ virtual bool FB2KAPI assert_main_thread()=0;
+ virtual bool FB2KAPI is_main_thread()=0;
+ virtual bool FB2KAPI is_shutting_down()=0;
+ virtual pcchar FB2KAPI get_profile_path()=0;
+ virtual bool FB2KAPI is_initializing() = 0;
+protected:
+ foobar2000_api() {}
+ ~foobar2000_api() {}
+};
+
+extern foobar2000_api * g_api;
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/component_client.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/component_client.h
new file mode 100644
index 0000000..46aa848
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/component_client.h
@@ -0,0 +1,6 @@
+#ifndef _COMPONENT_CLIENT_H_
+#define _COMPONENT_CLIENT_H_
+
+
+
+#endif //_COMPONENT_CLIENT_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/components_menu.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/components_menu.h
new file mode 100644
index 0000000..8352373
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/components_menu.h
@@ -0,0 +1,7 @@
+#ifndef _COMPONENTS_MENU_H_
+#define _COMPONENTS_MENU_H_
+
+#error deprecated, see menu_item.h
+
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/componentversion.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/componentversion.h
new file mode 100644
index 0000000..a3a3d3d
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/componentversion.h
@@ -0,0 +1,61 @@
+#ifndef _COMPONENTVERSION_H_
+#define _COMPONENTVERSION_H_
+
+class NOVTABLE componentversion : public service_base
+{
+public:
+ virtual void get_file_name(pfc::string_base & out)=0;
+ virtual void get_component_name(pfc::string_base & out)=0;
+ virtual void get_component_version(pfc::string_base & out)=0;
+ virtual void get_about_message(pfc::string_base & out)=0;//about message uses "\n" for line separators
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(componentversion);
+};
+
+class componentversion_impl_simple : public componentversion
+{
+ const char * name,*version,*about;
+public:
+ //do not derive/override
+ virtual void get_file_name(pfc::string_base & out) {out.set_string(core_api::get_my_file_name());}
+ virtual void get_component_name(pfc::string_base & out) {out.set_string(name?name:"");}
+ virtual void get_component_version(pfc::string_base & out) {out.set_string(version?version:"");}
+ virtual void get_about_message(pfc::string_base & out) {out.set_string(about?about:"");}
+ explicit componentversion_impl_simple(const char * p_name,const char * p_version,const char * p_about) : name(p_name), version(p_version), about(p_about ? p_about : "") {}
+};
+
+class componentversion_impl_copy : public componentversion
+{
+ pfc::string8 name,version,about;
+public:
+ //do not derive/override
+ virtual void get_file_name(pfc::string_base & out) {out.set_string(core_api::get_my_file_name());}
+ virtual void get_component_name(pfc::string_base & out) {out.set_string(name);}
+ virtual void get_component_version(pfc::string_base & out) {out.set_string(version);}
+ virtual void get_about_message(pfc::string_base & out) {out.set_string(about);}
+ explicit componentversion_impl_copy(const char * p_name,const char * p_version,const char * p_about) : name(p_name), version(p_version), about(p_about ? p_about : "") {}
+};
+
+typedef service_factory_single_transparent_t<componentversion_impl_simple> __componentversion_impl_simple_factory;
+typedef service_factory_single_transparent_t<componentversion_impl_copy> __componentversion_impl_copy_factory;
+
+class componentversion_impl_simple_factory : public __componentversion_impl_simple_factory {
+public:
+ componentversion_impl_simple_factory(const char * p_name,const char * p_version,const char * p_about) : __componentversion_impl_simple_factory(p_name,p_version,p_about) {}
+};
+
+class componentversion_impl_copy_factory : public __componentversion_impl_copy_factory {
+public:
+ componentversion_impl_copy_factory(const char * p_name,const char * p_version,const char * p_about) : __componentversion_impl_copy_factory(p_name,p_version,p_about) {}
+};
+
+#define DECLARE_COMPONENT_VERSION(NAME,VERSION,ABOUT) \
+ static componentversion_impl_simple_factory g_componentversion_service(NAME,VERSION,ABOUT);
+
+#define DECLARE_COMPONENT_VERSION_COPY(NAME,VERSION,ABOUT) \
+ static componentversion_impl_copy_factory g_componentversion_service(NAME,VERSION,ABOUT);
+
+//usage: DECLARE_COMPONENT_VERSION("blah","v1.337",(const char*)NULL)
+//_copy version copies strings around instead of keeping pointers (bigger but sometimes needed, eg. if strings are created as string_printf() or something inside constructor
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_io_callback.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_io_callback.cpp
new file mode 100644
index 0000000..85ad4c4
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_io_callback.cpp
@@ -0,0 +1,19 @@
+#include "foobar2000.h"
+
+void config_io_callback::g_on_read()
+{
+ service_enum_t<config_io_callback> e;
+ service_ptr_t<config_io_callback> ptr;
+ if (e.first(ptr)) do {
+ ptr->on_read();
+ } while(e.next(ptr));
+}
+
+void config_io_callback::g_on_write(bool reset)
+{
+ service_enum_t<config_io_callback> e;
+ service_ptr_t<config_io_callback> ptr;
+ if (e.first(ptr)) do {
+ ptr->on_write(reset);
+ } while(e.next(ptr));
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_io_callback.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_io_callback.h
new file mode 100644
index 0000000..157cf0c
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_io_callback.h
@@ -0,0 +1,17 @@
+#ifndef _config_io_callback_h_
+#define _config_io_callback_h_
+
+class NOVTABLE config_io_callback : public service_base
+{
+public:
+ virtual void on_read() = 0;
+ virtual void on_write(bool reset) = 0;
+
+ //for core use only
+ static void g_on_read();
+ static void g_on_write(bool reset);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(config_io_callback);
+};
+
+#endif //_config_io_callback_h_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_object.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_object.cpp
new file mode 100644
index 0000000..6ff59c5
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_object.cpp
@@ -0,0 +1,206 @@
+#include "foobar2000.h"
+
+void config_object_notify_manager::g_on_changed(const service_ptr_t<config_object> & p_object)
+{
+ if (core_api::assert_main_thread())
+ {
+ service_enum_t<config_object_notify_manager> e;
+ service_ptr_t<config_object_notify_manager> ptr;
+ while(e.next(ptr))
+ ptr->on_changed(p_object);
+ }
+}
+
+bool config_object::g_find(service_ptr_t<config_object> & p_out,const GUID & p_guid)
+{
+ service_ptr_t<config_object> ptr;
+ service_enum_t<config_object> e;
+ while(e.next(ptr))
+ {
+ if (ptr->get_guid() == p_guid)
+ {
+ p_out = ptr;
+ return true;
+ }
+ }
+ return false;
+}
+
+void config_object::g_get_data_string(const GUID & p_guid,pfc::string_base & p_out)
+{
+ service_ptr_t<config_object> ptr;
+ if (!g_find(ptr,p_guid)) throw exception_service_not_found();
+ ptr->get_data_string(p_out);
+}
+
+void config_object::g_set_data_string(const GUID & p_guid,const char * p_data,t_size p_length)
+{
+ service_ptr_t<config_object> ptr;
+ if (!g_find(ptr,p_guid)) throw exception_service_not_found();
+ ptr->set_data_string(p_data,p_length);
+}
+
+void config_object::get_data_int32(t_int32 & p_out)
+{
+ t_int32 temp;
+ get_data_struct_t<t_int32>(temp);
+ byte_order::order_le_to_native_t(temp);
+ p_out = temp;
+}
+
+void config_object::set_data_int32(t_int32 p_val)
+{
+ t_int32 temp = p_val;
+ byte_order::order_native_to_le_t(temp);
+ set_data_struct_t<t_int32>(temp);
+}
+
+bool config_object::get_data_bool_simple(bool p_default) {
+ try {
+ bool ret = p_default;
+ get_data_bool(ret);
+ return ret;
+ } catch(std::exception const &) {return p_default;}
+}
+
+t_int32 config_object::get_data_int32_simple(t_int32 p_default) {
+ try {
+ t_int32 ret = p_default;
+ get_data_int32(ret);
+ return ret;
+ } catch(std::exception const &) {return p_default;}
+}
+
+void config_object::g_get_data_int32(const GUID & p_guid,t_int32 & p_out) {
+ service_ptr_t<config_object> ptr;
+ if (!g_find(ptr,p_guid)) throw exception_service_not_found();
+ ptr->get_data_int32(p_out);
+}
+
+void config_object::g_set_data_int32(const GUID & p_guid,t_int32 p_val) {
+ service_ptr_t<config_object> ptr;
+ if (!g_find(ptr,p_guid)) throw exception_service_not_found();
+ ptr->set_data_int32(p_val);
+}
+
+bool config_object::g_get_data_bool_simple(const GUID & p_guid,bool p_default)
+{
+ service_ptr_t<config_object> ptr;
+ if (!g_find(ptr,p_guid)) throw exception_service_not_found();
+ return ptr->get_data_bool_simple(p_default);
+}
+
+t_int32 config_object::g_get_data_int32_simple(const GUID & p_guid,t_int32 p_default)
+{
+ service_ptr_t<config_object> ptr;
+ if (!g_find(ptr,p_guid)) throw exception_service_not_found();
+ return ptr->get_data_int32_simple(p_default);
+}
+
+void config_object::get_data_bool(bool & p_out) {get_data_struct_t<bool>(p_out);}
+void config_object::set_data_bool(bool p_val) {set_data_struct_t<bool>(p_val);}
+
+void config_object::g_get_data_bool(const GUID & p_guid,bool & p_out) {g_get_data_struct_t<bool>(p_guid,p_out);}
+void config_object::g_set_data_bool(const GUID & p_guid,bool p_val) {g_set_data_struct_t<bool>(p_guid,p_val);}
+
+namespace {
+ class stream_writer_string : public stream_writer {
+ public:
+ void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ m_out.add_string((const char*)p_buffer,p_bytes);
+ }
+ stream_writer_string(pfc::string_base & p_out) : m_out(p_out) {m_out.reset();}
+ private:
+ pfc::string_base & m_out;
+ };
+
+ class stream_writer_fixedbuffer : public stream_writer {
+ public:
+ void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ if (p_bytes > 0) {
+ if (p_bytes > m_bytes - m_bytes_read) throw pfc::exception_overflow();
+ memcpy((t_uint8*)m_out,p_buffer,p_bytes);
+ m_bytes_read += p_bytes;
+ }
+ }
+ stream_writer_fixedbuffer(void * p_out,t_size p_bytes,t_size & p_bytes_read) : m_out(p_out), m_bytes(p_bytes), m_bytes_read(p_bytes_read) {m_bytes_read = 0;}
+ private:
+ void * m_out;
+ t_size m_bytes;
+ t_size & m_bytes_read;
+ };
+
+
+
+ class stream_writer_get_length : public stream_writer {
+ public:
+ void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ m_length += p_bytes;
+ }
+ stream_writer_get_length(t_size & p_length) : m_length(p_length) {m_length = 0;}
+ private:
+ t_size & m_length;
+ };
+};
+
+t_size config_object::get_data_raw(void * p_out,t_size p_bytes) {
+ t_size ret = 0;
+ get_data(&stream_writer_fixedbuffer(p_out,p_bytes,ret),abort_callback_impl());
+ return ret;
+}
+
+t_size config_object::get_data_raw_length() {
+ t_size ret = 0;
+ get_data(&stream_writer_get_length(ret),abort_callback_impl());
+ return ret;
+}
+
+void config_object::set_data_raw(const void * p_data,t_size p_bytes, bool p_notify) {
+ set_data(&stream_reader_memblock_ref(p_data,p_bytes),abort_callback_impl(),p_notify);
+}
+
+void config_object::set_data_string(const char * p_data,t_size p_length) {
+ set_data_raw(p_data,pfc::strlen_max(p_data,p_length));
+}
+
+void config_object::get_data_string(pfc::string_base & p_out) {
+ get_data(&stream_writer_string(p_out),abort_callback_impl());
+}
+
+
+//config_object_impl stuff
+
+
+void config_object_impl::get_data(stream_writer * p_stream,abort_callback & p_abort) const {
+ insync(m_sync);
+ p_stream->write_object(m_data.get_ptr(),m_data.get_size(),p_abort);
+}
+
+void config_object_impl::set_data(stream_reader * p_stream,abort_callback & p_abort,bool p_notify) {
+ core_api::ensure_main_thread();
+
+ {
+ insync(m_sync);
+ m_data.set_size(0);
+ enum {delta = 1024};
+ t_uint8 buffer[delta];
+ for(;;)
+ {
+ t_size delta_done = p_stream->read(buffer,delta,p_abort);
+
+ if (delta_done > 0)
+ {
+ m_data.append_fromptr(buffer,delta_done);
+ }
+
+ if (delta_done != delta) break;
+ }
+ }
+
+ if (p_notify) config_object_notify_manager::g_on_changed(this);
+}
+
+config_object_impl::config_object_impl(const GUID & p_guid,const void * p_data,t_size p_bytes) : cfg_var(p_guid)
+{
+ m_data.set_data_fromptr((const t_uint8*)p_data,p_bytes);
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_object.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_object.h
new file mode 100644
index 0000000..e460dc5
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_object.h
@@ -0,0 +1,85 @@
+#ifndef _CONFIG_OBJECT_H_
+#define _CONFIG_OBJECT_H_
+
+class config_object;
+
+class NOVTABLE config_object_notify_manager : public service_base
+{
+public:
+ virtual void on_changed(const service_ptr_t<config_object> & p_object) = 0;
+ static void g_on_changed(const service_ptr_t<config_object> & p_object);
+
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(config_object_notify_manager);
+};
+
+class NOVTABLE config_object : public service_base
+{
+public:
+ //interface
+ virtual GUID get_guid() const = 0;
+ virtual void get_data(stream_writer * p_stream,abort_callback & p_abort) const = 0;
+ virtual void set_data(stream_reader * p_stream,abort_callback & p_abort,bool p_sendnotify = true) = 0;
+
+ //helpers
+ static bool g_find(service_ptr_t<config_object> & p_out,const GUID & p_guid);
+
+ void set_data_raw(const void * p_data,t_size p_bytes,bool p_sendnotify = true);
+ t_size get_data_raw(void * p_out,t_size p_bytes);
+ t_size get_data_raw_length();
+
+ template<class T> void get_data_struct_t(T& p_out);
+ template<class T> void set_data_struct_t(const T& p_in);
+ template<class T> static void g_get_data_struct_t(const GUID & p_guid,T & p_out);
+ template<class T> static void g_set_data_struct_t(const GUID & p_guid,const T & p_in);
+
+ void set_data_string(const char * p_data,t_size p_length);
+ void get_data_string(pfc::string_base & p_out);
+
+ void get_data_bool(bool & p_out);
+ void set_data_bool(bool p_val);
+ void get_data_int32(t_int32 & p_out);
+ void set_data_int32(t_int32 p_val);
+ bool get_data_bool_simple(bool p_default);
+ t_int32 get_data_int32_simple(t_int32 p_default);
+
+ static void g_get_data_string(const GUID & p_guid,pfc::string_base & p_out);
+ static void g_set_data_string(const GUID & p_guid,const char * p_data,t_size p_length = ~0);
+
+ static void g_get_data_bool(const GUID & p_guid,bool & p_out);
+ static void g_set_data_bool(const GUID & p_guid,bool p_val);
+ static void g_get_data_int32(const GUID & p_guid,t_int32 & p_out);
+ static void g_set_data_int32(const GUID & p_guid,t_int32 p_val);
+ static bool g_get_data_bool_simple(const GUID & p_guid,bool p_default);
+ static t_int32 g_get_data_int32_simple(const GUID & p_guid,t_int32 p_default);
+
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(config_object);
+};
+
+class standard_config_objects
+{
+public:
+ static const GUID bool_remember_window_positions, bool_ui_always_on_top,bool_playlist_stop_after_current;
+ static const GUID bool_playback_follows_cursor, bool_cursor_follows_playback;
+ static const GUID bool_show_keyboard_shortcuts_in_menus;
+ static const GUID string_gui_last_directory_media,string_gui_last_directory_playlists;
+ static const GUID int32_dynamic_bitrate_display_rate;
+
+
+ inline static bool query_show_keyboard_shortcuts_in_menus() {return config_object::g_get_data_bool_simple(standard_config_objects::bool_show_keyboard_shortcuts_in_menus,true);}
+ inline static bool query_remember_window_positions() {return config_object::g_get_data_bool_simple(standard_config_objects::bool_remember_window_positions,true);}
+
+};
+
+class config_object_notify : public service_base
+{
+public:
+ virtual t_size get_watched_object_count() = 0;
+ virtual GUID get_watched_object(t_size p_index) = 0;
+ virtual void on_watched_object_changed(const service_ptr_t<config_object> & p_object) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(config_object_notify);
+};
+
+#endif _CONFIG_OBJECT_H_
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_object_impl.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_object_impl.h
new file mode 100644
index 0000000..ccd4106
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/config_object_impl.h
@@ -0,0 +1,157 @@
+#ifndef _CONFIG_OBJECT_IMPL_H_
+#define _CONFIG_OBJECT_IMPL_H_
+
+//template function bodies from config_object class
+
+template<class T>
+void config_object::get_data_struct_t(T& p_out) {
+ if (get_data_raw(&p_out,sizeof(T)) != sizeof(T)) throw exception_io_data_truncation();
+}
+
+template<class T>
+void config_object::set_data_struct_t(const T& p_in) {
+ return set_data_raw(&p_in,sizeof(T));
+}
+
+template<class T>
+void config_object::g_get_data_struct_t(const GUID & p_guid,T & p_out) {
+ service_ptr_t<config_object> ptr;
+ if (!g_find(ptr,p_guid)) throw exception_service_not_found();
+ return ptr->get_data_struct_t<T>(p_out);
+}
+
+template<class T>
+void config_object::g_set_data_struct_t(const GUID & p_guid,const T & p_in) {
+ service_ptr_t<config_object> ptr;
+ if (!g_find(ptr,p_guid)) throw exception_service_not_found();
+ return ptr->set_data_struct_t<T>(p_in);
+}
+
+
+class config_object_impl : public config_object, private cfg_var
+{
+public:
+ GUID get_guid() const {return cfg_var::get_guid();}
+ void get_data(stream_writer * p_stream,abort_callback & p_abort) const ;
+ void set_data(stream_reader * p_stream,abort_callback & p_abort,bool p_notify);
+
+ config_object_impl(const GUID & p_guid,const void * p_data,t_size p_bytes);
+private:
+
+ //cfg_var methods
+ void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {get_data(p_stream,p_abort);}
+ void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {set_data(p_stream,p_abort,false);}
+
+ mutable critical_section m_sync;
+ pfc::array_t<t_uint8> m_data;
+};
+
+typedef service_factory_single_transparent_t<config_object_impl> config_object_factory;
+
+template<t_size p_size>
+class config_object_fixed_impl_t : public config_object, private cfg_var
+{
+public:
+ GUID get_guid() const {return cfg_var::get_guid();}
+
+ void get_data(stream_writer * p_stream,abort_callback & p_abort) const {
+ insync(m_sync);
+ p_stream->write_object(m_data,p_size,p_abort);
+ }
+
+ void set_data(stream_reader * p_stream,abort_callback & p_abort,bool p_notify) {
+ core_api::ensure_main_thread();
+
+ {
+ t_uint8 temp[p_size];
+ p_stream->read_object(temp,p_size,p_abort);
+ insync(m_sync);
+ memcpy(m_data,temp,p_size);
+ }
+
+ if (p_notify) config_object_notify_manager::g_on_changed(this);
+ }
+
+ config_object_fixed_impl_t (const GUID & p_guid,const void * p_data)
+ : cfg_var(p_guid)
+ {
+ memcpy(m_data,p_data,p_size);
+ }
+
+private:
+ //cfg_var methods
+ void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {get_data(p_stream,p_abort);}
+ void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {set_data(p_stream,p_abort,false);}
+
+ mutable critical_section m_sync;
+ t_uint8 m_data[p_size];
+
+};
+
+
+template<t_size p_size>
+class config_object_fixed_factory_t : public service_factory_single_transparent_t<config_object_fixed_impl_t<p_size> >
+{
+public:
+ config_object_fixed_factory_t(const GUID & p_guid,const void * p_initval)
+ :
+ service_factory_single_transparent_t<config_object_fixed_impl_t<p_size> >
+ (p_guid,p_initval)
+ {}
+};
+
+
+class config_object_string_factory : public config_object_factory
+{
+public:
+ config_object_string_factory(const GUID & p_guid,const char * p_string,t_size p_string_length = infinite)
+ : config_object_factory(p_guid,p_string,pfc::strlen_max(p_string,infinite)) {}
+
+};
+
+class config_object_bool_factory : public config_object_fixed_factory_t<1>
+{
+public:
+ config_object_bool_factory(const GUID & p_guid,bool p_initval)
+ : config_object_fixed_factory_t<1>(p_guid,&p_initval) {}
+};
+
+template<class T>
+class config_object_int_factory_t : public config_object_fixed_factory_t<sizeof(T)>
+{
+private:
+ template<class T>
+ struct t_initval
+ {
+ T m_initval;
+ t_initval(T p_initval) : m_initval(p_initval) {byte_order::order_native_to_le_t(m_initval);}
+ T * get_ptr() {return &m_initval;}
+ };
+public:
+ config_object_int_factory_t(const GUID & p_guid,T p_initval)
+ : config_object_fixed_factory_t<sizeof(T)>(p_guid,t_initval<T>(p_initval).get_ptr() )
+ {}
+};
+
+typedef config_object_int_factory_t<t_int32> config_object_int32_factory;
+
+
+
+class config_object_notify_impl_simple : public config_object_notify
+{
+public:
+ t_size get_watched_object_count() {return 1;}
+ GUID get_watched_object(t_size p_index) {return m_guid;}
+ void on_watched_object_changed(const service_ptr_t<config_object> & p_object) {m_func(p_object);}
+
+ typedef void (*t_func)(const service_ptr_t<config_object> &);
+
+ config_object_notify_impl_simple(const GUID & p_guid,t_func p_func) : m_guid(p_guid), m_func(p_func) {}
+private:
+ GUID m_guid;
+ t_func m_func;
+};
+
+typedef service_factory_single_transparent_t<config_object_notify_impl_simple> config_object_notify_simple_factory;
+
+#endif _CONFIG_OBJECT_IMPL_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/console.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/console.cpp
new file mode 100644
index 0000000..2c2c352
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/console.cpp
@@ -0,0 +1,43 @@
+#include "foobar2000.h"
+
+
+void console::info(const char * p_message) {print(p_message);}
+void console::error(const char * p_message) {formatter() << "ERROR : " << p_message;}
+void console::warning(const char * p_message) {formatter() << "WARNING : " << p_message;}
+
+void console::info_location(const playable_location & src) {print_location(src);}
+void console::info_location(const metadb_handle_ptr & src) {print_location(src);}
+
+void console::print_location(const metadb_handle_ptr & src)
+{
+ print_location(src->get_location());
+}
+
+void console::print_location(const playable_location & src)
+{
+ formatter() << src;
+}
+
+void console::print(const char* p_message)
+{
+ if (core_api::are_services_available()) {
+ service_ptr_t<console_receiver> ptr;
+ service_enum_t<console_receiver> e;
+ while(e.next(ptr)) ptr->print(p_message,infinite);
+ }
+}
+
+void console::printf(const char* p_format,...)
+{
+ va_list list;
+ va_start(list,p_format);
+ printfv(p_format,list);
+ va_end(list);
+}
+
+void console::printfv(const char* p_format,va_list p_arglist)
+{
+ pfc::string8_fastalloc temp;
+ uPrintfV(temp,p_format,p_arglist);
+ print(temp);
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/console.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/console.h
new file mode 100644
index 0000000..0377259
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/console.h
@@ -0,0 +1,35 @@
+#ifndef _CONSOLE_H_
+#define _CONSOLE_H_
+
+//! Namespace with functions for sending text to console. All functions are fully multi-thread safe, though they must not be called during dll initialization or deinitialization (e.g. static object constructors or destructors) when service system is not available.
+namespace console
+{
+ void info(const char * p_message);
+ void error(const char * p_message);
+ void warning(const char * p_message);
+ void info_location(const playable_location & src);
+ void info_location(const metadb_handle_ptr & src);
+ void print_location(const playable_location & src);
+ void print_location(const metadb_handle_ptr & src);
+
+ void print(const char*);
+ void printf(const char*,...);
+ void printfv(const char*,va_list p_arglist);
+
+ //! Usage: console::formatter() << "blah " << somenumber << " asdf" << somestring;
+ class formatter : public pfc::string_formatter {
+ public:
+ ~formatter() {if (!is_empty()) console::print(get_ptr());}
+ };
+};
+
+//! Interface receiving console output. Do not reimplement or call directly; use console namespace functions instead.
+class NOVTABLE console_receiver : public service_base
+{
+public:
+ virtual void print(const char * p_message,t_size p_message_length) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(console_receiver);
+};
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/contextmenu.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/contextmenu.h
new file mode 100644
index 0000000..c441e1a
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/contextmenu.h
@@ -0,0 +1,215 @@
+#ifndef _FOOBAR2000_MENU_ITEM_H_
+#define _FOOBAR2000_MENU_ITEM_H_
+
+typedef void * t_glyph;
+
+
+class NOVTABLE contextmenu_item_node {
+public:
+ enum t_flags {
+ FLAG_CHECKED = 1,
+ FLAG_DISABLED = 2,
+ FLAG_GRAYED = 4,
+ FLAG_DISABLED_GRAYED = FLAG_DISABLED|FLAG_GRAYED,
+ };
+
+ enum t_type {
+ TYPE_POPUP,TYPE_COMMAND,TYPE_SEPARATOR
+ };
+
+ virtual bool get_display_data(pfc::string_base & p_out,unsigned & p_displayflags,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller) = 0;
+ virtual t_type get_type() = 0;
+ virtual void execute(const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller) = 0;
+ virtual t_glyph get_glyph(const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller) {return 0;}//RESERVED
+ virtual t_size get_children_count() = 0;
+ virtual contextmenu_item_node * get_child(t_size p_index) = 0;
+ virtual bool get_description(pfc::string_base & p_out) = 0;
+ virtual GUID get_guid() = 0;
+ virtual bool is_mappable_shortcut() = 0;
+
+protected:
+ contextmenu_item_node() {}
+ ~contextmenu_item_node() {}
+};
+
+class NOVTABLE contextmenu_item_node_root : public contextmenu_item_node
+{
+public:
+ virtual ~contextmenu_item_node_root() {}
+};
+
+class NOVTABLE contextmenu_item_node_leaf : public contextmenu_item_node
+{
+public:
+ t_type get_type() {return TYPE_COMMAND;}
+ t_size get_children_count() {return 0;}
+ contextmenu_item_node * get_child(t_size) {return NULL;}
+};
+
+class NOVTABLE contextmenu_item_node_root_leaf : public contextmenu_item_node_root
+{
+public:
+ t_type get_type() {return TYPE_COMMAND;}
+ t_size get_children_count() {return 0;}
+ contextmenu_item_node * get_child(t_size) {return NULL;}
+};
+
+class NOVTABLE contextmenu_item_node_popup : public contextmenu_item_node
+{
+public:
+ t_type get_type() {return TYPE_POPUP;}
+ void execute(const pfc::list_base_const_t<metadb_handle_ptr> & data,const GUID & caller) {}
+ bool get_description(pfc::string_base & p_out) {return false;}
+};
+
+class NOVTABLE contextmenu_item_node_root_popup : public contextmenu_item_node_root
+{
+public:
+ t_type get_type() {return TYPE_POPUP;}
+ void execute(const pfc::list_base_const_t<metadb_handle_ptr> & data,const GUID & caller) {}
+ bool get_description(pfc::string_base & p_out) {return false;}
+};
+
+class contextmenu_item_node_separator : public contextmenu_item_node
+{
+public:
+ t_type get_type() {return TYPE_SEPARATOR;}
+ void execute(const pfc::list_base_const_t<metadb_handle_ptr> & data,const GUID & caller) {}
+ bool get_description(pfc::string_base & p_out) {return false;}
+ t_size get_children_count() {return 0;}
+ bool get_display_data(pfc::string_base & p_out,unsigned & p_displayflags,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller)
+ {
+ p_displayflags = 0;
+ p_out = "---";
+ return true;
+ }
+ contextmenu_item_node * get_child(t_size) {return NULL;}
+};
+
+/*!
+Service class for declaring context menu commands.\n
+See contextmenu_item_simple for implementation helper without dynamic menu generation features.\n
+All methods are valid from main app thread only.
+*/
+class NOVTABLE contextmenu_item : public service_base {
+public:
+ enum t_enabled_state {
+ FORCE_OFF,
+ DEFAULT_OFF,
+ DEFAULT_ON,
+ };
+
+ virtual unsigned get_num_items() = 0;
+ virtual contextmenu_item_node_root * instantiate_item(unsigned p_index,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller) = 0;
+ virtual GUID get_item_guid(unsigned p_index) = 0;
+ virtual void get_item_name(unsigned p_index,pfc::string_base & p_out) = 0;
+ virtual void get_item_default_path(unsigned p_index,pfc::string_base & p_out) = 0;
+ virtual bool get_item_description(unsigned p_index,pfc::string_base & p_out) = 0;
+ virtual t_enabled_state get_enabled_state(unsigned p_index) = 0;
+ virtual void item_execute_simple(unsigned p_index,const GUID & p_node,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller) = 0;
+
+ bool item_get_display_data_root(pfc::string_base & p_out,unsigned & displayflags,unsigned p_index,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller);
+ bool item_get_display_data(pfc::string_base & p_out,unsigned & displayflags,unsigned p_index,const GUID & p_node,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller);
+
+ static const GUID caller_now_playing;
+ static const GUID caller_playlist;
+ static const GUID caller_undefined;
+ static const GUID caller_keyboard_shortcut_list;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(contextmenu_item);
+};
+
+//! contextmenu_item implementation helper for implementing non-dynamically-generated context menu items; derive from this instead of from contextmenu_item directly if your menu items are static.
+class NOVTABLE contextmenu_item_simple : public contextmenu_item
+{
+private:
+ class contextmenu_item_node_impl : public contextmenu_item_node_root_leaf
+ {
+ public:
+ contextmenu_item_node_impl(contextmenu_item_simple * p_owner,unsigned p_index) : m_owner(p_owner), m_index(p_index) {}
+ bool get_display_data(pfc::string_base & p_out,unsigned & p_displayflags,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller) {return m_owner->get_display_data(m_index,p_data,p_out,p_displayflags,p_caller);}
+ void execute(const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller) {m_owner->context_command(m_index,p_data,p_caller);}
+ bool get_description(pfc::string_base & p_out) {return m_owner->get_item_description(m_index,p_out);}
+ GUID get_guid() {return pfc::guid_null;}
+ bool is_mappable_shortcut() {return m_owner->item_is_mappable_shortcut(m_index);}
+ private:
+ service_ptr_t<contextmenu_item_simple> m_owner;
+ unsigned m_index;
+ };
+
+ contextmenu_item_node_root * instantiate_item(unsigned p_index,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller)
+ {
+ return new contextmenu_item_node_impl(this,p_index);
+ }
+
+
+ void item_execute_simple(unsigned p_index,const GUID & p_node,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller)
+ {
+ if (p_node == pfc::guid_null)
+ context_command(p_index,p_data,p_caller);
+ }
+
+ virtual bool item_is_mappable_shortcut(unsigned p_index)
+ {
+ return true;
+ }
+
+
+ virtual bool get_display_data(unsigned n,const pfc::list_base_const_t<metadb_handle_ptr> & data,pfc::string_base & p_out,unsigned & displayflags,const GUID & caller)
+ {
+ bool rv = false;
+ assert(n>=0 && n<get_num_items());
+ if (data.get_count()>0)
+ {
+ rv = context_get_display(n,data,p_out,displayflags,caller);
+ }
+ return rv;
+ }
+public:
+ //! Same as contextmenu_item_node::t_flags.
+ enum t_flags
+ {
+ FLAG_CHECKED = 1,
+ FLAG_DISABLED = 2,
+ FLAG_GRAYED = 4,
+ FLAG_DISABLED_GRAYED = FLAG_DISABLED|FLAG_GRAYED,
+ };
+
+
+ virtual t_enabled_state get_enabled_state(unsigned p_index) {return contextmenu_item::DEFAULT_ON;}
+ virtual unsigned get_num_items()=0;
+ virtual void get_item_name(unsigned p_index,pfc::string_base & p_out)=0;
+ virtual void get_item_default_path(unsigned p_index,pfc::string_base & p_out) = 0;
+ virtual void context_command(unsigned p_index,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID& p_caller)=0;
+ virtual bool context_get_display(unsigned p_index,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,pfc::string_base & p_out,unsigned & p_displayflags,const GUID & p_caller) {
+ PFC_ASSERT(p_index>=0 && p_index<get_num_items());
+ get_item_name(p_index,p_out);
+ return true;
+ }
+ virtual GUID get_item_guid(unsigned p_index) = 0;
+ virtual bool get_item_description(unsigned p_index,pfc::string_base & p_out) = 0;
+
+};
+
+
+template<typename T>
+class contextmenu_item_factory_t : public service_factory_single_t<T> {};
+
+
+#define DECLARE_CONTEXT_MENU_ITEM(P_CLASSNAME,P_NAME,P_DEFAULTPATH,P_FUNC,P_GUID,P_DESCRIPTION) \
+ namespace { \
+ class P_CLASSNAME : public contextmenu_item_simple { \
+ public: \
+ unsigned get_num_items() {return 1;} \
+ void get_item_name(unsigned p_index,pfc::string_base & p_out) {p_out = P_NAME;} \
+ void get_item_default_path(unsigned p_index,pfc::string_base & p_out) {p_out = P_DEFAULTPATH;} \
+ void context_command(unsigned p_index,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID& p_caller) {P_FUNC(p_data);} \
+ GUID get_item_guid(unsigned p_index) {return P_GUID;} \
+ bool get_item_description(unsigned p_index,pfc::string_base & p_out) {if (P_DESCRIPTION[0] == 0) return false;p_out = P_DESCRIPTION; return true;} \
+ }; \
+ static contextmenu_item_factory_t<P_CLASSNAME> g_##P_CLASSNAME##_factory; \
+ }
+
+
+
+#endif //_FOOBAR2000_MENU_ITEM_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/contextmenu_manager.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/contextmenu_manager.h
new file mode 100644
index 0000000..3493617
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/contextmenu_manager.h
@@ -0,0 +1,108 @@
+#ifndef _FOOBAR2000_MENU_MANAGER_H_
+#define _FOOBAR2000_MENU_MANAGER_H_
+
+
+class NOVTABLE keyboard_shortcut_manager : public service_base
+{
+public:
+ static bool g_get(service_ptr_t<keyboard_shortcut_manager> & p_out) {return service_enum_create_t(p_out,0);}
+
+ enum shortcut_type
+ {
+ TYPE_MAIN,
+ TYPE_CONTEXT,
+ TYPE_CONTEXT_PLAYLIST,
+ TYPE_CONTEXT_NOW_PLAYING,
+ };
+
+
+ virtual bool process_keydown(shortcut_type type,const pfc::list_base_const_t<metadb_handle_ptr> & data,unsigned keycode)=0;
+ virtual bool process_keydown_ex(shortcut_type type,const pfc::list_base_const_t<metadb_handle_ptr> & data,unsigned keycode,const GUID & caller)=0;
+ bool on_keydown(shortcut_type type,WPARAM wp);
+ bool on_keydown_context(const pfc::list_base_const_t<metadb_handle_ptr> & data,WPARAM wp,const GUID & caller);
+ bool on_keydown_auto(WPARAM wp);
+ bool on_keydown_auto_playlist(WPARAM wp);
+ bool on_keydown_auto_context(const pfc::list_base_const_t<metadb_handle_ptr> & data,WPARAM wp,const GUID & caller);
+
+ virtual bool get_key_description_for_action(const GUID & p_command,const GUID & p_subcommand, pfc::string_base & out, shortcut_type type, bool is_global)=0;
+
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(keyboard_shortcut_manager);
+/*
+usage:
+
+ in a windowproc:
+
+ case WM_KEYDOWN:
+ keyboard_shortcut_manager::get()->on_keydown(wparam);
+ break;
+ case WM_SYSKEYDOWN:
+ keyboard_shortcut_manager::get()->on_keydown(wparam);
+ break;
+
+ return value is true if key got translated to one of user-configured actions, false if not
+ */
+};
+
+
+
+
+class NOVTABLE contextmenu_node {
+public:
+ virtual contextmenu_item_node::t_type get_type()=0;
+ virtual const char * get_name()=0;
+ virtual t_size get_num_children()=0;//TYPE_POPUP only
+ virtual contextmenu_node * get_child(t_size n)=0;//TYPE_POPUP only
+ virtual unsigned get_display_flags()=0;//TYPE_COMMAND/TYPE_POPUP only, see contextmenu_item::FLAG_*
+ virtual unsigned get_id()=0;//TYPE_COMMAND only, returns zero-based index (helpful for win32 menu command ids)
+ virtual void execute()=0;//TYPE_COMMAND only
+ virtual bool get_description(pfc::string_base & out)=0;//TYPE_COMMAND only
+ virtual bool get_full_name(pfc::string_base & out)=0;//TYPE_COMMAND only
+ virtual void * get_glyph()=0;//RESERVED, do not use
+protected:
+ contextmenu_node() {}
+ ~contextmenu_node() {}
+};
+
+
+
+class NOVTABLE contextmenu_manager : public service_base
+{
+public:
+ enum
+ {
+ FLAG_SHOW_SHORTCUTS = 1,
+ FLAG_SHOW_SHORTCUTS_GLOBAL = 2,
+ };
+ virtual void init_context(const pfc::list_base_const_t<metadb_handle_ptr> & data,unsigned flags)=0;//flags - see FLAG_* above
+ virtual void init_context_playlist(unsigned flags)=0;
+ virtual contextmenu_node * get_root()=0;//releasing contextmenu_manager service releaases nodes; root may be null in case of error or something
+ virtual contextmenu_node * find_by_id(unsigned id)=0;
+ virtual void set_shortcut_preference(const keyboard_shortcut_manager::shortcut_type * data,unsigned count)=0;
+
+
+
+ static void g_create(service_ptr_t<contextmenu_manager> & p_out) {p_out = standard_api_create_t<contextmenu_manager>();}
+
+#ifdef WIN32
+ static void win32_build_menu(HMENU menu,contextmenu_node * parent,int base_id,int max_id);//menu item identifiers are base_id<=N<base_id+max_id (if theres too many items, they will be clipped)
+ static void win32_run_menu_context(HWND parent,const pfc::list_base_const_t<metadb_handle_ptr> & data, const POINT * pt = 0,unsigned flags = 0);
+ static void win32_run_menu_context_playlist(HWND parent,const POINT * pt = 0,unsigned flags = 0);
+ void win32_run_menu_popup(HWND parent,const POINT * pt = 0);
+ void win32_build_menu(HMENU menu,int base_id,int max_id) {win32_build_menu(menu,get_root(),base_id,max_id);}
+
+
+#endif
+
+ virtual void init_context_ex(const pfc::list_base_const_t<metadb_handle_ptr> & data,unsigned flags,const GUID & caller)=0;
+ virtual bool init_context_now_playing(unsigned flags)=0;//returns false if not playing
+
+ bool execute_by_id(unsigned id);
+
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(contextmenu_manager);
+};
+
+
+
+#endif //_FOOBAR2000_MENU_MANAGER_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/core_api.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/core_api.h
new file mode 100644
index 0000000..d63d6eb
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/core_api.h
@@ -0,0 +1,33 @@
+#ifndef _CORE_API_H_
+#define _CORE_API_H_
+
+namespace core_api {
+
+ //! Exception thrown by APIs locked to main app thread when called from another thread.
+ PFC_DECLARE_EXCEPTION(exception_wrong_thread,pfc::exception_bug_check,"This method can be called only from the main thread");
+
+ //! Retrieves HINSTANCE of calling DLL.
+ HINSTANCE get_my_instance();
+ //! Retrieves filename of calling dll, excluding extension, e.g. "foo_asdf"
+ const char * get_my_file_name();
+ //! Retrieves full path of calling dll, e.g. file://c:\blah\foobar2000\foo_asdf.dll
+ const char * get_my_full_path();
+ //! Retrieves main app window. WARNING: this is provided for parent of dialog windows and such only; using it for anything else (such as hooking windowproc to alter app behaviors) is absolutely illegal.
+ HWND get_main_window();
+ //! Tests whether services are available at this time. They are not available only during DLL startup or shutdown (e.g. inside static object constructors or destructors).
+ bool are_services_available();
+ //! Tests whether calling thread is main app thread, and shows diagnostic message in debugger output if it's not.
+ bool assert_main_thread();
+ //! Throws exception_wrong_thread if calling thread is not main app thread.
+ void ensure_main_thread();
+ //! Returns true if calling thread is main app thread, false otherwise.
+ bool is_main_thread();
+ //! Returns whether the app is currently shutting down.
+ bool is_shutting_down();
+ //! Returns whether the app is currently initializing.
+ bool is_initializing();
+ //! Returns filesystem path to directory with user settings, e.g. file://c:\documents_and_settings\username\blah\foobar2000
+ const char * get_profile_path();
+};
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/coreversion.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/coreversion.h
new file mode 100644
index 0000000..38436a6
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/coreversion.h
@@ -0,0 +1,25 @@
+#ifndef _COREVERSION_H_
+#define _COREVERSION_H_
+
+class NOVTABLE core_version_info : public service_base {
+public:
+ virtual const char * get_version_string() = 0;
+ static const char * g_get_version_string() {return static_api_ptr_t<core_version_info>()->get_version_string();}
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(core_version_info);
+};
+
+struct t_core_version_data {
+ t_uint32 m_major, m_minor1, m_minor2, m_minor3;
+};
+
+//! New (0.9.4.2)
+class NOVTABLE core_version_info_v2 : public core_version_info {
+public:
+ virtual const char * get_name() = 0;//"foobar2000"
+ virtual const char * get_version_as_text() = 0;//"N.N.N.N"
+ virtual t_core_version_data get_version() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(core_version_info_v2, core_version_info);
+};
+
+#endif //_COREVERSION_H_
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp.cpp
new file mode 100644
index 0000000..d7b39d5
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp.cpp
@@ -0,0 +1,395 @@
+#include "foobar2000.h"
+#include <math.h>
+
+t_size dsp_chunk_list_impl::get_count() const {return m_data.get_count();}
+
+audio_chunk * dsp_chunk_list_impl::get_item(t_size n) const {return n>=0 && n<m_data.get_count() ? &*m_data[n] : 0;}
+
+void dsp_chunk_list_impl::remove_by_idx(t_size idx)
+{
+ if (idx>=0 && idx<m_data.get_count())
+ m_recycled.add_item(m_data.remove_by_idx(idx));
+}
+
+void dsp_chunk_list_impl::remove_mask(const bit_array & mask)
+{
+ t_size n, m = m_data.get_count();
+ for(n=0;n<m;n++)
+ if (mask[m])
+ m_recycled.add_item(m_data[n]);
+ m_data.remove_mask(mask);
+}
+
+audio_chunk * dsp_chunk_list_impl::insert_item(t_size idx,t_size hint_size)
+{
+ t_size max = get_count();
+ if (idx<0) idx=0;
+ else if (idx>max) idx = max;
+ pfc::rcptr_t<audio_chunk> ret;
+ if (m_recycled.get_count()>0)
+ {
+ t_size best;
+ if (hint_size>0)
+ {
+ best = 0;
+ t_size best_found = m_recycled[0]->get_data_size(), n, total = m_recycled.get_count();
+ for(n=1;n<total;n++)
+ {
+ if (best_found==hint_size) break;
+ t_size size = m_recycled[n]->get_data_size();
+ int delta_old = abs((int)best_found - (int)hint_size), delta_new = abs((int)size - (int)hint_size);
+ if (delta_new < delta_old)
+ {
+ best_found = size;
+ best = n;
+ }
+ }
+ }
+ else best = m_recycled.get_count()-1;
+
+ ret = m_recycled.remove_by_idx(best);
+ ret->set_sample_count(0);
+ ret->set_channels(0);
+ ret->set_srate(0);
+ }
+ else ret = pfc::rcnew_t<audio_chunk_impl>();
+ if (idx==max) m_data.add_item(ret);
+ else m_data.insert_item(ret,idx);
+ return &*ret;
+}
+
+void dsp_chunk_list::remove_bad_chunks()
+{
+ bool blah = false;
+ t_size idx;
+ for(idx=0;idx<get_count();)
+ {
+ audio_chunk * chunk = get_item(idx);
+ if (!chunk->is_valid())
+ {
+ chunk->reset();
+ remove_by_idx(idx);
+ blah = true;
+ }
+ else idx++;
+ }
+ if (blah) console::info("one or more bad chunks removed from dsp chunk list");
+}
+
+
+bool dsp_entry::g_instantiate(service_ptr_t<dsp> & p_out,const dsp_preset & p_preset)
+{
+ service_ptr_t<dsp_entry> ptr;
+ if (!g_get_interface(ptr,p_preset.get_owner())) return false;
+ return ptr->instantiate(p_out,p_preset);
+}
+
+bool dsp_entry::g_instantiate_default(service_ptr_t<dsp> & p_out,const GUID & p_guid)
+{
+ service_ptr_t<dsp_entry> ptr;
+ if (!g_get_interface(ptr,p_guid)) return false;
+ dsp_preset_impl preset;
+ if (!ptr->get_default_preset(preset)) return false;
+ return ptr->instantiate(p_out,preset);
+}
+
+bool dsp_entry::g_name_from_guid(pfc::string_base & p_out,const GUID & p_guid)
+{
+ service_ptr_t<dsp_entry> ptr;
+ if (!g_get_interface(ptr,p_guid)) return false;
+ ptr->get_name(p_out);
+ return true;
+}
+
+bool dsp_entry::g_dsp_exists(const GUID & p_guid)
+{
+ service_ptr_t<dsp_entry> blah;
+ return g_get_interface(blah,p_guid);
+}
+
+bool dsp_entry::g_get_default_preset(dsp_preset & p_out,const GUID & p_guid)
+{
+ service_ptr_t<dsp_entry> ptr;
+ if (!g_get_interface(ptr,p_guid)) return false;
+ return ptr->get_default_preset(p_out);
+}
+
+void dsp_chain_config::contents_to_stream(stream_writer * p_stream,abort_callback & p_abort) const {
+ t_size n, count = get_count();
+ p_stream->write_lendian_t(count,p_abort);
+ for(n=0;n<count;n++) {
+ get_item(n).contents_to_stream(p_stream,p_abort);
+ }
+}
+
+void dsp_chain_config::contents_from_stream(stream_reader * p_stream,abort_callback & p_abort) {
+ t_uint32 n,count;
+
+ remove_all();
+
+ p_stream->read_lendian_t(count,p_abort);
+
+ dsp_preset_impl temp;
+
+ for(n=0;n<count;n++) {
+ temp.contents_from_stream(p_stream,p_abort);
+ add_item(temp);
+ }
+}
+
+
+bool cfg_dsp_chain_config::get_data(dsp_chain_config & p_data) const {
+ p_data.copy(m_data);
+ return true;
+}
+
+void cfg_dsp_chain_config::set_data(const dsp_chain_config & p_data) {
+ m_data.copy(p_data);
+}
+
+void cfg_dsp_chain_config::reset() {
+ m_data.remove_all();
+}
+
+void cfg_dsp_chain_config::get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {
+ m_data.contents_to_stream(p_stream,p_abort);
+}
+
+void cfg_dsp_chain_config::set_data_raw(stream_reader * p_stream,t_size,abort_callback & p_abort) {
+ m_data.contents_from_stream(p_stream,p_abort);
+}
+
+void dsp_chain_config::remove_item(t_size p_index)
+{
+ remove_mask(bit_array_one(p_index));
+}
+
+void dsp_chain_config::add_item(const dsp_preset & p_data)
+{
+ insert_item(p_data,get_count());
+}
+
+void dsp_chain_config::remove_all()
+{
+ remove_mask(bit_array_true());
+}
+
+void dsp_chain_config::instantiate(service_list_t<dsp> & p_out)
+{
+ p_out.remove_all();
+ t_size n, m = get_count();
+ for(n=0;n<m;n++)
+ {
+ service_ptr_t<dsp> temp;
+ if (dsp_entry::g_instantiate(temp,get_item(n)))
+ p_out.add_item(temp);
+ }
+}
+
+t_size dsp_chain_config_impl::get_count() const
+{
+ return m_data.get_count();
+}
+
+const dsp_preset & dsp_chain_config_impl::get_item(t_size p_index) const
+{
+ return *m_data[p_index];
+}
+
+void dsp_chain_config_impl::replace_item(const dsp_preset & p_data,t_size p_index)
+{
+ *m_data[p_index] = p_data;
+}
+
+void dsp_chain_config_impl::insert_item(const dsp_preset & p_data,t_size p_index)
+{
+ m_data.insert_item(new dsp_preset_impl(p_data),p_index);
+}
+
+void dsp_chain_config_impl::remove_mask(const bit_array & p_mask)
+{
+ m_data.delete_mask(p_mask);
+}
+
+dsp_chain_config_impl::~dsp_chain_config_impl()
+{
+ m_data.delete_all();
+}
+
+void dsp_preset::contents_to_stream(stream_writer * p_stream,abort_callback & p_abort) const {
+ t_size size = get_data_size();
+ p_stream->write_lendian_t(get_owner(),p_abort);
+ p_stream->write_lendian_t(size,p_abort);
+ if (size > 0) {
+ p_stream->write_object(get_data(),size,p_abort);
+ }
+}
+
+void dsp_preset::contents_from_stream(stream_reader * p_stream,abort_callback & p_abort) {
+ t_uint32 size;
+ GUID guid;
+ p_stream->read_lendian_t(guid,p_abort);
+ set_owner(guid);
+ p_stream->read_lendian_t(size,p_abort);
+ if (size > 1024*1024*32) throw exception_io_data();
+ set_data_from_stream(p_stream,size,p_abort);
+}
+
+void dsp_preset::g_contents_from_stream_skip(stream_reader * p_stream,abort_callback & p_abort) {
+ t_uint32 size;
+ GUID guid;
+ p_stream->read_lendian_t(guid,p_abort);
+ p_stream->read_lendian_t(size,p_abort);
+ if (size > 1024*1024*32) throw exception_io_data();
+ p_stream->skip_object(size,p_abort);
+}
+
+void dsp_preset_impl::set_data_from_stream(stream_reader * p_stream,t_size p_bytes,abort_callback & p_abort) {
+ m_data.set_size(p_bytes);
+ if (p_bytes > 0) p_stream->read_object(m_data.get_ptr(),p_bytes,p_abort);
+}
+
+void dsp_chain_config::copy(const dsp_chain_config & p_source) {
+ remove_all();
+ t_size n, m = p_source.get_count();
+ for(n=0;n<m;n++)
+ add_item(p_source.get_item(n));
+}
+
+bool dsp_entry::g_have_config_popup(const GUID & p_guid)
+{
+ service_ptr_t<dsp_entry> entry;
+ if (!g_get_interface(entry,p_guid)) return false;
+ return entry->have_config_popup();
+}
+
+bool dsp_entry::g_have_config_popup(const dsp_preset & p_preset)
+{
+ return g_have_config_popup(p_preset.get_owner());
+}
+
+bool dsp_entry::g_show_config_popup(dsp_preset & p_preset,HWND p_parent)
+{
+ service_ptr_t<dsp_entry> entry;
+ if (!g_get_interface(entry,p_preset.get_owner())) return false;
+ return entry->show_config_popup(p_preset,p_parent);
+}
+
+void dsp_entry::g_show_config_popup_v2(const dsp_preset & p_preset,HWND p_parent,dsp_preset_edit_callback & p_callback) {
+ service_ptr_t<dsp_entry> entry;
+ if (g_get_interface(entry,p_preset.get_owner())) {
+ service_ptr_t<dsp_entry_v2> entry_v2;
+ if (entry->service_query_t(entry_v2)) {
+ entry_v2->show_config_popup_v2(p_preset,p_parent,p_callback);
+ } else {
+ dsp_preset_impl temp(p_preset);
+ if (entry->show_config_popup(temp,p_parent)) p_callback.on_preset_changed(temp);
+ }
+ }
+}
+
+bool dsp_entry::g_get_interface(service_ptr_t<dsp_entry> & p_out,const GUID & p_guid)
+{
+ service_ptr_t<dsp_entry> ptr;
+ service_enum_t<dsp_entry> e;
+ e.reset();
+ while(e.next(ptr))
+ {
+ if (ptr->get_guid() == p_guid)
+ {
+ p_out = ptr;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool resampler_entry::g_get_interface(service_ptr_t<resampler_entry> & p_out,unsigned p_srate_from,unsigned p_srate_to)
+{
+ service_ptr_t<dsp_entry> ptr_dsp;
+ service_ptr_t<resampler_entry> ptr_resampler;
+ service_enum_t<dsp_entry> e;
+ e.reset();
+ float found_priority = 0;
+ service_ptr_t<resampler_entry> found;
+ while(e.next(ptr_dsp))
+ {
+ if (ptr_dsp->service_query_t(ptr_resampler))
+ {
+ if (p_srate_from == 0 || ptr_resampler->is_conversion_supported(p_srate_from,p_srate_to))
+ {
+ float priority = ptr_resampler->get_priority();
+ if (found.is_empty() || priority > found_priority)
+ {
+ found = ptr_resampler;
+ found_priority = priority;
+ }
+ }
+ }
+ }
+ if (found.is_empty()) return false;
+ p_out = found;
+ return true;
+}
+
+bool resampler_entry::g_create_preset(dsp_preset & p_out,unsigned p_srate_from,unsigned p_srate_to,float p_qualityscale)
+{
+ service_ptr_t<resampler_entry> entry;
+ if (!g_get_interface(entry,p_srate_from,p_srate_to)) return false;
+ return entry->create_preset(p_out,p_srate_to,p_qualityscale);
+}
+
+bool resampler_entry::g_create(service_ptr_t<dsp> & p_out,unsigned p_srate_from,unsigned p_srate_to,float p_qualityscale)
+{
+ service_ptr_t<resampler_entry> entry;
+ if (!g_get_interface(entry,p_srate_from,p_srate_to)) return false;
+ dsp_preset_impl preset;
+ if (!entry->create_preset(preset,p_srate_to,p_qualityscale)) return false;
+ return entry->instantiate(p_out,preset);
+}
+
+
+void dsp_chain_config::get_name_list(pfc::string_base & p_out) const
+{
+ const t_size count = get_count();
+ bool added = false;
+ for(unsigned n=0;n<count;n++)
+ {
+ service_ptr_t<dsp_entry> ptr;
+ if (dsp_entry::g_get_interface(ptr,get_item(n).get_owner()))
+ {
+ if (added) p_out += ", ";
+ added = true;
+
+ pfc::string8 temp;
+ ptr->get_name(temp);
+ p_out += temp;
+ }
+ }
+}
+
+void dsp::run_abortable(dsp_chunk_list * p_chunk_list,const metadb_handle_ptr & p_cur_file,int p_flags,abort_callback & p_abort) {
+ service_ptr_t<dsp_v2> this_v2;
+ if (this->service_query_t(this_v2)) this_v2->run_v2(p_chunk_list,p_cur_file,p_flags,p_abort);
+ else run(p_chunk_list,p_cur_file,p_flags);
+}
+
+namespace {
+ class dsp_preset_edit_callback_impl : public dsp_preset_edit_callback {
+ public:
+ dsp_preset_edit_callback_impl(dsp_preset & p_data) : m_data(p_data) {}
+ void on_preset_changed(const dsp_preset & p_data) {m_data = p_data;}
+ private:
+ dsp_preset & m_data;
+ };
+};
+
+bool dsp_entry_v2::show_config_popup(dsp_preset & p_data,HWND p_parent) {
+ PFC_ASSERT(p_data.get_owner() == get_guid());
+ dsp_preset_impl temp(p_data);
+ show_config_popup_v2(p_data,p_parent,dsp_preset_edit_callback_impl(temp));
+ PFC_ASSERT(temp.get_owner() == get_guid());
+ if (temp == p_data) return false;
+ p_data = temp;
+ return true;
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp.h
new file mode 100644
index 0000000..07a617d
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp.h
@@ -0,0 +1,435 @@
+class NOVTABLE dsp_chunk_list {
+public:
+ virtual t_size get_count() const = 0;
+ virtual audio_chunk * get_item(t_size n) const = 0;
+ virtual void remove_by_idx(t_size idx) = 0;
+ virtual void remove_mask(const bit_array & mask) = 0;
+ virtual audio_chunk * insert_item(t_size idx,t_size hint_size=0) = 0;
+
+ audio_chunk * add_item(t_size hint_size=0) {return insert_item(get_count(),hint_size);}
+
+ void remove_all() {remove_mask(bit_array_true());}
+
+ double get_duration() {
+ double rv = 0;
+ t_size n,m = get_count();
+ for(n=0;n<m;n++) rv += get_item(n)->get_duration();
+ return rv;
+ }
+
+ void add_chunk(const audio_chunk * chunk) {
+ audio_chunk * dst = insert_item(get_count(),chunk->get_data_length());
+ if (dst) dst->copy(*chunk);
+ }
+
+ void remove_bad_chunks();
+protected:
+ dsp_chunk_list() {}
+ ~dsp_chunk_list() {}
+};
+
+class dsp_chunk_list_impl : public dsp_chunk_list//implementation
+{
+ pfc::list_t<pfc::rcptr_t<audio_chunk> > m_data, m_recycled;
+public:
+ t_size get_count() const;
+ audio_chunk * get_item(t_size n) const;
+ void remove_by_idx(t_size idx);
+ void remove_mask(const bit_array & mask);
+ audio_chunk * insert_item(t_size idx,t_size hint_size=0);
+};
+
+//! Instance of a DSP.\n
+//! Implementation: Derive from dsp_impl_base instead of deriving from dsp directly.\n
+//! Instantiation: Use dsp_entry static helper methods to instantiate DSPs, or dsp_chain_config / dsp_manager to deal with entire DSP chains.
+class NOVTABLE dsp : public service_base {
+public:
+ enum {
+ //! Flush whatever you need to when tracks change.
+ END_OF_TRACK = 1,
+ //! Flush everything.
+ FLUSH = 2
+ };
+
+ //! @param p_chunk_list List of chunks to process. The implementation may alter the list in any way, inserting chunks of different sample rate / channel configuration etc.
+ //! @param p_cur_file Optional, location of currently decoded file. May be null.
+ //! @param p_flags Flags. Can be null, or a combination of END_OF_TRACK and FLUSH constants.
+ virtual void run(dsp_chunk_list * p_chunk_list,const metadb_handle_ptr & p_cur_file,int p_flags)=0;
+
+ //! Flushes the DSP (reinitializes / drops any buffered data). Called after seeking, etc.
+ virtual void flush() = 0;
+
+ //! Retrieves amount of data buffered by the DSP, for syncing visualisation.
+ //! @returns Amount of buffered audio data, in seconds.
+ virtual double get_latency() = 0;
+ //! Returns true if DSP needs to know exact track change point (eg. for crossfading, removing silence).\n
+ //! Signaling this will force-flush any DSPs placed before this DSP so when it gets END_OF_TRACK, relevant chunks contain last samples of the track.\n
+ //! Signaling this will often break regular gapless playback so don't use it unless you have reasons to.
+ virtual bool need_track_change_mark() = 0;
+
+ void run_abortable(dsp_chunk_list * p_chunk_list,const metadb_handle_ptr & p_cur_file,int p_flags,abort_callback & p_abort);
+
+ FB2K_MAKE_SERVICE_INTERFACE(dsp,service_base);
+};
+
+//! Backwards-compatible extension to dsp interface, allows abortable operation. Introduced in 0.9.2.
+class NOVTABLE dsp_v2 : public dsp {
+public:
+ //! Abortable version of dsp::run(). See dsp::run() for descriptions of parameters.
+ virtual void run_v2(dsp_chunk_list * p_chunk_list,const metadb_handle_ptr & p_cur_file,int p_flags,abort_callback & p_abort) = 0;
+private:
+ void run(dsp_chunk_list * p_chunk_list,const metadb_handle_ptr & p_cur_file,int p_flags) {
+ run_v2(p_chunk_list,p_cur_file,p_flags,abort_callback_impl());
+ }
+
+ FB2K_MAKE_SERVICE_INTERFACE(dsp_v2,dsp);
+};
+
+//! Helper class for implementing dsps. You should derive from dsp_impl_base instead of from dsp directly.\n
+//! The dsp_impl_base_t template allows you to use a custom interface class as a base class for your implementation, in case you provide extended functionality.\n
+//! Use dsp_factory_t<> template to register your dsp implementation.
+//! The implementation - as required by dsp_factory_t<> template - must also provide following methods:\n
+//! A constructor taking const dsp_preset&, initializing the DSP with specified preset data.\n
+//! static void g_get_name(pfc::string_base &); - retrieving human-readable name of the DSP to display.\n
+//! static bool g_get_default_preset(dsp_preset &); - retrieving default preset for this DSP. Return value is reserved for future use and should always be true.\n
+//! static GUID g_get_guid(); - retrieving GUID of your DSP implementation, to be used to identify it when storing DSP chain configuration.\n
+//! static bool g_have_config_popup(); - retrieving whether your DSP implementation supplies a popup dialog for configuring it.\n
+//! static void g_show_config_popup(const dsp_preset & p_data,HWND p_parent, dsp_preset_edit_callback & p_callback); - displaying your DSP's settings dialog; called only when g_have_config_popup() returns true; call p_callback.on_preset_changed() whenever user has made adjustments to the preset data.\n
+template<class t_baseclass>
+class dsp_impl_base_t : public t_baseclass {
+private:
+ typedef dsp_impl_base_t<t_baseclass> t_self;
+ dsp_chunk_list * m_list;
+ t_size m_chunk_ptr;
+ metadb_handle* m_cur_file;
+ void run_v2(dsp_chunk_list * p_list,const metadb_handle_ptr & p_cur_file,int p_flags,abort_callback & p_abort);
+protected:
+ bool get_cur_file(metadb_handle_ptr & p_out) {p_out = m_cur_file; return p_out.is_valid();}// call only from on_chunk / on_endoftrack (on_endoftrack will give info on track being finished); may return null !!
+
+ dsp_impl_base_t() : m_list(NULL), m_cur_file(NULL), m_chunk_ptr(0) {}
+
+ audio_chunk * insert_chunk(t_size p_hint_size = 0) //call only from on_endoftrack / on_endofplayback / on_chunk
+ {//hint_size - optional, amout of buffer space you want to use
+ PFC_ASSERT(m_list != NULL);
+ return m_list->insert_item(m_chunk_ptr++,p_hint_size);
+ }
+
+
+ //! To be overridden by a DSP implementation.\n
+ //! Called on track change. You can use insert_chunk() to dump any data you have to flush. \n
+ //! Note that you must implement need_track_change_mark() to return true if you need this method called.
+ virtual void on_endoftrack(abort_callback & p_abort) = 0;
+ //! To be overridden by a DSP implementation.\n
+ //! Called at the end of played stream, typically at the end of last played track, to allow the DSP to return all data it has buffered-ahead.\n
+ //! Use insert_chunk() to return any data you have buffered.\n
+ //! Note that this call does not imply that the DSP will be destroyed next. \n
+ //! This is also called on track changes if some DSP placed after your DSP requests track change marks.
+ virtual void on_endofplayback(abort_callback & p_abort) = 0;
+ //! To be overridden by a DSP implementation.\n
+ //! Processes a chunk of audio data.\n
+ //! You can call insert_chunk() from inside on_chunk() to insert any audio data before currently processed chunk.\n
+ //! @param p_chunk Current chunk being processed. You can alter it in any way you like.
+ //! @returns True to keep p_chunk (with alterations made inside on_chunk()) in the stream, false to remove it.
+ virtual bool on_chunk(audio_chunk * p_chunk,abort_callback & p_abort) = 0;
+
+public:
+ //! To be overridden by a DSP implementation.\n
+ //! Flushes the DSP (reinitializes / drops any buffered data). Called after seeking, etc.
+ virtual void flush() = 0;
+ //! To be overridden by a DSP implementation.\n
+ //! Retrieves amount of data buffered by the DSP, for syncing visualisation.
+ //! @returns Amount of buffered audio data, in seconds.
+ virtual double get_latency() = 0;
+ //! To be overridden by a DSP implementation.\n
+ //! Returns true if DSP needs to know exact track change point (eg. for crossfading, removing silence).\n
+ //! Signaling this will force-flush any DSPs placed before this DSP so when it gets on_endoftrack(), relevant chunks contain last samples of the track.\n
+ //! Signaling this may interfere with gapless playback in certain scenarios (forces flush of DSPs placed before you) so don't use it unless you have reasons to.
+ virtual bool need_track_change_mark() = 0;
+private:
+ dsp_impl_base_t(const t_self&) {throw pfc::exception_bug_check();}
+ const t_self & operator=(const t_self &) {throw pfc::exception_bug_check();}
+};
+
+template<class t_baseclass>
+void dsp_impl_base_t<t_baseclass>::run_v2(dsp_chunk_list * p_list,const metadb_handle_ptr & p_cur_file,int p_flags,abort_callback & p_abort) {
+ pfc::vartoggle_t<dsp_chunk_list*> l_list_toggle(m_list,p_list);
+ pfc::vartoggle_t<metadb_handle*> l_cur_file_toggle(m_cur_file,p_cur_file.get_ptr());
+
+ for(m_chunk_ptr = 0;m_chunk_ptr<m_list->get_count();m_chunk_ptr++) {
+ audio_chunk * c = m_list->get_item(m_chunk_ptr);
+ if (c->is_empty() || !on_chunk(c,p_abort))
+ m_list->remove_by_idx(m_chunk_ptr--);
+ }
+
+ if (p_flags & FLUSH) {
+ on_endofplayback(p_abort);
+ } else if (p_flags & END_OF_TRACK) {
+ if (need_track_change_mark()) on_endoftrack(p_abort);
+ }
+}
+
+
+typedef dsp_impl_base_t<dsp_v2> dsp_impl_base;
+
+class NOVTABLE dsp_preset {
+public:
+ virtual GUID get_owner() const = 0;
+ virtual void set_owner(const GUID & p_owner) = 0;
+ virtual const void * get_data() const = 0;
+ virtual t_size get_data_size() const = 0;
+ virtual void set_data(const void * p_data,t_size p_data_size) = 0;
+ virtual void set_data_from_stream(stream_reader * p_stream,t_size p_bytes,abort_callback & p_abort) = 0;
+
+ const dsp_preset & operator=(const dsp_preset & p_source) {copy(p_source); return *this;}
+
+ void copy(const dsp_preset & p_source) {set_owner(p_source.get_owner());set_data(p_source.get_data(),p_source.get_data_size());}
+
+ void contents_to_stream(stream_writer * p_stream,abort_callback & p_abort) const;
+ void contents_from_stream(stream_reader * p_stream,abort_callback & p_abort);
+ static void g_contents_from_stream_skip(stream_reader * p_stream,abort_callback & p_abort);
+
+ bool operator==(const dsp_preset & p_other) const {
+ if (get_owner() != p_other.get_owner()) return false;
+ if (get_data_size() != p_other.get_data_size()) return false;
+ if (memcmp(get_data(),p_other.get_data(),get_data_size()) != 0) return false;
+ return true;
+ }
+ bool operator!=(const dsp_preset & p_other) const {
+ return !(*this == p_other);
+ }
+protected:
+ dsp_preset() {}
+ ~dsp_preset() {}
+};
+
+class dsp_preset_writer : public stream_writer {
+public:
+ void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ p_abort.check();
+ m_data.append_fromptr((const t_uint8 *) p_buffer,p_bytes);
+ }
+ void flush(dsp_preset & p_preset) {
+ p_preset.set_data(m_data.get_ptr(),m_data.get_size());
+ m_data.set_size(0);
+ }
+private:
+ pfc::array_t<t_uint8,pfc::alloc_fast_aggressive> m_data;
+};
+
+class dsp_preset_reader : public stream_reader {
+public:
+ dsp_preset_reader() : m_walk(0) {}
+ dsp_preset_reader(const dsp_preset_reader & p_source) : m_walk(0) {*this = p_source;}
+ void init(const dsp_preset & p_preset) {
+ m_data.set_data_fromptr( (const t_uint8*) p_preset.get_data(), p_preset.get_data_size() );
+ m_walk = 0;
+ }
+ t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ p_abort.check();
+ t_size todo = pfc::min_t<t_size>(p_bytes,m_data.get_size()-m_walk);
+ memcpy(p_buffer,m_data.get_ptr()+m_walk,todo);
+ m_walk += todo;
+ return todo;
+ }
+ bool is_finished() {return m_walk == m_data.get_size();}
+private:
+ t_size m_walk;
+ pfc::array_t<t_uint8> m_data;
+};
+
+class dsp_preset_impl : public dsp_preset
+{
+public:
+ dsp_preset_impl() {}
+ dsp_preset_impl(const dsp_preset_impl & p_source) {copy(p_source);}
+ dsp_preset_impl(const dsp_preset & p_source) {copy(p_source);}
+
+ const dsp_preset_impl& operator=(const dsp_preset_impl & p_source) {copy(p_source); return *this;}
+ const dsp_preset_impl& operator=(const dsp_preset & p_source) {copy(p_source); return *this;}
+
+ GUID get_owner() const {return m_owner;}
+ void set_owner(const GUID & p_owner) {m_owner = p_owner;}
+ const void * get_data() const {return m_data.get_ptr();}
+ t_size get_data_size() const {return m_data.get_size();}
+ void set_data(const void * p_data,t_size p_data_size) {m_data.set_data_fromptr((const t_uint8*)p_data,p_data_size);}
+ void set_data_from_stream(stream_reader * p_stream,t_size p_bytes,abort_callback & p_abort);
+private:
+ GUID m_owner;
+ pfc::array_t<t_uint8> m_data;
+};
+
+class NOVTABLE dsp_preset_edit_callback {
+public:
+ virtual void on_preset_changed(const dsp_preset &) = 0;
+private:
+ dsp_preset_edit_callback(const dsp_preset_edit_callback&) {throw pfc::exception_not_implemented();}
+ const dsp_preset_edit_callback & operator=(const dsp_preset_edit_callback &) {throw pfc::exception_not_implemented();}
+protected:
+ dsp_preset_edit_callback() {}
+ ~dsp_preset_edit_callback() {}
+};
+
+class NOVTABLE dsp_entry : public service_base {
+public:
+ virtual void get_name(pfc::string_base & p_out) = 0;
+ virtual bool get_default_preset(dsp_preset & p_out) = 0;
+ virtual bool instantiate(service_ptr_t<dsp> & p_out,const dsp_preset & p_preset) = 0;
+ virtual GUID get_guid() = 0;
+ virtual bool have_config_popup() = 0;
+ virtual bool show_config_popup(dsp_preset & p_data,HWND p_parent) = 0;
+
+
+ static bool g_get_interface(service_ptr_t<dsp_entry> & p_out,const GUID & p_guid);
+ static bool g_instantiate(service_ptr_t<dsp> & p_out,const dsp_preset & p_preset);
+ static bool g_instantiate_default(service_ptr_t<dsp> & p_out,const GUID & p_guid);
+ static bool g_name_from_guid(pfc::string_base & p_out,const GUID & p_guid);
+ static bool g_dsp_exists(const GUID & p_guid);
+ static bool g_get_default_preset(dsp_preset & p_out,const GUID & p_guid);
+ static bool g_have_config_popup(const GUID & p_guid);
+ static bool g_have_config_popup(const dsp_preset & p_preset);
+ static bool g_show_config_popup(dsp_preset & p_preset,HWND p_parent);
+
+ static void g_show_config_popup_v2(const dsp_preset & p_preset,HWND p_parent,dsp_preset_edit_callback & p_callback);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(dsp_entry);
+};
+
+class NOVTABLE dsp_entry_v2 : public dsp_entry {
+public:
+ virtual void show_config_popup_v2(const dsp_preset & p_data,HWND p_parent,dsp_preset_edit_callback & p_callback) = 0;
+
+private:
+ bool show_config_popup(dsp_preset & p_data,HWND p_parent);
+
+ FB2K_MAKE_SERVICE_INTERFACE(dsp_entry_v2,dsp_entry);
+};
+
+template<class T,class t_entry = dsp_entry>
+class dsp_entry_impl_nopreset_t : public t_entry {
+public:
+ void get_name(pfc::string_base & p_out) {T::g_get_name(p_out);}
+ bool get_default_preset(dsp_preset & p_out)
+ {
+ p_out.set_owner(T::g_get_guid());
+ p_out.set_data(0,0);
+ return true;
+ }
+ bool instantiate(service_ptr_t<dsp> & p_out,const dsp_preset & p_preset)
+ {
+ if (p_preset.get_owner() == T::g_get_guid() && p_preset.get_data_size() == 0)
+ {
+ p_out = new service_impl_t<T>();
+ return p_out.is_valid();
+ }
+ else return false;
+ }
+ GUID get_guid() {return T::g_get_guid();}
+
+ bool have_config_popup() {return false;}
+ bool show_config_popup(dsp_preset & p_data,HWND p_parent) {return false;}
+};
+
+template<class T, class t_entry = dsp_entry_v2>
+class dsp_entry_impl_t : public t_entry {
+public:
+ void get_name(pfc::string_base & p_out) {T::g_get_name(p_out);}
+ bool get_default_preset(dsp_preset & p_out) {return T::g_get_default_preset(p_out);}
+ bool instantiate(service_ptr_t<dsp> & p_out,const dsp_preset & p_preset) {
+ if (p_preset.get_owner() == T::g_get_guid()) {
+ p_out = new service_impl_t<T>(p_preset);
+ return true;
+ }
+ else return false;
+ }
+ GUID get_guid() {return T::g_get_guid();}
+
+ bool have_config_popup() {return T::g_have_config_popup();}
+ bool show_config_popup(dsp_preset & p_data,HWND p_parent) {return T::g_show_config_popup(p_data,p_parent);}
+ //void show_config_popup_v2(const dsp_preset & p_data,HWND p_parent,dsp_preset_edit_callback & p_callback) {T::g_show_config_popup(p_data,p_parent,p_callback);}
+};
+
+template<class T, class t_entry = dsp_entry_v2>
+class dsp_entry_v2_impl_t : public t_entry {
+public:
+ void get_name(pfc::string_base & p_out) {T::g_get_name(p_out);}
+ bool get_default_preset(dsp_preset & p_out) {return T::g_get_default_preset(p_out);}
+ bool instantiate(service_ptr_t<dsp> & p_out,const dsp_preset & p_preset) {
+ if (p_preset.get_owner() == T::g_get_guid()) {
+ p_out = new service_impl_t<T>(p_preset);
+ return true;
+ }
+ else return false;
+ }
+ GUID get_guid() {return T::g_get_guid();}
+
+ bool have_config_popup() {return T::g_have_config_popup();}
+ //bool show_config_popup(dsp_preset & p_data,HWND p_parent) {return T::g_show_config_popup(p_data,p_parent);}
+ void show_config_popup_v2(const dsp_preset & p_data,HWND p_parent,dsp_preset_edit_callback & p_callback) {T::g_show_config_popup(p_data,p_parent,p_callback);}
+};
+
+
+template<class T>
+class dsp_factory_nopreset_t : public service_factory_single_t<dsp_entry_impl_nopreset_t<T> > {};
+
+template<class T>
+class dsp_factory_t : public service_factory_single_t<dsp_entry_v2_impl_t<T> > {};
+
+class NOVTABLE dsp_chain_config
+{
+public:
+ virtual t_size get_count() const = 0;
+ virtual const dsp_preset & get_item(t_size p_index) const = 0;
+ virtual void replace_item(const dsp_preset & p_data,t_size p_index) = 0;
+ virtual void insert_item(const dsp_preset & p_data,t_size p_index) = 0;
+ virtual void remove_mask(const bit_array & p_mask) = 0;
+
+ void remove_item(t_size p_index);
+ void remove_all();
+ void add_item(const dsp_preset & p_data);
+ void copy(const dsp_chain_config & p_source);
+
+ const dsp_chain_config & operator=(const dsp_chain_config & p_source) {copy(p_source); return *this;}
+
+ void contents_to_stream(stream_writer * p_stream,abort_callback & p_abort) const;
+ void contents_from_stream(stream_reader * p_stream,abort_callback & p_abort);
+
+ void instantiate(service_list_t<dsp> & p_out);
+
+ void get_name_list(pfc::string_base & p_out) const;
+};
+
+class dsp_chain_config_impl : public dsp_chain_config
+{
+public:
+ dsp_chain_config_impl() {}
+ dsp_chain_config_impl(const dsp_chain_config & p_source) {copy(p_source);}
+ dsp_chain_config_impl(const dsp_chain_config_impl & p_source) {copy(p_source);}
+ t_size get_count() const;
+ const dsp_preset & get_item(t_size p_index) const;
+ void replace_item(const dsp_preset & p_data,t_size p_index);
+ void insert_item(const dsp_preset & p_data,t_size p_index);
+ void remove_mask(const bit_array & p_mask);
+
+ const dsp_chain_config_impl & operator=(const dsp_chain_config & p_source) {copy(p_source); return *this;}
+ const dsp_chain_config_impl & operator=(const dsp_chain_config_impl & p_source) {copy(p_source); return *this;}
+
+ ~dsp_chain_config_impl();
+private:
+ pfc::ptr_list_t<dsp_preset_impl> m_data;
+};
+
+class cfg_dsp_chain_config : public cfg_var {
+protected:
+ void get_data_raw(stream_writer * p_stream,abort_callback & p_abort);
+ void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort);
+public:
+ void reset();
+ inline cfg_dsp_chain_config(const GUID & p_guid) : cfg_var(p_guid) {}
+ t_size get_count() const {return m_data.get_count();}
+ const dsp_preset & get_item(t_size p_index) const {return m_data.get_item(p_index);}
+ bool get_data(dsp_chain_config & p_data) const;
+ void set_data(const dsp_chain_config & p_data);
+private:
+ dsp_chain_config_impl m_data;
+
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp_manager.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp_manager.cpp
new file mode 100644
index 0000000..fc36489
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp_manager.cpp
@@ -0,0 +1,137 @@
+#include "foobar2000.h"
+
+void dsp_manager::close() {
+ m_chain.remove_all();
+ m_config_changed = true;
+}
+
+void dsp_manager::set_config( const dsp_chain_config & p_data )
+{
+ //dsp_chain_config::g_instantiate(m_dsp_list,p_data);
+ m_config.copy(p_data);
+ m_config_changed = true;
+}
+
+void dsp_manager::dsp_run(t_dsp_chain::const_iterator p_iter,dsp_chunk_list * p_list,const metadb_handle_ptr & cur_file,unsigned flags,double & latency,abort_callback & p_abort)
+{
+ p_list->remove_bad_chunks();
+
+ TRACK_CODE("dsp::run",p_iter->m_dsp->run_abortable(p_list,cur_file,flags,p_abort));
+ TRACK_CODE("dsp::get_latency",latency += p_iter->m_dsp->get_latency());
+}
+
+double dsp_manager::run(dsp_chunk_list * p_list,const metadb_handle_ptr & p_cur_file,unsigned p_flags,abort_callback & p_abort) {
+ TRACK_CALL_TEXT("dsp_manager::run");
+
+ try {
+ fpu_control_default l_fpu_control;
+
+ double latency=0;
+ bool done = false;
+
+ t_dsp_chain::const_iterator flush_mark;
+ if ((p_flags & dsp::END_OF_TRACK) && ! (p_flags & dsp::FLUSH)) {
+ for(t_dsp_chain::const_iterator iter = m_chain.first(); iter.is_valid(); ++iter) {
+ if (iter->m_dsp->need_track_change_mark()) flush_mark = iter;
+ }
+ }
+
+ if (m_config_changed)
+ {
+ t_dsp_chain newchain;
+ bool recycle_available = true;
+
+ for(t_size n=0;n<m_config.get_count();n++) {
+ service_ptr_t<dsp> temp;
+
+ const dsp_preset & preset = m_config.get_item(n);
+ if (dsp_entry::g_dsp_exists(preset.get_owner())) {
+ t_dsp_chain::iterator iter = newchain.insert_last();
+ iter->m_preset = m_config.get_item(n);
+ iter->m_recycle_flag = false;
+ }
+ }
+
+
+ //HACK: recycle existing DSPs in a special case when user has apparently only altered settings of one of DSPs.
+ if (newchain.get_count() == m_chain.get_count()) {
+ t_size data_mismatch_count = 0;
+ t_size owner_mismatch_count = 0;
+ t_dsp_chain::iterator iter_src, iter_dst;
+ iter_src = m_chain.first(); iter_dst = newchain.first();
+ while(iter_src.is_valid() && iter_dst.is_valid()) {
+ if (iter_src->m_preset.get_owner() != iter_dst->m_preset.get_owner()) {
+ owner_mismatch_count++;
+ } else if (iter_src->m_preset != iter_dst->m_preset) {
+ data_mismatch_count++;
+ }
+ ++iter_src; ++iter_dst;
+ }
+ recycle_available = (owner_mismatch_count == 0 && data_mismatch_count <= 1);
+ } else {
+ recycle_available = false;
+ }
+
+ if (recycle_available) {
+ t_dsp_chain::iterator iter_src, iter_dst;
+ iter_src = m_chain.first(); iter_dst = newchain.first();
+ while(iter_src.is_valid() && iter_dst.is_valid()) {
+ if (iter_src->m_preset == iter_dst->m_preset) {
+ iter_src->m_recycle_flag = true;
+ iter_dst->m_dsp = iter_src->m_dsp;
+ }
+ ++iter_src; ++iter_dst;
+ }
+ }
+
+ for(t_dsp_chain::iterator iter = newchain.first(); iter.is_valid(); ++iter) {
+ if (iter->m_dsp.is_empty()) {
+ if (!dsp_entry::g_instantiate(iter->m_dsp,iter->m_preset)) throw pfc::exception_bug_check();
+ }
+ }
+
+ if (m_chain.get_count()>0) {
+ bool flushflag = flush_mark.is_valid();
+ for(t_dsp_chain::const_iterator iter = m_chain.first(); iter.is_valid(); ++iter) {
+ unsigned flags2 = p_flags;
+ if (iter == flush_mark) flushflag = false;
+ if (flushflag || !iter->m_recycle_flag) flags2|=dsp::FLUSH;
+ dsp_run(iter,p_list,p_cur_file,flags2,latency,p_abort);
+ }
+ done = true;
+ }
+
+ m_chain = newchain;
+ m_config_changed = false;
+ }
+
+ if (!done)
+ {
+ bool flushflag = flush_mark.is_valid();
+ for(t_dsp_chain::const_iterator iter = m_chain.first(); iter.is_valid(); ++iter) {
+ unsigned flags2 = p_flags;
+ if (iter == flush_mark) flushflag = false;
+ if (flushflag) flags2|=dsp::FLUSH;
+ dsp_run(iter,p_list,p_cur_file,flags2,latency,p_abort);
+ }
+ done = true;
+ }
+
+ p_list->remove_bad_chunks();
+
+ return latency;
+ } catch(...) {
+ p_list->remove_all();
+ throw;
+ }
+}
+
+void dsp_manager::flush()
+{
+ for(t_dsp_chain::const_iterator iter = m_chain.first(); iter.is_valid(); ++iter) {
+ TRACK_CODE("dsp::flush",iter->m_dsp->flush());
+ }
+}
+
+
+bool dsp_manager::is_active() {return m_config.get_count()>0;} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp_manager.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp_manager.h
new file mode 100644
index 0000000..e3405ac
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/dsp_manager.h
@@ -0,0 +1,52 @@
+struct t_dsp_chain_entry {
+ service_ptr_t<dsp> m_dsp;
+ dsp_preset_impl m_preset;
+ bool m_recycle_flag;
+};
+typedef pfc::chain_list_t<t_dsp_chain_entry> t_dsp_chain;
+
+class dsp_manager {
+public:
+ dsp_manager() : m_config_changed(false) {}
+
+ void set_config( const dsp_chain_config & p_data );
+ double run(dsp_chunk_list * p_list,const metadb_handle_ptr & p_cur_file,unsigned p_flags,abort_callback & p_abort);
+ void flush();
+ void close();
+
+ bool is_active();
+
+private:
+ t_dsp_chain m_chain;
+ dsp_chain_config_impl m_config;
+ bool m_config_changed;
+
+ void dsp_run(t_dsp_chain::const_iterator p_iter,dsp_chunk_list * list,const metadb_handle_ptr & cur_file,unsigned flags,double & latency,abort_callback&);
+
+ dsp_manager(const dsp_manager &) {throw pfc::exception_not_implemented();}
+ const dsp_manager & operator=(const dsp_manager&) {throw pfc::exception_not_implemented();}
+};
+
+
+class dsp_config_manager : public service_base
+{
+public:
+ virtual void get_core_settings(dsp_chain_config & p_out) = 0;
+ virtual void set_core_settings(const dsp_chain_config & p_data) = 0;
+
+ virtual bool configure_popup(dsp_chain_config & p_data,HWND p_parent,const char * p_title) = 0;
+
+ virtual HWND configure_embedded(const dsp_chain_config & p_initdata,HWND p_parent,unsigned p_id,bool p_from_modal) = 0;
+ virtual void configure_embedded_retrieve(HWND wnd,dsp_chain_config & p_data) = 0;
+ virtual void configure_embedded_change(HWND wnd,const dsp_chain_config & p_data) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(dsp_config_manager);
+};
+
+class NOVTABLE dsp_config_callback : public service_base
+{
+public:
+ virtual void on_core_settings_change(const dsp_chain_config & p_newdata) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(dsp_config_callback);
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info.cpp
new file mode 100644
index 0000000..2af249d
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info.cpp
@@ -0,0 +1,447 @@
+#include "foobar2000.h"
+
+t_size file_info::meta_find_ex(const char * p_name,t_size p_name_length) const
+{
+ t_size n, m = meta_get_count();
+ for(n=0;n<m;n++)
+ {
+ if (pfc::stricmp_ascii_ex(meta_enum_name(n),infinite,p_name,p_name_length) == 0) return n;
+ }
+ return infinite;
+}
+
+bool file_info::meta_exists_ex(const char * p_name,t_size p_name_length) const
+{
+ return meta_find_ex(p_name,p_name_length) != infinite;
+}
+
+void file_info::meta_remove_field_ex(const char * p_name,t_size p_name_length)
+{
+ t_size index = meta_find_ex(p_name,p_name_length);
+ if (index!=infinite) meta_remove_index(index);
+}
+
+
+void file_info::meta_remove_index(t_size p_index)
+{
+ meta_remove_mask(bit_array_one(p_index));
+}
+
+void file_info::meta_remove_all()
+{
+ meta_remove_mask(bit_array_true());
+}
+
+void file_info::meta_remove_value(t_size p_index,t_size p_value)
+{
+ meta_remove_values(p_index,bit_array_one(p_value));
+}
+
+t_size file_info::meta_get_count_by_name_ex(const char * p_name,t_size p_name_length) const
+{
+ t_size index = meta_find_ex(p_name,p_name_length);
+ if (index == infinite) return 0;
+ return meta_enum_value_count(index);
+}
+
+t_size file_info::info_find_ex(const char * p_name,t_size p_name_length) const
+{
+ t_size n, m = info_get_count();
+ for(n=0;n<m;n++) {
+ if (pfc::stricmp_ascii_ex(info_enum_name(n),infinite,p_name,p_name_length) == 0) return n;
+ }
+ return infinite;
+}
+
+bool file_info::info_exists_ex(const char * p_name,t_size p_name_length) const
+{
+ return info_find_ex(p_name,p_name_length) != infinite;
+}
+
+void file_info::info_remove_index(t_size p_index)
+{
+ info_remove_mask(bit_array_one(p_index));
+}
+
+void file_info::info_remove_all()
+{
+ info_remove_mask(bit_array_true());
+}
+
+bool file_info::info_remove_ex(const char * p_name,t_size p_name_length)
+{
+ t_size index = info_find_ex(p_name,p_name_length);
+ if (index != infinite)
+ {
+ info_remove_index(index);
+ return true;
+ }
+ else return false;
+}
+
+void file_info::copy_meta_single(const file_info & p_source,t_size p_index)
+{
+ copy_meta_single_rename(p_source,p_index,p_source.meta_enum_name(p_index));
+}
+
+void file_info::copy_meta_single_nocheck(const file_info & p_source,t_size p_index)
+{
+ const char * name = p_source.meta_enum_name(p_index);
+ t_size n, m = p_source.meta_enum_value_count(p_index);
+ t_size new_index = infinite;
+ for(n=0;n<m;n++)
+ {
+ const char * value = p_source.meta_enum_value(p_index,n);
+ if (n == 0) new_index = meta_set_nocheck(name,value);
+ else meta_add_value(new_index,value);
+ }
+}
+
+void file_info::copy_meta_single_by_name_ex(const file_info & p_source,const char * p_name,t_size p_name_length)
+{
+ t_size index = p_source.meta_find_ex(p_name,p_name_length);
+ if (index != infinite) copy_meta_single(p_source,index);
+}
+
+void file_info::copy_info_single_by_name_ex(const file_info & p_source,const char * p_name,t_size p_name_length)
+{
+ t_size index = p_source.info_find_ex(p_name,p_name_length);
+ if (index != infinite) copy_info_single(p_source,index);
+}
+
+void file_info::copy_meta_single_by_name_nocheck_ex(const file_info & p_source,const char * p_name,t_size p_name_length)
+{
+ t_size index = p_source.meta_find_ex(p_name,p_name_length);
+ if (index != infinite) copy_meta_single_nocheck(p_source,index);
+}
+
+void file_info::copy_info_single_by_name_nocheck_ex(const file_info & p_source,const char * p_name,t_size p_name_length)
+{
+ t_size index = p_source.info_find_ex(p_name,p_name_length);
+ if (index != infinite) copy_info_single_nocheck(p_source,index);
+}
+
+void file_info::copy_info_single(const file_info & p_source,t_size p_index)
+{
+ info_set(p_source.info_enum_name(p_index),p_source.info_enum_value(p_index));
+}
+
+void file_info::copy_info_single_nocheck(const file_info & p_source,t_size p_index)
+{
+ info_set_nocheck(p_source.info_enum_name(p_index),p_source.info_enum_value(p_index));
+}
+
+void file_info::copy_meta(const file_info & p_source)
+{
+ if (&p_source != this) {
+ meta_remove_all();
+ t_size n, m = p_source.meta_get_count();
+ for(n=0;n<m;n++)
+ copy_meta_single_nocheck(p_source,n);
+ }
+}
+
+void file_info::copy_info(const file_info & p_source)
+{
+ if (&p_source != this) {
+ info_remove_all();
+ t_size n, m = p_source.info_get_count();
+ for(n=0;n<m;n++)
+ copy_info_single_nocheck(p_source,n);
+ }
+}
+
+void file_info::copy(const file_info & p_source)
+{
+ if (&p_source != this) {
+ copy_meta(p_source);
+ copy_info(p_source);
+ set_length(p_source.get_length());
+ set_replaygain(p_source.get_replaygain());
+ }
+}
+
+
+const char * file_info::meta_get_ex(const char * p_name,t_size p_name_length,t_size p_index) const
+{
+ t_size index = meta_find_ex(p_name,p_name_length);
+ if (index == infinite) return 0;
+ t_size max = meta_enum_value_count(index);
+ if (p_index >= max) return 0;
+ return meta_enum_value(index,p_index);
+}
+
+const char * file_info::info_get_ex(const char * p_name,t_size p_name_length) const
+{
+ t_size index = info_find_ex(p_name,p_name_length);
+ if (index == infinite) return 0;
+ return info_enum_value(index);
+}
+
+t_int64 file_info::info_get_int(const char * name) const
+{
+ PFC_ASSERT(pfc::is_valid_utf8(name));
+ const char * val = info_get(name);
+ if (val==0) return 0;
+ return _atoi64(val);
+}
+
+t_int64 file_info::info_get_length_samples() const
+{
+ t_int64 ret = 0;
+ double len = get_length();
+ t_int64 srate = info_get_int("samplerate");
+
+ if (srate>0 && len>0)
+ {
+ ret = audio_math::time_to_samples(len,(unsigned)srate);
+ }
+ return ret;
+}
+
+double file_info::info_get_float(const char * name) const
+{
+ const char * ptr = info_get(name);
+ if (ptr) return pfc::string_to_float(ptr);
+ else return 0;
+}
+
+void file_info::info_set_int(const char * name,t_int64 value)
+{
+ PFC_ASSERT(pfc::is_valid_utf8(name));
+ info_set(name,pfc::format_int(value));
+}
+
+void file_info::info_set_float(const char * name,double value,unsigned precision,bool force_sign,const char * unit)
+{
+ PFC_ASSERT(pfc::is_valid_utf8(name));
+ PFC_ASSERT(unit==0 || strlen(unit) <= 64);
+ char temp[128];
+ pfc::float_to_string(temp,64,value,precision,force_sign);
+ temp[63] = 0;
+ if (unit)
+ {
+ strcat(temp," ");
+ strcat(temp,unit);
+ }
+ info_set(name,temp);
+}
+
+
+void file_info::info_set_replaygain_album_gain(float value)
+{
+ replaygain_info temp = get_replaygain();
+ temp.m_album_gain = value;
+ set_replaygain(temp);
+}
+
+void file_info::info_set_replaygain_album_peak(float value)
+{
+ replaygain_info temp = get_replaygain();
+ temp.m_album_peak = value;
+ set_replaygain(temp);
+}
+
+void file_info::info_set_replaygain_track_gain(float value)
+{
+ replaygain_info temp = get_replaygain();
+ temp.m_track_gain = value;
+ set_replaygain(temp);
+}
+
+void file_info::info_set_replaygain_track_peak(float value)
+{
+ replaygain_info temp = get_replaygain();
+ temp.m_track_peak = value;
+ set_replaygain(temp);
+}
+
+
+static bool is_valid_bps(t_int64 val)
+{
+ return val>0 && val<=256;
+}
+
+unsigned file_info::info_get_decoded_bps() const
+{
+ t_int64 val = info_get_int("decoded_bitspersample");
+ if (is_valid_bps(val)) return (unsigned)val;
+ val = info_get_int("bitspersample");
+ if (is_valid_bps(val)) return (unsigned)val;
+ return 0;
+
+}
+
+void file_info::reset()
+{
+ info_remove_all();
+ meta_remove_all();
+ set_length(0);
+ reset_replaygain();
+}
+
+void file_info::reset_replaygain()
+{
+ replaygain_info temp;
+ temp.reset();
+ set_replaygain(temp);
+}
+
+void file_info::copy_meta_single_rename_ex(const file_info & p_source,t_size p_index,const char * p_new_name,t_size p_new_name_length)
+{
+ t_size n, m = p_source.meta_enum_value_count(p_index);
+ t_size new_index = infinite;
+ for(n=0;n<m;n++)
+ {
+ const char * value = p_source.meta_enum_value(p_index,n);
+ if (n == 0) new_index = meta_set_ex(p_new_name,p_new_name_length,value,infinite);
+ else meta_add_value(new_index,value);
+ }
+}
+
+t_size file_info::meta_add_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length)
+{
+ t_size index = meta_find_ex(p_name,p_name_length);
+ if (index == infinite) return meta_set_nocheck_ex(p_name,p_name_length,p_value,p_value_length);
+ else
+ {
+ meta_add_value_ex(index,p_value,p_value_length);
+ return index;
+ }
+}
+
+void file_info::meta_add_value_ex(t_size p_index,const char * p_value,t_size p_value_length)
+{
+ meta_insert_value_ex(p_index,meta_enum_value_count(p_index),p_value,p_value_length);
+}
+
+
+t_size file_info::meta_calc_total_value_count() const
+{
+ t_size n, m = meta_get_count(), ret = 0;
+ for(n=0;n<m;n++) ret += meta_enum_value_count(n);
+ return ret;
+}
+
+bool file_info::info_set_replaygain_ex(const char * p_name,t_size p_name_len,const char * p_value,t_size p_value_len)
+{
+ replaygain_info temp = get_replaygain();
+ if (temp.set_from_meta_ex(p_name,p_name_len,p_value,p_value_len))
+ {
+ set_replaygain(temp);
+ return true;
+ }
+ else return false;
+}
+
+void file_info::info_set_replaygain_auto_ex(const char * p_name,t_size p_name_len,const char * p_value,t_size p_value_len)
+{
+ if (!info_set_replaygain_ex(p_name,p_name_len,p_value,p_value_len))
+ info_set_ex(p_name,p_name_len,p_value,p_value_len);
+}
+
+bool replaygain_info::g_equal(const replaygain_info & item1,const replaygain_info & item2)
+{
+ return item1.m_album_gain == item2.m_album_gain &&
+ item1.m_track_gain == item2.m_track_gain &&
+ item1.m_album_peak == item2.m_album_peak &&
+ item1.m_track_peak == item2.m_track_peak;
+}
+
+bool file_info::are_meta_fields_identical(t_size p_index1,t_size p_index2) const
+{
+ const t_size count = meta_enum_value_count(p_index1);
+ if (count != meta_enum_value_count(p_index2)) return false;
+ t_size n;
+ for(n=0;n<count;n++)
+ {
+ if (strcmp(meta_enum_value(p_index1,n),meta_enum_value(p_index2,n))) return false;
+ }
+ return true;
+}
+
+
+bool file_info::meta_format(const char * p_name,pfc::string_base & p_out) const
+{
+ p_out.reset();
+ t_size index = meta_find(p_name);
+ if (index == infinite) return false;
+ t_size val, count = meta_enum_value_count(index);
+ if (count == 0) return false;
+ for(val=0;val<count;val++)
+ {
+ if (val > 0) p_out += ", ";
+ p_out += meta_enum_value(index,val);
+ }
+ return true;
+}
+
+void file_info::info_calculate_bitrate(t_filesize p_filesize,double p_length)
+{
+ info_set_bitrate((unsigned)floor((double)p_filesize * 8 / (p_length * 1000) + 0.5));
+}
+
+bool file_info::is_encoding_lossy() const {
+ const char * encoding = info_get("encoding");
+ if (encoding != NULL) {
+ if (pfc::stricmp_ascii(encoding,"lossy") == 0 /*|| pfc::stricmp_ascii(encoding,"hybrid") == 0*/) return true;
+ } else {
+ //the old way
+ if (info_get("bitspersample") == NULL) return true;
+ }
+ return false;
+}
+
+bool file_info::g_is_meta_equal(const file_info & p_item1,const file_info & p_item2) {
+ const t_size count = p_item1.meta_get_count();
+ if (count != p_item2.meta_get_count()) {
+ //uDebugLog() << "meta count mismatch";
+ return false;
+ }
+ pfc::map_t<const char*,t_size,field_name_comparator> item2_meta_map;
+ for(t_size n=0; n<count; n++) {
+ item2_meta_map.set(p_item2.meta_enum_name(n),n);
+ }
+ for(t_size n1=0; n1<count; n1++) {
+ t_size n2;
+ if (!item2_meta_map.query(p_item1.meta_enum_name(n1),n2)) {
+ //uDebugLog() << "item2 doesn't have " << p_item1.meta_enum_name(n1);
+ return false;
+ }
+ t_size value_count = p_item1.meta_enum_value_count(n1);
+ if (value_count != p_item2.meta_enum_value_count(n2)) {
+ //uDebugLog() << "meta value count mismatch: " << p_item1.meta_enum_name(n1) << " : " << value_count << " vs " << p_item2.meta_enum_value_count(n2);
+ return false;
+ }
+ for(t_size v = 0; v < value_count; v++) {
+ if (strcmp(p_item1.meta_enum_value(n1,v),p_item2.meta_enum_value(n2,v)) != 0) {
+ //uDebugLog() << "meta mismatch: " << p_item1.meta_enum_name(n1) << " : " << p_item1.meta_enum_value(n1,v) << " vs " << p_item2.meta_enum_value(n2,v);
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool file_info::g_is_info_equal(const file_info & p_item1,const file_info & p_item2) {
+ t_size count = p_item1.info_get_count();
+ if (count != p_item2.info_get_count()) return false;
+ for(t_size n1=0; n1<count; n1++) {
+ t_size n2 = p_item2.info_find(p_item1.info_enum_name(n1));
+ if (n2 == infinite) return false;
+ if (strcmp(p_item1.info_enum_value(n1),p_item2.info_enum_value(n2)) != 0) return false;
+ }
+ return true;
+}
+
+static bool is_valid_field_name_char(char p_char) {
+ return p_char >= 32 && p_char < 127 && p_char != '=' && p_char != '%' && p_char != '<' && p_char != '>';
+}
+
+bool file_info::g_is_valid_field_name(const char * p_name,t_size p_length) {
+ t_size walk;
+ for(walk = 0; walk < p_length && p_name[walk] != 0; walk++) {
+ if (!is_valid_field_name_char(p_name[walk])) return false;
+ }
+ return walk > 0;
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info.h
new file mode 100644
index 0000000..19eaef3
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info.h
@@ -0,0 +1,228 @@
+#ifndef _FILE_INFO_H_
+#define _FILE_INFO_H_
+
+//! Structure containing ReplayGain scan results from some playable object, also providing various helper methods to manipulate those results.
+struct replaygain_info
+{
+ float m_album_gain,m_track_gain;
+ float m_album_peak,m_track_peak;
+
+ enum {text_buffer_size = 16 };
+ typedef char t_text_buffer[text_buffer_size];
+
+ enum { peak_invalid = -1, gain_invalid = -1000 };
+
+ static bool g_format_gain(float p_value,char p_buffer[text_buffer_size]);
+ static bool g_format_peak(float p_value,char p_buffer[text_buffer_size]);
+
+ inline bool format_album_gain(char p_buffer[text_buffer_size]) const {return g_format_gain(m_album_gain,p_buffer);}
+ inline bool format_track_gain(char p_buffer[text_buffer_size]) const {return g_format_gain(m_track_gain,p_buffer);}
+ inline bool format_album_peak(char p_buffer[text_buffer_size]) const {return g_format_peak(m_album_peak,p_buffer);}
+ inline bool format_track_peak(char p_buffer[text_buffer_size]) const {return g_format_peak(m_track_peak,p_buffer);}
+
+ void set_album_gain_text(const char * p_text,t_size p_text_len = infinite);
+ void set_track_gain_text(const char * p_text,t_size p_text_len = infinite);
+ void set_album_peak_text(const char * p_text,t_size p_text_len = infinite);
+ void set_track_peak_text(const char * p_text,t_size p_text_len = infinite);
+
+ static bool g_is_meta_replaygain(const char * p_name,t_size p_name_len = infinite);
+ bool set_from_meta_ex(const char * p_name,t_size p_name_len,const char * p_value,t_size p_value_len);
+ inline bool set_from_meta(const char * p_name,const char * p_value) {return set_from_meta_ex(p_name,infinite,p_value,infinite);}
+
+ inline bool is_album_gain_present() const {return m_album_gain != gain_invalid;}
+ inline bool is_track_gain_present() const {return m_track_gain != gain_invalid;}
+ inline bool is_album_peak_present() const {return m_album_peak != peak_invalid;}
+ inline bool is_track_peak_present() const {return m_track_peak != peak_invalid;}
+
+ inline void remove_album_gain() {m_album_gain = gain_invalid;}
+ inline void remove_track_gain() {m_track_gain = gain_invalid;}
+ inline void remove_album_peak() {m_album_peak = peak_invalid;}
+ inline void remove_track_peak() {m_track_peak = peak_invalid;}
+
+ t_size get_value_count();
+
+ static replaygain_info g_merge(replaygain_info r1,replaygain_info r2);
+
+ static bool g_equal(const replaygain_info & item1,const replaygain_info & item2);
+
+ void reset();
+};
+
+inline bool operator==(const replaygain_info & item1,const replaygain_info & item2) {return replaygain_info::g_equal(item1,item2);}
+inline bool operator!=(const replaygain_info & item1,const replaygain_info & item2) {return !replaygain_info::g_equal(item1,item2);}
+
+static const replaygain_info replaygain_info_invalid = {replaygain_info::gain_invalid,replaygain_info::gain_invalid,replaygain_info::peak_invalid,replaygain_info::peak_invalid};
+
+
+//! Main interface class for information about some playable object.
+class NOVTABLE file_info {
+public:
+ //! Retrieves length, in seconds.
+ virtual double get_length() const = 0;
+ //! Sets length, in seconds.
+ virtual void set_length(double p_length) = 0;
+
+ //! Sets ReplayGain information.
+ virtual void set_replaygain(const replaygain_info & p_info) = 0;
+ //! Retrieves ReplayGain information.
+ virtual replaygain_info get_replaygain() const = 0;
+
+ //! Retrieves count of metadata entries.
+ virtual t_size meta_get_count() const = 0;
+ //! Retrieves the name of metadata entry of specified index. Return value is a null-terminated UTF-8 encoded string.
+ virtual const char* meta_enum_name(t_size p_index) const = 0;
+ //! Retrieves count of values in metadata entry of specified index. The value is always equal to or greater than 1.
+ virtual t_size meta_enum_value_count(t_size p_index) const = 0;
+ //! Retrieves specified value from specified metadata entry. Return value is a null-terminated UTF-8 encoded string.
+ virtual const char* meta_enum_value(t_size p_index,t_size p_value_number) const = 0;
+ //! Finds index of metadata entry of specified name. Returns infinite when not found.
+ virtual t_size meta_find_ex(const char * p_name,t_size p_name_length) const;
+ //! Creates a new metadata entry of specified name with specified value. If an entry of same name already exists, it is erased. Return value is the index of newly created metadata entry.
+ virtual t_size meta_set_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length) = 0;
+ //! Inserts a new value into specified metadata entry.
+ virtual void meta_insert_value_ex(t_size p_index,t_size p_value_index,const char * p_value,t_size p_value_length) = 0;
+ //! Removes metadata entries according to specified bit mask.
+ virtual void meta_remove_mask(const bit_array & p_mask) = 0;
+ //! Reorders metadata entries according to specified permutation.
+ virtual void meta_reorder(const t_size * p_order) = 0;
+ //! Removes values according to specified bit mask from specified metadata entry. If all values are removed, entire metadata entry is removed as well.
+ virtual void meta_remove_values(t_size p_index,const bit_array & p_mask) = 0;
+ //! Alters specified value in specified metadata entry.
+ virtual void meta_modify_value_ex(t_size p_index,t_size p_value_index,const char * p_value,t_size p_value_length) = 0;
+
+ //! Retrieves number of technical info entries.
+ virtual t_size info_get_count() const = 0;
+ //! Retrieves the name of specified technical info entry. Return value is a null-terminated UTF-8 encoded string.
+ virtual const char* info_enum_name(t_size p_index) const = 0;
+ //! Retrieves the value of specified technical info entry. Return value is a null-terminated UTF-8 encoded string.
+ virtual const char* info_enum_value(t_size p_index) const = 0;
+ //! Creates a new technical info entry with specified name and specified value. If an entry of the same name already exists, it is erased. Return value is the index of newly created entry.
+ virtual t_size info_set_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length) = 0;
+ //! Removes technical info entries indicated by specified bit mask.
+ virtual void info_remove_mask(const bit_array & p_mask) = 0;
+ //! Finds technical info entry of specified name. Returns index of found entry on success, infinite on failure.
+ virtual t_size info_find_ex(const char * p_name,t_size p_name_length) const;
+
+ //! Copies entire file_info contents from specified file_info object.
+ virtual void copy(const file_info & p_source);//virtualized for performance reasons, can be faster in two-pass
+ //! Copies metadata from specified file_info object.
+ virtual void copy_meta(const file_info & p_source);//virtualized for performance reasons, can be faster in two-pass
+ //! Copies technical info from specified file_info object.
+ virtual void copy_info(const file_info & p_source);//virtualized for performance reasons, can be faster in two-pass
+
+ bool meta_exists_ex(const char * p_name,t_size p_name_length) const;
+ void meta_remove_field_ex(const char * p_name,t_size p_name_length);
+ void meta_remove_index(t_size p_index);
+ void meta_remove_all();
+ void meta_remove_value(t_size p_index,t_size p_value);
+ const char * meta_get_ex(const char * p_name,t_size p_name_length,t_size p_index) const;
+ t_size meta_get_count_by_name_ex(const char * p_name,t_size p_name_length) const;
+ void meta_add_value_ex(t_size p_index,const char * p_value,t_size p_value_length);
+ t_size meta_add_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length);
+ t_size meta_calc_total_value_count() const;
+ bool meta_format(const char * p_name,pfc::string_base & p_out) const;
+
+
+ bool info_exists_ex(const char * p_name,t_size p_name_length) const;
+ void info_remove_index(t_size p_index);
+ void info_remove_all();
+ bool info_remove_ex(const char * p_name,t_size p_name_length);
+ const char * info_get_ex(const char * p_name,t_size p_name_length) const;
+
+ inline t_size meta_find(const char * p_name) const {return meta_find_ex(p_name,infinite);}
+ inline bool meta_exists(const char * p_name) const {return meta_exists_ex(p_name,infinite);}
+ inline void meta_remove_field(const char * p_name) {meta_remove_field_ex(p_name,infinite);}
+ inline t_size meta_set(const char * p_name,const char * p_value) {return meta_set_ex(p_name,infinite,p_value,infinite);}
+ inline void meta_insert_value(t_size p_index,t_size p_value_index,const char * p_value) {meta_insert_value_ex(p_index,p_value_index,p_value,infinite);}
+ inline void meta_add_value(t_size p_index,const char * p_value) {meta_add_value_ex(p_index,p_value,infinite);}
+ inline const char* meta_get(const char * p_name,t_size p_index) const {return meta_get_ex(p_name,infinite,p_index);}
+ inline t_size meta_get_count_by_name(const char * p_name) const {return meta_get_count_by_name_ex(p_name,infinite);}
+ inline t_size meta_add(const char * p_name,const char * p_value) {return meta_add_ex(p_name,infinite,p_value,infinite);}
+ inline void meta_modify_value(t_size p_index,t_size p_value_index,const char * p_value) {meta_modify_value_ex(p_index,p_value_index,p_value,infinite);}
+
+
+
+ inline t_size info_set(const char * p_name,const char * p_value) {return info_set_ex(p_name,infinite,p_value,infinite);}
+ inline t_size info_find(const char * p_name) const {return info_find_ex(p_name,infinite);}
+ inline t_size info_exists(const char * p_name) const {return info_exists_ex(p_name,infinite);}
+ inline bool info_remove(const char * p_name) {return info_remove_ex(p_name,infinite);}
+ inline const char * info_get(const char * p_name) const {return info_get_ex(p_name,infinite);}
+
+ bool info_set_replaygain_ex(const char * p_name,t_size p_name_len,const char * p_value,t_size p_value_len);
+ inline bool info_set_replaygain(const char * p_name,const char * p_value) {return info_set_replaygain_ex(p_name,infinite,p_value,infinite);}
+ void info_set_replaygain_auto_ex(const char * p_name,t_size p_name_len,const char * p_value,t_size p_value_len);
+ inline void info_set_replaygain_auto(const char * p_name,const char * p_value) {info_set_replaygain_auto_ex(p_name,infinite,p_value,infinite);}
+
+
+
+ void copy_meta_single(const file_info & p_source,t_size p_index);
+ void copy_info_single(const file_info & p_source,t_size p_index);
+ void copy_meta_single_by_name_ex(const file_info & p_source,const char * p_name,t_size p_name_length);
+ void copy_info_single_by_name_ex(const file_info & p_source,const char * p_name,t_size p_name_length);
+ inline void copy_meta_single_by_name(const file_info & p_source,const char * p_name) {copy_meta_single_by_name_ex(p_source,p_name,infinite);}
+ inline void copy_info_single_by_name(const file_info & p_source,const char * p_name) {copy_info_single_by_name_ex(p_source,p_name,infinite);}
+ void reset();
+ void reset_replaygain();
+ void copy_meta_single_rename_ex(const file_info & p_source,t_size p_index,const char * p_new_name,t_size p_new_name_length);
+ inline void copy_meta_single_rename(const file_info & p_source,t_size p_index,const char * p_new_name) {copy_meta_single_rename_ex(p_source,p_index,p_new_name,infinite);}
+ void overwrite_info(const file_info & p_source);
+
+ t_int64 info_get_int(const char * name) const;
+ t_int64 info_get_length_samples() const;
+ double info_get_float(const char * name) const;
+ void info_set_int(const char * name,t_int64 value);
+ void info_set_float(const char * name,double value,unsigned precision,bool force_sign = false,const char * unit = 0);
+ void info_set_replaygain_track_gain(float value);
+ void info_set_replaygain_album_gain(float value);
+ void info_set_replaygain_track_peak(float value);
+ void info_set_replaygain_album_peak(float value);
+
+ inline t_int64 info_get_bitrate_vbr() const {return info_get_int("bitrate_dynamic");}
+ inline void info_set_bitrate_vbr(t_int64 val) {info_set_int("bitrate_dynamic",val);}
+ inline t_int64 info_get_bitrate() const {return info_get_int("bitrate");}
+ inline void info_set_bitrate(t_int64 val) {info_set_int("bitrate",val);}
+ bool is_encoding_lossy() const;
+
+ void info_calculate_bitrate(t_filesize p_filesize,double p_length);
+
+ unsigned info_get_decoded_bps() const;//what bps the stream originally was (before converting to audio_sample), 0 if unknown
+
+ void merge(const pfc::list_base_const_t<const file_info*> & p_sources);
+
+ bool are_meta_fields_identical(t_size p_index1,t_size p_index2) const;
+
+ inline const file_info & operator=(const file_info & p_source) {copy(p_source);return *this;}
+
+ static bool g_is_meta_equal(const file_info & p_item1,const file_info & p_item2);
+ static bool g_is_info_equal(const file_info & p_item1,const file_info & p_item2);
+
+ //! Unsafe - does not check whether the field already exists and will result in duplicates if it does - call only when appropriate checks have been applied externally.
+ t_size __meta_add_unsafe_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length) {return meta_set_nocheck_ex(p_name,p_name_length,p_value,p_value_length);}
+ //! Unsafe - does not check whether the field already exists and will result in duplicates if it does - call only when appropriate checks have been applied externally.
+ t_size __meta_add_unsafe(const char * p_name,const char * p_value) {return meta_set_nocheck_ex(p_name,infinite,p_value,infinite);}
+
+ //! Unsafe - does not check whether the field already exists and will result in duplicates if it does - call only when appropriate checks have been applied externally.
+ t_size __info_add_unsafe_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length) {return info_set_nocheck_ex(p_name,p_name_length,p_value,p_value_length);}
+ //! Unsafe - does not check whether the field already exists and will result in duplicates if it does - call only when appropriate checks have been applied externally.
+ t_size __info_add_unsafe(const char * p_name,const char * p_value) {return info_set_nocheck_ex(p_name,infinite,p_value,infinite);}
+
+ static bool g_is_valid_field_name(const char * p_name,t_size p_length = infinite);
+ typedef pfc::comparator_stricmp_ascii field_name_comparator;
+protected:
+ file_info() {}
+ ~file_info() {}
+ void copy_meta_single_nocheck(const file_info & p_source,t_size p_index);
+ void copy_info_single_nocheck(const file_info & p_source,t_size p_index);
+ void copy_meta_single_by_name_nocheck_ex(const file_info & p_source,const char * p_name,t_size p_name_length);
+ void copy_info_single_by_name_nocheck_ex(const file_info & p_source,const char * p_name,t_size p_name_length);
+ inline void copy_meta_single_by_name_nocheck(const file_info & p_source,const char * p_name) {copy_meta_single_by_name_nocheck_ex(p_source,p_name,infinite);}
+ inline void copy_info_single_by_name_nocheck(const file_info & p_source,const char * p_name) {copy_info_single_by_name_nocheck_ex(p_source,p_name,infinite);}
+
+ virtual t_size meta_set_nocheck_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length) = 0;
+ virtual t_size info_set_nocheck_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length) = 0;
+ inline t_size meta_set_nocheck(const char * p_name,const char * p_value) {return meta_set_nocheck_ex(p_name,infinite,p_value,infinite);}
+ inline t_size info_set_nocheck(const char * p_name,const char * p_value) {return info_set_nocheck_ex(p_name,infinite,p_value,infinite);}
+};
+
+
+#endif //_FILE_INFO_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info_impl.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info_impl.cpp
new file mode 100644
index 0000000..f55be0e
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info_impl.cpp
@@ -0,0 +1,243 @@
+#include "foobar2000.h"
+
+
+t_size file_info_impl::meta_get_count() const
+{
+ return m_meta.get_count();
+}
+
+const char* file_info_impl::meta_enum_name(t_size p_index) const
+{
+ return m_meta.get_name(p_index);
+}
+
+t_size file_info_impl::meta_enum_value_count(t_size p_index) const
+{
+ return m_meta.get_value_count(p_index);
+}
+
+const char* file_info_impl::meta_enum_value(t_size p_index,t_size p_value_number) const
+{
+ return m_meta.get_value(p_index,p_value_number);
+}
+
+t_size file_info_impl::meta_set_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length)
+{
+ meta_remove_field_ex(p_name,p_name_length);
+ return meta_set_nocheck_ex(p_name,p_name_length,p_value,p_value_length);
+}
+
+t_size file_info_impl::meta_set_nocheck_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length)
+{
+ return m_meta.add_entry(p_name,p_name_length,p_value,p_value_length);
+}
+
+void file_info_impl::meta_insert_value_ex(t_size p_index,t_size p_value_index,const char * p_value,t_size p_value_length)
+{
+ m_meta.insert_value(p_index,p_value_index,p_value,p_value_length);
+}
+
+void file_info_impl::meta_remove_mask(const bit_array & p_mask)
+{
+ m_meta.remove_mask(p_mask);
+}
+
+void file_info_impl::meta_reorder(const t_size * p_order)
+{
+ m_meta.reorder(p_order);
+}
+
+void file_info_impl::meta_remove_values(t_size p_index,const bit_array & p_mask)
+{
+ m_meta.remove_values(p_index,p_mask);
+ if (m_meta.get_value_count(p_index) == 0)
+ m_meta.remove_mask(bit_array_one(p_index));
+}
+
+t_size file_info_impl::info_get_count() const
+{
+ return m_info.get_count();
+}
+
+const char* file_info_impl::info_enum_name(t_size p_index) const
+{
+ return m_info.get_name(p_index);
+}
+
+const char* file_info_impl::info_enum_value(t_size p_index) const
+{
+ return m_info.get_value(p_index);
+}
+
+t_size file_info_impl::info_set_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length)
+{
+ info_remove_ex(p_name,p_name_length);
+ return info_set_nocheck_ex(p_name,p_name_length,p_value,p_value_length);
+}
+
+t_size file_info_impl::info_set_nocheck_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length)
+{
+ return m_info.add_item(p_name,p_name_length,p_value,p_value_length);
+}
+
+void file_info_impl::info_remove_mask(const bit_array & p_mask)
+{
+ m_info.remove_mask(p_mask);
+}
+
+
+file_info_impl::file_info_impl(const file_info & p_source) : m_length(0)
+{
+ copy(p_source);
+}
+
+file_info_impl::file_info_impl(const file_info_impl & p_source) : m_length(0)
+{
+ copy(p_source);
+}
+
+const file_info_impl & file_info_impl::operator=(const file_info_impl & p_source)
+{
+ copy(p_source);
+ return *this;
+}
+
+file_info_impl::file_info_impl() : m_length(0)
+{
+ m_replaygain.reset();
+}
+
+double file_info_impl::get_length() const
+{
+ return m_length;
+}
+
+void file_info_impl::set_length(double p_length)
+{
+ m_length = p_length;
+}
+
+void file_info_impl::meta_modify_value_ex(t_size p_index,t_size p_value_index,const char * p_value,t_size p_value_length)
+{
+ m_meta.modify_value(p_index,p_value_index,p_value,p_value_length);
+}
+
+replaygain_info file_info_impl::get_replaygain() const
+{
+ return m_replaygain;
+}
+
+void file_info_impl::set_replaygain(const replaygain_info & p_info)
+{
+ m_replaygain = p_info;
+}
+
+
+
+
+file_info_impl::~file_info_impl()
+{
+}
+
+t_size file_info_impl_utils::info_storage::add_item(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length) {
+ t_size index = m_info.get_size();
+ m_info.set_size(index + 1);
+ m_info[index].init(p_name,p_name_length,p_value,p_value_length);
+ return index;
+}
+
+void file_info_impl_utils::info_storage::remove_mask(const bit_array & p_mask) {
+ pfc::remove_mask_t(m_info,p_mask);
+}
+
+
+
+t_size file_info_impl_utils::meta_storage::add_entry(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length)
+{
+ meta_entry temp(p_name,p_name_length,p_value,p_value_length);
+ return pfc::append_swap_t(m_data,temp);
+}
+
+void file_info_impl_utils::meta_storage::insert_value(t_size p_index,t_size p_value_index,const char * p_value,t_size p_value_length)
+{
+ m_data[p_index].insert_value(p_value_index,p_value,p_value_length);
+}
+
+void file_info_impl_utils::meta_storage::modify_value(t_size p_index,t_size p_value_index,const char * p_value,t_size p_value_length)
+{
+ m_data[p_index].modify_value(p_value_index,p_value,p_value_length);
+}
+
+void file_info_impl_utils::meta_storage::remove_values(t_size p_index,const bit_array & p_mask)
+{
+ m_data[p_index].remove_values(p_mask);
+}
+
+void file_info_impl_utils::meta_storage::remove_mask(const bit_array & p_mask)
+{
+ pfc::remove_mask_t(m_data,p_mask);
+}
+
+
+file_info_impl_utils::meta_entry::meta_entry(const char * p_name,t_size p_name_len,const char * p_value,t_size p_value_len)
+{
+ m_name.set_string(p_name,p_name_len);
+ m_values.set_size(1);
+ m_values[0].set_string(p_value,p_value_len);
+}
+
+
+void file_info_impl_utils::meta_entry::remove_values(const bit_array & p_mask)
+{
+ pfc::remove_mask_t(m_values,p_mask);
+}
+
+void file_info_impl_utils::meta_entry::insert_value(t_size p_value_index,const char * p_value,t_size p_value_length)
+{
+ pfc::string_simple temp;
+ temp.set_string(p_value,p_value_length);
+ pfc::insert_swap_t(m_values,temp,p_value_index);
+}
+
+void file_info_impl_utils::meta_entry::modify_value(t_size p_value_index,const char * p_value,t_size p_value_length)
+{
+ m_values[p_value_index].set_string(p_value,p_value_length);
+}
+
+void file_info_impl_utils::meta_storage::reorder(const t_size * p_order)
+{
+ pfc::reorder_t(m_data,p_order,m_data.get_size());
+}
+
+void file_info_impl::copy_meta(const file_info & p_source)
+{
+ m_meta.copy_from(p_source);
+}
+
+void file_info_impl::copy_info(const file_info & p_source)
+{
+ m_info.copy_from(p_source);
+}
+
+void file_info_impl_utils::meta_storage::copy_from(const file_info & p_info)
+{
+ t_size meta_index,meta_count = p_info.meta_get_count();
+ m_data.set_size(meta_count);
+ for(meta_index=0;meta_index<meta_count;meta_index++)
+ {
+ meta_entry & entry = m_data[meta_index];
+ t_size value_index,value_count = p_info.meta_enum_value_count(meta_index);
+ entry.m_name = p_info.meta_enum_name(meta_index);
+ entry.m_values.set_size(value_count);
+ for(value_index=0;value_index<value_count;value_index++)
+ entry.m_values[value_index] = p_info.meta_enum_value(meta_index,value_index);
+ }
+}
+
+void file_info_impl_utils::info_storage::copy_from(const file_info & p_info)
+{
+ t_size n, count;
+ count = p_info.info_get_count();
+ m_info.set_count(count);
+ for(n=0;n<count;n++) m_info[n].init(p_info.info_enum_name(n),infinite,p_info.info_enum_value(n),infinite);
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info_impl.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info_impl.h
new file mode 100644
index 0000000..5d76695
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info_impl.h
@@ -0,0 +1,146 @@
+#ifndef _FOOBAR2000_SDK_FILE_INFO_IMPL_H_
+#define _FOOBAR2000_SDK_FILE_INFO_IMPL_H_
+
+namespace file_info_impl_utils {
+
+ struct info_entry {
+ void init(const char * p_name,t_size p_name_len,const char * p_value,t_size p_value_len) {
+ m_name.set_string(p_name,p_name_len);
+ m_value.set_string(p_value,p_value_len);
+ }
+
+ inline const char * get_name() const {return m_name;}
+ inline const char * get_value() const {return m_value;}
+
+ pfc::string_simple m_name,m_value;
+ };
+
+ typedef pfc::array_t<info_entry,pfc::alloc_fast> info_entry_array;
+
+}
+
+namespace pfc {
+ template<> class traits_t<file_info_impl_utils::info_entry> : public traits_t<pfc::string_simple> {};
+};
+
+
+namespace file_info_impl_utils {
+ class info_storage
+ {
+ public:
+ t_size add_item(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length);
+ void remove_mask(const bit_array & p_mask);
+ inline t_size get_count() const {return m_info.get_count();}
+ inline const char * get_name(t_size p_index) const {return m_info[p_index].get_name();}
+ inline const char * get_value(t_size p_index) const {return m_info[p_index].get_value();}
+ void copy_from(const file_info & p_info);
+ private:
+ info_entry_array m_info;
+ };
+}
+
+
+namespace file_info_impl_utils {
+ typedef pfc::array_hybrid_t<pfc::string_simple,1,pfc::alloc_fast > meta_value_array;
+ struct meta_entry {
+ meta_entry() {}
+ meta_entry(const char * p_name,t_size p_name_len,const char * p_value,t_size p_value_len);
+
+ void remove_values(const bit_array & p_mask);
+ void insert_value(t_size p_value_index,const char * p_value,t_size p_value_length);
+ void modify_value(t_size p_value_index,const char * p_value,t_size p_value_length);
+
+ inline const char * get_name() const {return m_name;}
+ inline const char * get_value(t_size p_index) const {return m_values[p_index];}
+ inline t_size get_value_count() const {return m_values.get_size();}
+
+
+ pfc::string_simple m_name;
+ meta_value_array m_values;
+ };
+ typedef pfc::array_hybrid_t<meta_entry,10, pfc::alloc_fast> meta_entry_array;
+}
+namespace pfc {
+ template<> class traits_t<file_info_impl_utils::meta_entry> : public pfc::traits_combined<pfc::string_simple,file_info_impl_utils::meta_value_array> {};
+}
+
+
+namespace file_info_impl_utils {
+ class meta_storage
+ {
+ public:
+ t_size add_entry(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length);
+ void insert_value(t_size p_index,t_size p_value_index,const char * p_value,t_size p_value_length);
+ void modify_value(t_size p_index,t_size p_value_index,const char * p_value,t_size p_value_length);
+ void remove_values(t_size p_index,const bit_array & p_mask);
+ void remove_mask(const bit_array & p_mask);
+ void copy_from(const file_info & p_info);
+
+ inline void reorder(const t_size * p_order);
+
+ inline t_size get_count() const {return m_data.get_size();}
+
+ inline const char * get_name(t_size p_index) const {assert(p_index < m_data.get_size()); return m_data[p_index].get_name();}
+ inline const char * get_value(t_size p_index,t_size p_value_index) const {assert(p_index < m_data.get_size()); return m_data[p_index].get_value(p_value_index);}
+ inline t_size get_value_count(t_size p_index) const {assert(p_index < m_data.get_size()); return m_data[p_index].get_value_count();}
+
+ private:
+ meta_entry_array m_data;
+ };
+}
+
+//! Implements file_info.
+class file_info_impl : public file_info
+{
+public:
+ file_info_impl(const file_info_impl & p_source);
+ file_info_impl(const file_info & p_source);
+ file_info_impl();
+ ~file_info_impl();
+
+ double get_length() const;
+ void set_length(double p_length);
+
+ void copy_meta(const file_info & p_source);//virtualized for performance reasons, can be faster in two-pass
+ void copy_info(const file_info & p_source);//virtualized for performance reasons, can be faster in two-pass
+
+ t_size meta_get_count() const;
+ const char* meta_enum_name(t_size p_index) const;
+ t_size meta_enum_value_count(t_size p_index) const;
+ const char* meta_enum_value(t_size p_index,t_size p_value_number) const;
+ t_size meta_set_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length);
+ void meta_insert_value_ex(t_size p_index,t_size p_value_index,const char * p_value,t_size p_value_length);
+ void meta_remove_mask(const bit_array & p_mask);
+ void meta_reorder(const t_size * p_order);
+ void meta_remove_values(t_size p_index,const bit_array & p_mask);
+ void meta_modify_value_ex(t_size p_index,t_size p_value_index,const char * p_value,t_size p_value_length);
+
+ t_size info_get_count() const;
+ const char* info_enum_name(t_size p_index) const;
+ const char* info_enum_value(t_size p_index) const;
+ t_size info_set_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length);
+ void info_remove_mask(const bit_array & p_mask);
+
+ const file_info_impl & operator=(const file_info_impl & p_source);
+
+ replaygain_info get_replaygain() const;
+ void set_replaygain(const replaygain_info & p_info);
+
+protected:
+ t_size meta_set_nocheck_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length);
+ t_size info_set_nocheck_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length);
+private:
+
+
+ file_info_impl_utils::meta_storage m_meta;
+ file_info_impl_utils::info_storage m_info;
+
+
+ double m_length;
+
+ replaygain_info m_replaygain;
+};
+
+typedef file_info_impl file_info_i;//for compatibility
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info_merge.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info_merge.cpp
new file mode 100644
index 0000000..e7aba0d
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_info_merge.cpp
@@ -0,0 +1,130 @@
+#include "foobar2000.h"
+
+static t_size merge_tags_calc_rating_by_index(const file_info & p_info,t_size p_index) {
+ t_size n,m = p_info.meta_enum_value_count(p_index);
+ t_size ret = 0;
+ for(n=0;n<m;n++)
+ ret += strlen(p_info.meta_enum_value(p_index,n)) + 10;//yes, strlen on utf8 data, plus a slight bump to prefer multivalue over singlevalue w/ separator
+ return ret;
+}
+
+static t_size merge_tags_calc_rating(const file_info & p_info,const char * p_field) {
+ t_size field_index = p_info.meta_find(p_field);
+ t_size ret = 0;
+ if (field_index != infinite) {
+ return merge_tags_calc_rating_by_index(p_info,field_index);
+ } else {
+ return 0;
+ }
+}
+
+static void merge_tags_copy_info(const char * field,const file_info * from,file_info * to)
+{
+ const char * val = from->info_get(field);
+ if (val) to->info_set(field,val);
+}
+
+namespace {
+ struct meta_merge_entry {
+ meta_merge_entry() : m_rating(0) {}
+ t_size m_rating;
+ pfc::array_t<const char *> m_data;
+ };
+
+ class meta_merge_map_enumerator {
+ public:
+ meta_merge_map_enumerator(file_info & p_out) : m_out(p_out) {
+ m_out.meta_remove_all();
+ }
+ void operator() (const char * p_name, const meta_merge_entry & p_entry) {
+ if (p_entry.m_data.get_size() > 0) {
+ t_size index = m_out.__meta_add_unsafe(p_name,p_entry.m_data[0]);
+ for(t_size walk = 1; walk < p_entry.m_data.get_size(); ++walk) {
+ m_out.meta_add_value(index,p_entry.m_data[walk]);
+ }
+ }
+ }
+ private:
+ file_info & m_out;
+ };
+}
+
+static void merge_meta(file_info & p_out,const pfc::list_base_const_t<const file_info*> & p_in) {
+ pfc::map_t<const char *,meta_merge_entry,pfc::comparator_stricmp_ascii> map;
+ for(t_size in_walk = 0; in_walk < p_in.get_count(); in_walk++) {
+ const file_info & in = * p_in[in_walk];
+ for(t_size meta_walk = 0, meta_count = in.meta_get_count(); meta_walk < meta_count; meta_walk++ ) {
+ meta_merge_entry & entry = map.find_or_add(in.meta_enum_name(meta_walk));
+ t_size rating = merge_tags_calc_rating_by_index(in,meta_walk);
+ if (rating > entry.m_rating) {
+ entry.m_rating = rating;
+ const t_size value_count = in.meta_enum_value_count(meta_walk);
+ entry.m_data.set_size(value_count);
+ for(t_size value_walk = 0; value_walk < value_count; value_walk++ ) {
+ entry.m_data[value_walk] = in.meta_enum_value(meta_walk,value_walk);
+ }
+ }
+ }
+ }
+
+ map.enumerate(meta_merge_map_enumerator(p_out));
+}
+
+void file_info::merge(const pfc::list_base_const_t<const file_info*> & p_in)
+{
+ t_size in_count = p_in.get_count();
+ if (in_count == 0)
+ {
+ meta_remove_all();
+ return;
+ }
+ else if (in_count == 1)
+ {
+ const file_info * info = p_in[0];
+
+ copy_meta(*info);
+
+ set_replaygain(replaygain_info::g_merge(get_replaygain(),info->get_replaygain()));
+
+ overwrite_info(*info);
+
+ //copy_info_single_by_name(*info,"tagtype");
+
+ return;
+ }
+
+ merge_meta(*this,p_in);
+
+ {
+ pfc::string8_fastalloc tagtype;
+ replaygain_info rg = get_replaygain();
+ t_size in_ptr;
+ for(in_ptr = 0; in_ptr < in_count; in_ptr++ )
+ {
+ const file_info * info = p_in[in_ptr];
+ rg = replaygain_info::g_merge(rg, info->get_replaygain());
+ t_size field_ptr, field_max = info->info_get_count();
+ for(field_ptr = 0; field_ptr < field_max; field_ptr++ )
+ {
+ const char * field_name = info->info_enum_name(field_ptr), * field_value = info->info_enum_value(field_ptr);
+ if (*field_value)
+ {
+ if (!stricmp_utf8(field_name,"tagtype"))
+ {
+ if (!tagtype.is_empty()) tagtype += "|";
+ tagtype += field_value;
+ }
+ }
+ }
+ }
+ if (!tagtype.is_empty()) info_set("tagtype",tagtype);
+ set_replaygain(rg);
+ }
+}
+
+void file_info::overwrite_info(const file_info & p_source) {
+ t_size count = p_source.info_get_count();
+ for(t_size n=0;n<count;n++) {
+ info_set(p_source.info_enum_name(n),p_source.info_enum_value(n));
+ }
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_operation_callback.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_operation_callback.cpp
new file mode 100644
index 0000000..b1d883b
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_operation_callback.cpp
@@ -0,0 +1,93 @@
+#include "foobar2000.h"
+
+
+static void g_on_files_deleted_sorted(const pfc::list_base_const_t<const char *> & p_items)
+{
+ static_api_ptr_t<library_manager>()->on_files_deleted_sorted(p_items);
+ static_api_ptr_t<playlist_manager>()->on_files_deleted_sorted(p_items);
+
+ service_ptr_t<file_operation_callback> ptr;
+ service_enum_t<file_operation_callback> e;
+ while(e.next(ptr))
+ {
+ ptr->on_files_deleted_sorted(p_items);
+ }
+}
+
+static void g_on_files_moved_sorted(const pfc::list_base_const_t<const char *> & p_from,const pfc::list_base_const_t<const char *> & p_to)
+{
+ static_api_ptr_t<playlist_manager>()->on_files_moved_sorted(p_from,p_to);
+ static_api_ptr_t<playlist_manager>()->on_files_deleted_sorted(p_from);
+
+ service_ptr_t<file_operation_callback> ptr;
+ service_enum_t<file_operation_callback> e;
+ while(e.next(ptr))
+ {
+ ptr->on_files_moved_sorted(p_from,p_to);
+ }
+}
+
+static void g_on_files_copied_sorted(const pfc::list_base_const_t<const char *> & p_from,const pfc::list_base_const_t<const char *> & p_to)
+{
+ service_ptr_t<file_operation_callback> ptr;
+ service_enum_t<file_operation_callback> e;
+ while(e.next(ptr))
+ {
+ ptr->on_files_copied_sorted(p_from,p_to);
+ }
+}
+
+void file_operation_callback::g_on_files_deleted(const pfc::list_base_const_t<const char *> & p_items)
+{
+ core_api::ensure_main_thread();
+ t_size count = p_items.get_count();
+ if (count > 0)
+ {
+ if (count == 1) g_on_files_deleted_sorted(p_items);
+ else
+ {
+ pfc::array_t<t_size> order; order.set_size(count);
+ order_helper::g_fill(order);
+ p_items.sort_get_permutation_t(metadb::path_compare,order.get_ptr());
+ g_on_files_deleted_sorted(pfc::list_permutation_t<const char*>(p_items,order.get_ptr(),count));
+ }
+ }
+}
+
+void file_operation_callback::g_on_files_moved(const pfc::list_base_const_t<const char *> & p_from,const pfc::list_base_const_t<const char *> & p_to)
+{
+ core_api::ensure_main_thread();
+ pfc::dynamic_assert(p_from.get_count() == p_to.get_count());
+ t_size count = p_from.get_count();
+ if (count > 0)
+ {
+ if (count == 1) g_on_files_moved_sorted(p_from,p_to);
+ else
+ {
+ pfc::array_t<t_size> order; order.set_size(count);
+ order_helper::g_fill(order);
+ p_from.sort_get_permutation_t(metadb::path_compare,order.get_ptr());
+ g_on_files_moved_sorted(pfc::list_permutation_t<const char*>(p_from,order.get_ptr(),count),pfc::list_permutation_t<const char*>(p_to,order.get_ptr(),count));
+ }
+ }
+}
+
+void file_operation_callback::g_on_files_copied(const pfc::list_base_const_t<const char *> & p_from,const pfc::list_base_const_t<const char *> & p_to)
+{
+ if (core_api::assert_main_thread())
+ {
+ assert(p_from.get_count() == p_to.get_count());
+ t_size count = p_from.get_count();
+ if (count > 0)
+ {
+ if (count == 1) g_on_files_copied_sorted(p_from,p_to);
+ else
+ {
+ pfc::array_t<t_size> order; order.set_size(count);
+ order_helper::g_fill(order);
+ p_from.sort_get_permutation_t(metadb::path_compare,order.get_ptr());
+ g_on_files_copied_sorted(pfc::list_permutation_t<const char*>(p_from,order.get_ptr(),count),pfc::list_permutation_t<const char*>(p_to,order.get_ptr(),count));
+ }
+ }
+ }
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_operation_callback.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_operation_callback.h
new file mode 100644
index 0000000..f6eba0a
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/file_operation_callback.h
@@ -0,0 +1,25 @@
+#ifndef _FILE_OPERATION_CALLBACK_H_
+#define _FILE_OPERATION_CALLBACK_H_
+
+//! Interface to notify component system about files being deleted or moved. Operates in app's main thread only.
+
+class file_operation_callback : public service_base
+{
+public:
+ //! p_items is a metadb::path_compare sorted list of files that have been deleted.
+ virtual void on_files_deleted_sorted(const pfc::list_base_const_t<const char *> & p_items) = 0;
+ //! p_from is a metadb::path_compare sorted list of files that have been moved, p_to is a list of corresponding target locations.
+ virtual void on_files_moved_sorted(const pfc::list_base_const_t<const char *> & p_from,const pfc::list_base_const_t<const char *> & p_to) = 0;
+ //! p_from is a metadb::path_compare sorted list of files that have been copied, p_to is a list of corresponding target locations.
+ virtual void on_files_copied_sorted(const pfc::list_base_const_t<const char *> & p_from,const pfc::list_base_const_t<const char *> & p_to) = 0;
+
+ static void g_on_files_deleted(const pfc::list_base_const_t<const char *> & p_items);
+ static void g_on_files_moved(const pfc::list_base_const_t<const char *> & p_from,const pfc::list_base_const_t<const char *> & p_to);
+ static void g_on_files_copied(const pfc::list_base_const_t<const char *> & p_from,const pfc::list_base_const_t<const char *> & p_to);
+
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(file_operation_callback);
+};
+
+
+#endif //_FILE_OPERATION_CALLBACK_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem.cpp
new file mode 100644
index 0000000..950e8fd
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem.cpp
@@ -0,0 +1,821 @@
+#include "foobar2000.h"
+
+
+void unpacker::g_open(service_ptr_t<file> & p_out,const service_ptr_t<file> & p,abort_callback & p_abort)
+{
+ service_enum_t<unpacker> e;
+ service_ptr_t<unpacker> ptr;
+ if (e.first(ptr)) do {
+ p->reopen(p_abort);
+ try {
+ ptr->open(p_out,p,p_abort);
+ return;
+ } catch(exception_io_data const &) {}
+ } while(e.next(ptr));
+ throw exception_io_data();
+}
+
+void file::seek_ex(t_sfilesize p_position, file::t_seek_mode p_mode, abort_callback &p_abort) {
+ switch(p_mode) {
+ case seek_from_beginning:
+ seek(p_position,p_abort);
+ break;
+ case seek_from_current:
+ seek(p_position + get_position(p_abort),p_abort);
+ break;
+ case seek_from_eof:
+ seek(p_position + get_size_ex(p_abort),p_abort);
+ break;
+ default:
+ throw exception_io_data();
+ }
+}
+
+t_filesize file::g_transfer(stream_reader * p_src,stream_writer * p_dst,t_filesize p_bytes,abort_callback & p_abort) {
+ enum {BUFSIZE = 1024*1024*8};
+ pfc::array_t<t_uint8> temp;
+ temp.set_size((t_size)pfc::min_t<t_filesize>(BUFSIZE,p_bytes));
+ void* ptr = temp.get_ptr();
+ t_filesize done = 0;
+ while(done<p_bytes) {
+ p_abort.check_e();
+ t_size delta = (t_size)pfc::min_t<t_filesize>(BUFSIZE,p_bytes-done);
+ delta = p_src->read(ptr,delta,p_abort);
+ if (delta<=0) break;
+ p_dst->write(ptr,delta,p_abort);
+ done += delta;
+ }
+ return done;
+}
+
+void file::g_transfer_object(stream_reader * p_src,stream_writer * p_dst,t_filesize p_bytes,abort_callback & p_abort) {
+ if (g_transfer(p_src,p_dst,p_bytes,p_abort) != p_bytes)
+ throw exception_io_data_truncation();
+}
+
+
+void filesystem::g_get_canonical_path(const char * path,pfc::string_base & out)
+{
+ TRACK_CALL_TEXT("filesystem::g_get_canonical_path");
+
+ service_enum_t<filesystem> e;
+ service_ptr_t<filesystem> ptr;
+ if (e.first(ptr)) do {
+ if (ptr->get_canonical_path(path,out)) return;
+ } while(e.next(ptr));
+ //no one wants to process this, lets copy over
+ out.set_string(path);
+}
+
+void filesystem::g_get_display_path(const char * path,pfc::string_base & out)
+{
+ TRACK_CALL_TEXT("filesystem::g_get_display_path");
+ service_ptr_t<filesystem> ptr;
+ if (!g_get_interface(ptr,path))
+ {
+ //noone wants to process this, lets copy over
+ out.set_string(path);
+ }
+ else
+ {
+ if (!ptr->get_display_path(path,out))
+ out.set_string(path);
+ }
+}
+
+bool filesystem::g_get_interface(service_ptr_t<filesystem> & p_out,const char * path)
+{
+ service_enum_t<filesystem> e;
+ service_ptr_t<filesystem> ptr;
+ if (e.first(ptr)) do {
+ if (ptr->is_our_path(path))
+ {
+ p_out = ptr;
+ return true;
+ }
+ } while(e.next(ptr));
+ return false;
+}
+
+
+void filesystem::g_open(service_ptr_t<file> & p_out,const char * path,t_open_mode mode,abort_callback & p_abort)
+{
+ TRACK_CALL_TEXT("filesystem::g_open");
+ service_ptr_t<filesystem> fs;
+ if (!g_get_interface(fs,path)) throw exception_io_no_handler_for_path();
+ fs->open(p_out,path,mode,p_abort);
+}
+
+void filesystem::g_open_timeout(service_ptr_t<file> & p_out,const char * p_path,t_open_mode p_mode,double p_timeout,abort_callback & p_abort) {
+ pfc::lores_timer timer;
+ timer.start();
+ for(;;) {
+ try {
+ g_open(p_out,p_path,p_mode,p_abort);
+ break;
+ } catch(exception_io_sharing_violation) {
+ if (timer.query() > p_timeout) throw;
+ p_abort.sleep(0.01);
+ }
+ }
+}
+
+bool filesystem::g_exists(const char * p_path,abort_callback & p_abort)
+{
+ t_filestats stats;
+ bool dummy;
+ try {
+ g_get_stats(p_path,stats,dummy,p_abort);
+ } catch(exception_io_not_found) {return false;}
+ return true;
+}
+
+bool filesystem::g_exists_writeable(const char * p_path,abort_callback & p_abort)
+{
+ t_filestats stats;
+ bool writeable;
+ try {
+ g_get_stats(p_path,stats,writeable,p_abort);
+ } catch(exception_io_not_found) {return false;}
+ return writeable;
+}
+
+void filesystem::g_remove(const char * p_path,abort_callback & p_abort) {
+ service_ptr_t<filesystem> fs;
+ if (!g_get_interface(fs,p_path)) throw exception_io_no_handler_for_path();
+ fs->remove(p_path,p_abort);
+}
+
+void filesystem::g_remove_timeout(const char * p_path,double p_timeout,abort_callback & p_abort) {
+ pfc::lores_timer timer;
+ timer.start();
+ for(;;) {
+ try {
+ g_remove(p_path,p_abort);
+ break;
+ } catch(exception_io_sharing_violation) {
+ if (timer.query() > p_timeout) throw;
+ p_abort.sleep(0.01);
+ }
+ }
+}
+
+void filesystem::g_move_timeout(const char * p_src,const char * p_dst,double p_timeout,abort_callback & p_abort) {
+ pfc::lores_timer timer;
+ timer.start();
+ for(;;) {
+ try {
+ g_move(p_src,p_dst,p_abort);
+ break;
+ } catch(exception_io_sharing_violation) {
+ if (timer.query() > p_timeout) throw;
+ p_abort.sleep(0.01);
+ }
+ }
+}
+
+void filesystem::g_copy_timeout(const char * p_src,const char * p_dst,double p_timeout,abort_callback & p_abort) {
+ pfc::lores_timer timer;
+ timer.start();
+ for(;;) {
+ try {
+ g_copy(p_src,p_dst,p_abort);
+ break;
+ } catch(exception_io_sharing_violation) {
+ if (timer.query() > p_timeout) throw;
+ p_abort.sleep(0.01);
+ }
+ }
+}
+
+void filesystem::g_create_directory(const char * p_path,abort_callback & p_abort)
+{
+ service_ptr_t<filesystem> fs;
+ if (!g_get_interface(fs,p_path)) throw exception_io_no_handler_for_path();
+ fs->create_directory(p_path,p_abort);
+}
+
+void filesystem::g_move(const char * src,const char * dst,abort_callback & p_abort) {
+ service_enum_t<filesystem> e;
+ service_ptr_t<filesystem> ptr;
+ if (e.first(ptr)) do {
+ if (ptr->is_our_path(src) && ptr->is_our_path(dst)) {
+ ptr->move(src,dst,p_abort);
+ return;
+ }
+ } while(e.next(ptr));
+ throw exception_io_no_handler_for_path();
+}
+
+void filesystem::g_list_directory(const char * p_path,directory_callback & p_out,abort_callback & p_abort)
+{
+ service_ptr_t<filesystem> ptr;
+ if (!g_get_interface(ptr,p_path)) throw exception_io_no_handler_for_path();
+ ptr->list_directory(p_path,p_out,p_abort);
+}
+
+
+static void path_pack_string(pfc::string_base & out,const char * src)
+{
+ out.add_char('|');
+ out << strlen(src);
+ out.add_char('|');
+ out << src;
+ out.add_char('|');
+}
+
+static int path_unpack_string(pfc::string8 & out,const char * src)
+{
+ int ptr=0;
+ if (src[ptr++]!='|') return -1;
+ int len = atoi(src+ptr);
+ if (len<=0) return -1;
+ while(src[ptr]!=0 && src[ptr]!='|') ptr++;
+ if (src[ptr]!='|') return -1;
+ ptr++;
+ int start = ptr;
+ while(ptr-start<len)
+ {
+ if (src[ptr]==0) return -1;
+ ptr++;
+ }
+ if (src[ptr]!='|') return -1;
+ out.add_string(&src[start],len);
+ ptr++;
+ return ptr;
+}
+
+
+void filesystem::g_open_precache(service_ptr_t<file> & p_out,const char * p_path,abort_callback & p_abort) {
+ service_ptr_t<filesystem> fs;
+ if (!g_get_interface(fs,p_path)) throw exception_io_no_handler_for_path();
+ if (fs->is_remote(p_path)) throw exception_io_object_is_remote();
+ fs->open(p_out,p_path,open_mode_read,p_abort);
+}
+
+bool filesystem::g_is_remote(const char * p_path) {
+ service_ptr_t<filesystem> fs;
+ if (g_get_interface(fs,p_path)) return fs->is_remote(p_path);
+ else throw exception_io_no_handler_for_path();
+}
+
+bool filesystem::g_is_remote_safe(const char * p_path) {
+ service_ptr_t<filesystem> fs;
+ if (g_get_interface(fs,p_path)) return fs->is_remote(p_path);
+ else return false;
+}
+
+bool filesystem::g_is_remote_or_unrecognized(const char * p_path) {
+ service_ptr_t<filesystem> fs;
+ if (g_get_interface(fs,p_path)) return fs->is_remote(p_path);
+ else return true;
+}
+
+bool filesystem::g_relative_path_create(const char * file_path,const char * playlist_path,pfc::string_base & out)
+{
+
+ bool rv = false;
+ service_ptr_t<filesystem> fs;
+
+ if (g_get_interface(fs,file_path))
+ rv = fs->relative_path_create(file_path,playlist_path,out);
+
+ return rv;
+}
+
+bool filesystem::g_relative_path_parse(const char * relative_path,const char * playlist_path,pfc::string_base & out)
+{
+ service_enum_t<filesystem> e;
+ service_ptr_t<filesystem> ptr;
+ if (e.first(ptr)) do {
+ if (ptr->relative_path_parse(relative_path,playlist_path,out)) return true;
+ } while(e.next(ptr));
+ return false;
+}
+
+
+
+bool archive_impl::get_canonical_path(const char * path,pfc::string_base & out)
+{
+ if (is_our_path(path))
+ {
+ pfc::string8 archive,file,archive_canonical;
+ if (g_parse_unpack_path(path,archive,file))
+ {
+ g_get_canonical_path(archive,archive_canonical);
+ make_unpack_path(out,archive_canonical,file);
+
+ return true;
+ }
+ else return false;
+ }
+ else return false;
+}
+
+bool archive_impl::is_our_path(const char * path)
+{
+ if (strncmp(path,"unpack://",9)) return false;
+ const char * type = get_archive_type();
+ path += 9;
+ while(*type)
+ {
+ if (*type!=*path) return false;
+ type++;
+ path++;
+ }
+ if (*path!='|') return false;
+ return true;
+}
+
+bool archive_impl::get_display_path(const char * path,pfc::string_base & out)
+{
+ pfc::string8 archive,file;
+ if (g_parse_unpack_path(path,archive,file))
+ {
+ g_get_display_path(archive,out);
+ out.add_string("|");
+ out.add_string(file);
+ return true;
+ }
+ else return false;
+}
+
+void archive_impl::open(service_ptr_t<file> & p_out,const char * path,t_open_mode mode, abort_callback & p_abort)
+{
+ if (mode != open_mode_read) throw exception_io_denied();
+ pfc::string8 archive,file;
+ if (!g_parse_unpack_path(path,archive,file)) throw exception_io_not_found();
+ open_archive(p_out,archive,file,p_abort);
+}
+
+
+void archive_impl::remove(const char * path,abort_callback & p_abort) {
+ throw exception_io_denied();
+}
+
+void archive_impl::move(const char * src,const char * dst,abort_callback & p_abort) {
+ throw exception_io_denied();
+}
+
+bool archive_impl::is_remote(const char * src) {
+ pfc::string8 archive,file;
+ if (g_parse_unpack_path(src,archive,file)) return g_is_remote(archive);
+ else throw exception_io_not_found();
+}
+
+bool archive_impl::relative_path_create(const char * file_path,const char * playlist_path,pfc::string_base & out) {
+ pfc::string8 archive,file;
+ if (g_parse_unpack_path(file_path,archive,file))
+ {
+ pfc::string8 archive_rel;
+ if (g_relative_path_create(archive,playlist_path,archive_rel))
+ {
+ pfc::string8 out_path;
+ make_unpack_path(out_path,archive_rel,file);
+ out.set_string(out_path);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool archive_impl::relative_path_parse(const char * relative_path,const char * playlist_path,pfc::string_base & out)
+{
+ if (!is_our_path(relative_path)) return false;
+ pfc::string8 archive_rel,file;
+ if (g_parse_unpack_path(relative_path,archive_rel,file))
+ {
+ pfc::string8 archive;
+ if (g_relative_path_parse(archive_rel,playlist_path,archive))
+ {
+ pfc::string8 out_path;
+ make_unpack_path(out_path,archive,file);
+ out.set_string(out_path);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool archive_impl::g_parse_unpack_path(const char * path,pfc::string8 & archive,pfc::string8 & file)
+{
+ path = strchr(path,'|');
+ if (!path) return false;
+ int delta = path_unpack_string(archive,path);
+ if (delta<0) return false;
+ path += delta;
+ file = path;
+ return true;
+}
+
+void archive_impl::g_make_unpack_path(pfc::string_base & path,const char * archive,const char * file,const char * name)
+{
+ path = "unpack://";
+ path += name;
+ path_pack_string(path,archive);
+ path += file;
+}
+
+void archive_impl::make_unpack_path(pfc::string_base & path,const char * archive,const char * file) {g_make_unpack_path(path,archive,file,get_archive_type());}
+
+
+FILE * filesystem::streamio_open(const char * path,const char * flags)
+{
+ FILE * ret = 0;
+ pfc::string8 temp;
+ g_get_canonical_path(path,temp);
+ if (!strncmp(temp,"file://",7))
+ {
+ ret = _wfopen(pfc::stringcvt::string_wide_from_utf8(path+7),pfc::stringcvt::string_wide_from_utf8(flags));
+ }
+ return ret;
+}
+
+
+namespace {
+
+ class directory_callback_isempty : public directory_callback
+ {
+ bool m_isempty;
+ public:
+ directory_callback_isempty() : m_isempty(true) {}
+ bool on_entry(filesystem * owner,abort_callback & p_abort,const char * url,bool is_subdirectory,const t_filestats & p_stats)
+ {
+ m_isempty = false;
+ return false;
+ }
+ bool isempty() {return m_isempty;}
+ };
+
+ class directory_callback_dummy : public directory_callback
+ {
+ public:
+ bool on_entry(filesystem * owner,abort_callback & p_abort,const char * url,bool is_subdirectory,const t_filestats & p_stats) {return false;}
+ };
+
+}
+
+bool filesystem::g_is_empty_directory(const char * path,abort_callback & p_abort)
+{
+ directory_callback_isempty callback;
+ try {
+ g_list_directory(path,callback,p_abort);
+ } catch(exception_io const &) {return false;}
+ return callback.isempty();
+}
+
+bool filesystem::g_is_valid_directory(const char * path,abort_callback & p_abort) {
+ try {
+ g_list_directory(path,directory_callback_dummy(),p_abort);
+ return true;
+ } catch(exception_io const &) {return false;}
+}
+
+bool directory_callback_impl::on_entry(filesystem * owner,abort_callback & p_abort,const char * url,bool is_subdirectory,const t_filestats & p_stats) {
+ p_abort.check_e();
+ if (is_subdirectory) {
+ if (m_recur) {
+ try {
+ owner->list_directory(url,*this,p_abort);
+ } catch(exception_io const &) {}
+ }
+ } else {
+ m_data.add_item(pfc::rcnew_t<t_entry>(url,p_stats));
+ }
+ return true;
+}
+
+namespace {
+ class directory_callback_impl_copy : public directory_callback
+ {
+ public:
+ directory_callback_impl_copy(const char * p_target)
+ {
+ m_target = p_target;
+ m_target.fix_dir_separator('\\');
+ }
+
+ bool on_entry(filesystem * owner,abort_callback & p_abort,const char * url,bool is_subdirectory,const t_filestats & p_stats) {
+ const char * fn = url + pfc::scan_filename(url);
+ t_size truncat = m_target.length();
+ m_target += fn;
+ if (is_subdirectory) {
+ try {
+ filesystem::g_create_directory(m_target,p_abort);
+ } catch(exception_io_already_exists) {}
+ m_target += "\\";
+ owner->list_directory(url,*this,p_abort);
+ } else {
+ filesystem::g_copy(url,m_target,p_abort);
+ }
+ m_target.truncate(truncat);
+ return true;
+ }
+ private:
+ pfc::string8_fastalloc m_target;
+// t_io_result m_status;
+ };
+}
+
+void filesystem::g_copy_directory(const char * src,const char * dst,abort_callback & p_abort) {
+ //UNTESTED
+ filesystem::g_list_directory(src,directory_callback_impl_copy(dst),p_abort);
+}
+
+void filesystem::g_copy(const char * src,const char * dst,abort_callback & p_abort) {
+ service_ptr_t<file> r_src,r_dst;
+ t_filesize size;
+
+ g_open(r_src,src,open_mode_read,p_abort);
+ size = r_src->get_size_ex(p_abort);
+ g_open(r_dst,dst,open_mode_write_new,p_abort);
+
+ if (size > 0) {
+ try {
+ file::g_transfer_object(r_src,r_dst,size,p_abort);
+ } catch(std::exception) {
+ r_dst.release();
+ try {g_remove(dst,abort_callback_impl());} catch(std::exception) {}
+ throw;
+ }
+ }
+}
+
+void stream_reader::read_object(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ if (read(p_buffer,p_bytes,p_abort) != p_bytes) throw exception_io_data_truncation();
+}
+
+t_filestats file::get_stats(abort_callback & p_abort)
+{
+ t_filestats temp;
+ temp.m_size = get_size(p_abort);
+ temp.m_timestamp = get_timestamp(p_abort);
+ return temp;
+}
+
+t_filesize stream_reader::skip(t_filesize p_bytes,abort_callback & p_abort)
+{
+ t_uint8 temp[256];
+ t_filesize todo = p_bytes, done = 0;
+ while(todo > 0) {
+ t_size delta,deltadone;
+ delta = sizeof(temp);
+ if (delta > todo) delta = (t_size) todo;
+ deltadone = read(temp,delta,p_abort);
+ done += deltadone;
+ todo -= deltadone;
+ if (deltadone < delta) break;
+ }
+ return done;
+}
+
+void stream_reader::skip_object(t_filesize p_bytes,abort_callback & p_abort) {
+ if (skip(p_bytes,p_abort) != p_bytes) throw exception_io_data_truncation();
+}
+
+void filesystem::g_open_write_new(service_ptr_t<file> & p_out,const char * p_path,abort_callback & p_abort) {
+ g_open(p_out,p_path,open_mode_write_new,p_abort);
+}
+void file::g_transfer_file(const service_ptr_t<file> & p_from,const service_ptr_t<file> & p_to,abort_callback & p_abort) {
+ t_filesize length = p_from->get_size_ex(p_abort);
+ p_from->seek(0,p_abort);
+ p_to->seek(0,p_abort);
+ p_to->set_eof(p_abort);
+ if (length > 0) {
+ g_transfer_object(p_from,p_to,length,p_abort);
+ }
+}
+
+void filesystem::g_open_temp(service_ptr_t<file> & p_out,abort_callback & p_abort) {
+ g_open(p_out,"tempfile://",open_mode_write_new,p_abort);
+}
+
+void filesystem::g_open_tempmem(service_ptr_t<file> & p_out,abort_callback & p_abort) {
+ g_open(p_out,"tempmem://",open_mode_write_new,p_abort);
+}
+
+void archive_impl::list_directory(const char * p_path,directory_callback & p_out,abort_callback & p_abort) {
+ throw exception_io_not_found();
+}
+
+void archive_impl::create_directory(const char * path,abort_callback &) {
+ throw exception_io_denied();
+}
+
+void filesystem::g_get_stats(const char * p_path,t_filestats & p_stats,bool & p_is_writeable,abort_callback & p_abort) {
+ TRACK_CALL_TEXT("filesystem::g_get_stats");
+ service_ptr_t<filesystem> fs;
+ if (!g_get_interface(fs,p_path)) throw exception_io_no_handler_for_path();
+ return fs->get_stats(p_path,p_stats,p_is_writeable,p_abort);
+}
+
+void archive_impl::get_stats(const char * p_path,t_filestats & p_stats,bool & p_is_writeable,abort_callback & p_abort) {
+ pfc::string8 archive,file;
+ if (g_parse_unpack_path(p_path,archive,file)) {
+ if (g_is_remote(archive)) throw exception_io_object_is_remote();
+ p_is_writeable = false;
+ p_stats = get_stats_in_archive(archive,file,p_abort);
+ }
+ else throw exception_io_not_found();
+}
+
+
+bool file::is_eof(abort_callback & p_abort) {
+ t_filesize position,size;
+ position = get_position(p_abort);
+ size = get_size(p_abort);
+ if (size == filesize_invalid) return false;
+ return position >= size;
+}
+
+
+t_filetimestamp foobar2000_io::filetimestamp_from_system_timer()
+{
+ t_filetimestamp ret;
+ GetSystemTimeAsFileTime((FILETIME*)&ret);
+ return ret;
+}
+
+void stream_reader::read_string_ex(pfc::string_base & p_out,t_size p_bytes,abort_callback & p_abort) {
+ char * ptr = p_out.lock_buffer(p_bytes);
+ try {
+ read_object(ptr,p_bytes,p_abort);
+ } catch(...) {
+ p_out.unlock_buffer();
+ throw;
+ }
+ p_out.unlock_buffer();
+}
+void stream_reader::read_string(pfc::string_base & p_out,abort_callback & p_abort)
+{
+ t_uint32 length;
+ read_lendian_t(length,p_abort);
+ read_string_ex(p_out,length,p_abort);
+}
+
+void stream_reader::read_string_raw(pfc::string_base & p_out,abort_callback & p_abort) {
+ enum {delta = 256};
+ char buffer[delta];
+ p_out.reset();
+ for(;;) {
+ t_size delta_done;
+ delta_done = read(buffer,delta,p_abort);
+ p_out.add_string(buffer,delta_done);
+ if (delta_done < delta) break;
+ }
+}
+
+void stream_writer::write_string(const char * p_string,abort_callback & p_abort) {
+ t_uint32 len = pfc::downcast_guarded<t_uint32>(strlen(p_string));
+ write_lendian_t(len,p_abort);
+ write_object(p_string,len,p_abort);
+}
+
+void stream_writer::write_string_raw(const char * p_string,abort_callback & p_abort) {
+ write_object(p_string,strlen(p_string),p_abort);
+}
+
+void file::truncate(t_uint64 p_position,abort_callback & p_abort) {
+ if (p_position < get_size(p_abort)) resize(p_position,p_abort);
+}
+
+
+format_filetimestamp::format_filetimestamp(t_filetimestamp p_timestamp) {
+#ifdef _WIN32
+ SYSTEMTIME st; FILETIME ft;
+ if (FileTimeToLocalFileTime((FILETIME*)&p_timestamp,&ft)) {
+ if (FileTimeToSystemTime(&ft,&st)) {
+ m_buffer
+ << pfc::format_uint(st.wYear,4) << "-" << pfc::format_uint(st.wMonth,2) << "-" << pfc::format_uint(st.wDay,2) << " "
+ << pfc::format_uint(st.wHour,2) << ":" << pfc::format_uint(st.wMinute,2) << ":" << pfc::format_uint(st.wSecond,2);
+ } else m_buffer << "<invalid timestamp>";
+ } else m_buffer << "<invalid timestamp>";
+#else
+#error portme
+#endif
+}
+
+#ifdef _WIN32
+namespace {
+ //rare/weird win32 errors that didn't make it to the main API
+ PFC_DECLARE_EXCEPTION(exception_io_device_not_ready, exception_io,"Device not ready");
+ PFC_DECLARE_EXCEPTION(exception_io_invalid_drive, exception_io_not_found,"Drive not found");
+ PFC_DECLARE_EXCEPTION(exception_io_win32, exception_io,"Generic win32 I/O error");
+ PFC_DECLARE_EXCEPTION(exception_io_buffer_overflow, exception_io,"The file name is too long");
+
+ class exception_io_win32_ex : public exception_io_win32 {
+ public:
+ exception_io_win32_ex(DWORD p_code) : m_msg(pfc::string_formatter() << "I/O error (win32 #" << (t_uint32)p_code << ")") {}
+ exception_io_win32_ex(const exception_io_win32_ex & p_other) {*this = p_other;}
+ const char * what() const throw() {return m_msg;}
+ private:
+ pfc::string8 m_msg;
+ };
+}
+void foobar2000_io::exception_io_from_win32(DWORD p_code) {
+ switch(p_code) {
+ case ERROR_ALREADY_EXISTS:
+ case ERROR_FILE_EXISTS:
+ throw exception_io_already_exists();
+ case ERROR_NETWORK_ACCESS_DENIED:
+ case ERROR_ACCESS_DENIED:
+ throw exception_io_denied();
+ case ERROR_WRITE_PROTECT:
+ throw exception_io_write_protected();
+ case ERROR_BUSY:
+ case ERROR_PATH_BUSY:
+ case ERROR_SHARING_VIOLATION:
+ case ERROR_LOCK_VIOLATION:
+ throw exception_io_sharing_violation();
+ case ERROR_HANDLE_DISK_FULL:
+ case ERROR_DISK_FULL:
+ throw exception_io_device_full();
+ case ERROR_FILE_NOT_FOUND:
+ case ERROR_PATH_NOT_FOUND:
+ throw exception_io_not_found();
+ case ERROR_BROKEN_PIPE:
+ case ERROR_NO_DATA:
+ throw exception_io_no_data();
+ case ERROR_NETWORK_UNREACHABLE:
+ case ERROR_NETNAME_DELETED:
+ throw exception_io_network_not_reachable();
+ case ERROR_NOT_READY:
+ throw exception_io_device_not_ready();
+ case ERROR_INVALID_DRIVE:
+ throw exception_io_invalid_drive();
+ case ERROR_CRC:
+ case ERROR_FILE_CORRUPT:
+ case ERROR_DISK_CORRUPT:
+ throw exception_io_file_corrupted();
+ case ERROR_BUFFER_OVERFLOW:
+ throw exception_io_buffer_overflow();
+ case ERROR_DISK_CHANGE:
+ throw exception_io_disk_change();
+ default:
+ throw exception_io_win32_ex(p_code);
+ }
+}
+#endif
+
+t_filesize file::get_size_ex(abort_callback & p_abort) {
+ t_filesize temp = get_size(p_abort);
+ if (temp == filesize_invalid) throw exception_io_no_length();
+ return temp;
+}
+
+void file::ensure_local() {
+ if (is_remote()) throw exception_io_object_is_remote();
+}
+
+void file::ensure_seekable() {
+ if (!can_seek()) throw exception_io_object_not_seekable();
+}
+
+bool filesystem::g_is_recognized_path(const char * p_path) {
+ return g_get_interface(service_ptr_t<filesystem>(),p_path);
+}
+
+t_filesize file::get_remaining(abort_callback & p_abort) {
+ t_filesize length = get_size_ex(p_abort);
+ t_filesize position = get_position(p_abort);
+ pfc::dynamic_assert(position <= length);
+ return length - position;
+}
+
+
+t_filesize file::g_transfer(service_ptr_t<file> p_src,service_ptr_t<file> p_dst,t_filesize p_bytes,abort_callback & p_abort) {
+ return g_transfer(pfc::safe_cast<stream_reader*>(p_src.get_ptr()),pfc::safe_cast<stream_writer*>(p_dst.get_ptr()),p_bytes,p_abort);
+}
+
+void file::g_transfer_object(service_ptr_t<file> p_src,service_ptr_t<file> p_dst,t_filesize p_bytes,abort_callback & p_abort) {
+ if (p_bytes > 1024) /* don't bother on small objects */
+ {
+ t_filesize oldsize = p_dst->get_size(p_abort);
+ if (oldsize != filesize_invalid) {
+ t_filesize newpos = p_dst->get_position(p_abort) + p_bytes;
+ if (newpos > oldsize) p_dst->resize(newpos ,p_abort);
+ }
+ }
+ g_transfer_object(pfc::safe_cast<stream_reader*>(p_src.get_ptr()),pfc::safe_cast<stream_writer*>(p_dst.get_ptr()),p_bytes,p_abort);
+}
+
+
+void foobar2000_io::generate_temp_location_for_file(pfc::string_base & p_out, const char * p_origpath,const char * p_extension,const char * p_magic) {
+ hasher_md5_result hash;
+ {
+ static_api_ptr_t<hasher_md5> hasher;
+ hasher_md5_state state;
+ hasher->initialize(state);
+ hasher->process(state,p_origpath,strlen(p_origpath));
+ hasher->process(state,p_extension,strlen(p_extension));
+ hasher->process(state,p_magic,strlen(p_magic));
+ hash = hasher->get_result(state);
+ }
+
+ p_out = p_origpath;
+ p_out.truncate(p_out.scan_filename());
+ p_out += "temp-";
+ p_out += pfc::format_hexdump(hash.m_data,sizeof(hash.m_data),"");
+ p_out += ".";
+ p_out += p_extension;
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem.h
new file mode 100644
index 0000000..0960bd4
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem.h
@@ -0,0 +1,494 @@
+#ifndef _FOOBAR2000_SDK_FILESYSTEM_H_
+#define _FOOBAR2000_SDK_FILESYSTEM_H_
+
+class playlist_loader_callback;
+class file_info;
+
+//! Contains various I/O related structures and interfaces.
+
+namespace foobar2000_io
+{
+ //! Type used for file size related variables.
+ typedef t_uint64 t_filesize;
+ //! Type used for file size related variables when signed value is needed.
+ typedef t_int64 t_sfilesize;
+ //! Type used for file timestamp related variables. 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601; 0 for invalid/unknown time.
+ typedef t_uint64 t_filetimestamp;
+ //! Invalid/unknown file timestamp constant. Also see: t_filetimestamp.
+ const t_filetimestamp filetimestamp_invalid = 0;
+ //! Invalid/unknown file size constant. Also see: t_filesize.
+ const t_filesize filesize_invalid = (t_filesize)(~0);
+
+ //! Generic I/O error. Root class for I/O failure exception. See relevant default message for description of each derived exception class.
+ PFC_DECLARE_EXCEPTION(exception_io, pfc::exception,"I/O error");
+ //! Object not found.
+ PFC_DECLARE_EXCEPTION(exception_io_not_found, exception_io,"Object not found");
+ //! Access denied.
+ PFC_DECLARE_EXCEPTION(exception_io_denied, exception_io,"Access denied");
+ //! Unsupported format or corrupted file (unexpected data encountered).
+ PFC_DECLARE_EXCEPTION(exception_io_data, exception_io,"Unsupported format or corrupted file");
+ //! Unsupported format or corrupted file (truncation encountered).
+ PFC_DECLARE_EXCEPTION(exception_io_data_truncation, exception_io_data,"Unsupported format or corrupted file");
+ //! Unsupported format (a subclass of "unsupported format or corrupted file" exception).
+ PFC_DECLARE_EXCEPTION(exception_io_unsupported_format, exception_io_data,"Unsupported file format");
+ //! Object is remote, while specific operation is supported only for local objects.
+ PFC_DECLARE_EXCEPTION(exception_io_object_is_remote, exception_io,"This operation is not supported on remote objects");
+ //! Sharing violation.
+ PFC_DECLARE_EXCEPTION(exception_io_sharing_violation, exception_io,"Sharing violation");
+ //! Device full.
+ PFC_DECLARE_EXCEPTION(exception_io_device_full, exception_io,"Device full");
+ //! Attempt to seek outside valid range.
+ PFC_DECLARE_EXCEPTION(exception_io_seek_out_of_range, exception_io,"Seek offset out of range");
+ //! This operation requires a seekable object.
+ PFC_DECLARE_EXCEPTION(exception_io_object_not_seekable, exception_io,"Object is not seekable");
+ //! This operation requires an object with known length.
+ PFC_DECLARE_EXCEPTION(exception_io_no_length, exception_io,"Length of object is unknown");
+ //! Invalid path.
+ PFC_DECLARE_EXCEPTION(exception_io_no_handler_for_path, exception_io,"Invalid path");
+ //! Object already exists.
+ PFC_DECLARE_EXCEPTION(exception_io_already_exists, exception_io,"Object already exists");
+ //! Pipe error.
+ PFC_DECLARE_EXCEPTION(exception_io_no_data, exception_io,"The process receiving or sending data has terminated");
+ //! Network not reachable.
+ PFC_DECLARE_EXCEPTION(exception_io_network_not_reachable,exception_io,"Network not reachable");
+ //! Media is write protected.
+ PFC_DECLARE_EXCEPTION(exception_io_write_protected, exception_io_denied,"The media is write protected");
+ //! File is corrupted. This indicates filesystem call failure, not actual invalid data being read by the app.
+ PFC_DECLARE_EXCEPTION(exception_io_file_corrupted, exception_io,"The file is corrupted");
+ //! The disc required for requested operation is not available.
+ PFC_DECLARE_EXCEPTION(exception_io_disk_change, exception_io,"Disc not available");
+
+ //! Stores file stats (size and timestamp).
+ struct t_filestats {
+ //! Size of the file.
+ t_filesize m_size;
+ //! Time of last file modification.
+ t_filetimestamp m_timestamp;
+
+ inline bool operator==(const t_filestats & param) const {return m_size == param.m_size && m_timestamp == param.m_timestamp;}
+ inline bool operator!=(const t_filestats & param) const {return m_size != param.m_size || m_timestamp != param.m_timestamp;}
+ };
+
+ //! Invalid/unknown file stats constant. See: t_filestats.
+ static const t_filestats filestats_invalid = {filesize_invalid,filetimestamp_invalid};
+
+#ifdef _WIN32
+ void exception_io_from_win32(DWORD p_code);
+#endif
+
+ //! Generic interface to read data from a nonseekable stream. Also see: stream_writer, file. \n
+ //! Error handling: all methods may throw exception_io or one of derivatives on failure; exception_aborted when abort_callback is signaled.
+ class NOVTABLE stream_reader {
+ public:
+ //! Attempts to reads specified number of bytes from the stream.
+ //! @param p_buffer Receives data being read. Must have at least p_bytes bytes of space allocated.
+ //! @param p_bytes Number of bytes to read.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ //! @returns Number of bytes actually read. May be less than requested when EOF was reached.
+ virtual t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) = 0;
+ //! Reads specified number of bytes from the stream. If requested amount of bytes can't be read (e.g. EOF), throws exception_io_data_truncation.
+ //! @param p_buffer Receives data being read. Must have at least p_bytes bytes of space allocated.
+ //! @param p_bytes Number of bytes to read.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void read_object(void * p_buffer,t_size p_bytes,abort_callback & p_abort);
+ //! Attempts to skip specified number of bytes in the stream.
+ //! @param p_bytes Number of bytes to skip.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ //! @returns Number of bytes actually skipped, May be less than requested when EOF was reached.
+ virtual t_filesize skip(t_filesize p_bytes,abort_callback & p_abort);
+ //! Skips specified number of bytes in the stream. If requested amount of bytes can't be skipped (e.g. EOF), throws exception_io_data_truncation.
+ //! @param p_bytes Number of bytes to skip.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void skip_object(t_filesize p_bytes,abort_callback & p_abort);
+
+ //! Helper template built around read_object. Reads single raw object from the stream.
+ //! @param p_object Receives object read from the stream on success.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ template<typename T> inline void read_object_t(T& p_object,abort_callback & p_abort) {pfc::assert_raw_type<T>(); read_object(&p_object,sizeof(p_object),p_abort);}
+ //! Helper template built around read_object. Reads single raw object from the stream; corrects byte order assuming stream uses little endian order.
+ //! @param p_object Receives object read from the stream on success.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ template<typename T> inline void read_lendian_t(T& p_object,abort_callback & p_abort) {read_object_t(p_object,p_abort); byte_order::order_le_to_native_t(p_object);}
+ //! Helper template built around read_object. Reads single raw object from the stream; corrects byte order assuming stream uses big endian order.
+ //! @param p_object Receives object read from the stream on success.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ template<typename T> inline void read_bendian_t(T& p_object,abort_callback & p_abort) {read_object_t(p_object,p_abort); byte_order::order_be_to_native_t(p_object);}
+
+ //! Helper function; reads string (with 32-bit header indicating length in bytes followed by UTF-8 encoded data without null terminator).
+ void read_string(pfc::string_base & p_out,abort_callback & p_abort);
+ //! Helper function; alternate way of storing strings; assumes string takes space up to end of stream.
+ void read_string_raw(pfc::string_base & p_out,abort_callback & p_abort);
+
+ //! Helper function; reads string of specified length from the stream.
+ void read_string_ex(pfc::string_base & p_out,t_size p_bytes,abort_callback & p_abort);
+ protected:
+ stream_reader() {}
+ ~stream_reader() {}
+ };
+
+
+ //! Generic interface to write data to a nonseekable stream. Also see: stream_reader, file. \n
+ //! Error handling: all methods may throw exception_io or one of derivatives on failure; exception_aborted when abort_callback is signaled.
+ class NOVTABLE stream_writer {
+ public:
+ //! Writes specified number of bytes from specified buffer to the stream.
+ //! @param p_buffer Buffer with data to write. Must contain at least p_bytes bytes.
+ //! @param p_bytes Number of bytes to write.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) = 0;
+
+ //! Helper. Same as write(), provided for consistency.
+ inline void write_object(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {write(p_buffer,p_bytes,p_abort);}
+
+ //! Helper template. Writes single raw object to the stream.
+ //! @param p_object Object to write.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ template<typename T> inline void write_object_t(const T & p_object, abort_callback & p_abort) {pfc::assert_raw_type<T>(); write_object(&p_object,sizeof(p_object),p_abort);}
+ //! Helper template. Writes single raw object to the stream; corrects byte order assuming stream uses little endian order.
+ //! @param p_object Object to write.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ template<typename T> inline void write_lendian_t(const T & p_object, abort_callback & p_abort) {T temp = p_object; byte_order::order_native_to_le_t(temp); write_object_t(temp,p_abort);}
+ //! Helper template. Writes single raw object to the stream; corrects byte order assuming stream uses big endian order.
+ //! @param p_object Object to write.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ template<typename T> inline void write_bendian_t(const T & p_object, abort_callback & p_abort) {T temp = p_object; byte_order::order_native_to_be_t(temp); write_object_t(temp,p_abort);}
+
+ //! Helper function; writes string (with 32-bit header indicating length in bytes followed by UTF-8 encoded data without null terminator).
+ void write_string(const char * p_string,abort_callback & p_abort);
+
+ //! Helper function; writes raw string to the stream, with no length info or null terminators.
+ void write_string_raw(const char * p_string,abort_callback & p_abort);
+ protected:
+ stream_writer() {}
+ ~stream_writer() {}
+ };
+
+ //! A class providing abstraction for an open file object, with reading/writing/seeking methods. See also: stream_reader, stream_writer (which it inherits read/write methods from). \n
+ //! Error handling: all methods may throw exception_io or one of derivatives on failure; exception_aborted when abort_callback is signaled.
+ class NOVTABLE file : public service_base, public stream_reader, public stream_writer {
+ public:
+
+ //! Seeking mode constants. Note: these are purposedly defined to same values as standard C SEEK_* constants
+ enum t_seek_mode {
+ //! Seek relative to beginning of file (same as seeking to absolute offset).
+ seek_from_beginning = 0,
+ //! Seek relative to current position.
+ seek_from_current = 1,
+ //! Seek relative to end of file.
+ seek_from_eof = 2,
+ };
+
+ //! Retrieves size of the file.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ //! @returns File size on success; filesize_invalid if unknown (nonseekable stream etc).
+ virtual t_filesize get_size(abort_callback & p_abort) = 0;
+
+
+ //! Retrieves read/write cursor position in the file. In case of non-seekable stream, this should return number of bytes read so far since open/reopen call.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ //! @returns Read/write cursor position
+ virtual t_filesize get_position(abort_callback & p_abort) = 0;
+
+ //! Resizes file to specified size in bytes.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void resize(t_filesize p_size,abort_callback & p_abort) = 0;
+
+ //! Sets read/write cursor position to specific offset.
+ //! @param p_position position to seek to.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void seek(t_filesize p_position,abort_callback & p_abort) = 0;
+
+
+ //! Sets read/write cursor position to specific offset; extended form allowing seeking relative to current position or to end of file.
+ //! @param p_position Position to seek to; interpretation of this value depends on p_mode parameter.
+ //! @param p_mode Seeking mode; see t_seek_mode enum values for further description.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void seek_ex(t_sfilesize p_position,t_seek_mode p_mode,abort_callback & p_abort);
+
+ //! Returns whether the file is seekable or not. If can_seek() returns false, all seek() or seek_ex() calls will fail; reopen() is still usable on nonseekable streams.
+ virtual bool can_seek() = 0;
+
+ //! Retrieves mime type of the file.
+ //! @param p_out Receives content type string on success.
+ virtual bool get_content_type(pfc::string_base & p_out) = 0;
+
+ //! Hint, returns whether the file is already fully buffered into memory.
+ virtual bool is_in_memory() {return false;}
+
+ //! Optional, called by owner thread before sleeping.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void on_idle(abort_callback & p_abort) {}
+
+ //! Retrieves last modification time of the file.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ //! @returns Last modification time o fthe file; filetimestamp_invalid if N/A.
+ virtual t_filetimestamp get_timestamp(abort_callback & p_abort) {return filetimestamp_invalid;}
+
+ //! Resets non-seekable stream, or seeks to zero on seekable file.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void reopen(abort_callback & p_abort) = 0;
+
+ //! Indicates whether the file is a remote resource and non-sequential access may be slowed down by lag. This is typically returns to true on non-seekable sources but may also return true on seekable sources indicating that seeking is supported but will be relatively slow.
+ virtual bool is_remote() = 0;
+
+ //! Retrieves file stats structure. Usese get_size() and get_timestamp().
+ t_filestats get_stats(abort_callback & p_abort);
+
+ //! Returns whether read/write cursor position is at the end of file.
+ bool is_eof(abort_callback & p_abort);
+
+ //! Truncates file to specified size (while preserving read/write cursor position if possible); uses set_eof().
+ void truncate(t_filesize p_position,abort_callback & p_abort);
+
+ //! Truncates the file at current read/write cursor position.
+ void set_eof(abort_callback & p_abort) {resize(get_position(p_abort),p_abort);}
+
+
+ //! Helper; retrieves size of the file. If size is not available (get_size() returns filesize_invalid), throws exception_io_no_length.
+ t_filesize get_size_ex(abort_callback & p_abort);
+
+ //! Helper; retrieves amount of bytes between read/write cursor position and end of file. Fails when length can't be determined.
+ t_filesize get_remaining(abort_callback & p_abort);
+
+ //! Helper; throws exception_io_object_not_seekable if file is not seekable.
+ void ensure_seekable();
+
+ //! Helper; throws exception_io_object_is_remote if the file is remote.
+ void ensure_local();
+
+ //! Helper; transfers specified number of bytes between streams.
+ //! @returns number of bytes actually transferred. May be less than requested if e.g. EOF is reached.
+ static t_filesize g_transfer(stream_reader * src,stream_writer * dst,t_filesize bytes,abort_callback & p_abort);
+ //! Helper; transfers specified number of bytes between streams. Throws exception if requested number of bytes could not be read (EOF).
+ static void g_transfer_object(stream_reader * src,stream_writer * dst,t_filesize bytes,abort_callback & p_abort);
+ //! Helper; transfers entire file content from one file to another, erasing previous content.
+ static void g_transfer_file(const service_ptr_t<file> & p_from,const service_ptr_t<file> & p_to,abort_callback & p_abort);
+
+ //! Helper; improved performance over g_transfer on streams (avoids disk fragmentation when transferring large blocks).
+ static t_filesize g_transfer(service_ptr_t<file> p_src,service_ptr_t<file> p_dst,t_filesize p_bytes,abort_callback & p_abort);
+ //! Helper; improved performance over g_transfer_file on streams (avoids disk fragmentation when transferring large blocks).
+ static void g_transfer_object(service_ptr_t<file> p_src,service_ptr_t<file> p_dst,t_filesize p_bytes,abort_callback & p_abort);
+
+ FB2K_MAKE_SERVICE_INTERFACE(file,service_base);
+ };
+
+ //! Special hack for shoutcast metadata nonsense handling. Documentme.
+ class file_dynamicinfo : public file {
+ public:
+ //! Retrieves "static" info that doesn't change in the middle of stream, such as station names etc. Returns true on success; false when static info is not available.
+ virtual bool get_static_info(class file_info & p_out) = 0;
+ //! Returns whether dynamic info is available on this stream or not.
+ virtual bool is_dynamic_info_enabled()=0;
+ //! Retrieves dynamic stream info (e.g. online stream track titles). Returns true on success, false when info has not changed since last call.
+ virtual bool get_dynamic_info(class file_info & p_out) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(file_dynamicinfo,file);
+ };
+
+ //! Implementation helper - contains dummy implementations of methods that modify the file
+ template<typename t_base> class file_readonly_t : public t_base {
+ public:
+ void resize(t_filesize p_size,abort_callback & p_abort) {throw exception_io_denied();}
+ void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {throw exception_io_denied();}
+ };
+ typedef file_readonly_t<file> file_readonly;
+
+ class filesystem;
+
+ class NOVTABLE directory_callback {
+ public:
+ //! @returns true to continue enumeration, false to abort.
+ virtual bool on_entry(filesystem * p_owner,abort_callback & p_abort,const char * p_url,bool p_is_subdirectory,const t_filestats & p_stats)=0;
+ };
+
+
+ //! Entrypoint service for all filesystem operations.\n
+ //! Implementation: standard implementations for local filesystem etc are provided by core.\n
+ //! Instantiation: use static helper functions rather than calling filesystem interface methods directly, e.g. filesystem::g_open() to open a file.
+ class NOVTABLE filesystem : public service_base {
+ public:
+ //! Enumeration specifying how to open a file. See: filesystem::open(), filesystem::g_open().
+ enum t_open_mode {
+ //! Opens an existing file for reading; if the file does not exist, the operation will fail.
+ open_mode_read,
+ //! Opens an existing file for writing; if the file does not exist, the operation will fail.
+ open_mode_write_existing,
+ //! Opens a new file for writing; if the file exists, its contents will be wiped.
+ open_mode_write_new,
+ };
+
+ virtual bool get_canonical_path(const char * p_path,pfc::string_base & p_out)=0;
+ virtual bool is_our_path(const char * p_path)=0;
+ virtual bool get_display_path(const char * p_path,pfc::string_base & p_out)=0;
+
+ virtual void open(service_ptr_t<file> & p_out,const char * p_path, t_open_mode p_mode,abort_callback & p_abort)=0;
+ virtual void remove(const char * p_path,abort_callback & p_abort)=0;
+ virtual void move(const char * p_src,const char * p_dst,abort_callback & p_abort)=0;
+ //! Queries whether a file at specified path belonging to this filesystem is a remove object or not.
+ virtual bool is_remote(const char * p_src) = 0;
+
+ //! Retrieves stats of a file at specified path.
+ virtual void get_stats(const char * p_path,t_filestats & p_stats,bool & p_is_writeable,abort_callback & p_abort) = 0;
+
+ virtual bool relative_path_create(const char * file_path,const char * playlist_path,pfc::string_base & out) {return false;}
+ virtual bool relative_path_parse(const char * relative_path,const char * playlist_path,pfc::string_base & out) {return false;}
+
+ //! Creates a directory.
+ virtual void create_directory(const char * p_path,abort_callback & p_abort) = 0;
+
+ virtual void list_directory(const char * p_path,directory_callback & p_out,abort_callback & p_abort)=0;
+
+ //! Hint; returns whether this filesystem supports mime types.
+ virtual bool supports_content_types() = 0;
+
+ static void g_get_canonical_path(const char * path,pfc::string_base & out);
+ static void g_get_display_path(const char * path,pfc::string_base & out);
+
+ static bool g_get_interface(service_ptr_t<filesystem> & p_out,const char * path);//path is AFTER get_canonical_path
+ static bool g_is_remote(const char * p_path);//path is AFTER get_canonical_path
+ static bool g_is_remote_safe(const char * p_path);//path is AFTER get_canonical_path
+ static bool g_is_remote_or_unrecognized(const char * p_path);
+ static bool g_is_recognized_path(const char * p_path);
+
+ //! Opens file at specified path, with specified access privileges.
+ static void g_open(service_ptr_t<file> & p_out,const char * p_path,t_open_mode p_mode,abort_callback & p_abort);
+ //! Attempts to open file at specified path; if the operation fails with sharing violation error, keeps retrying (with short sleep period between retries) for specified amount of time.
+ static void g_open_timeout(service_ptr_t<file> & p_out,const char * p_path,t_open_mode p_mode,double p_timeout,abort_callback & p_abort);
+ static void g_open_write_new(service_ptr_t<file> & p_out,const char * p_path,abort_callback & p_abort);
+ static void g_open_read(service_ptr_t<file> & p_out,const char * path,abort_callback & p_abort) {return g_open(p_out,path,open_mode_read,p_abort);}
+ static void g_open_precache(service_ptr_t<file> & p_out,const char * path,abort_callback & p_abort);//open only for precaching data (eg. will fail on http etc)
+ static bool g_exists(const char * p_path,abort_callback & p_abort);
+ static bool g_exists_writeable(const char * p_path,abort_callback & p_abort);
+ //! Removes file at specified path.
+ static void g_remove(const char * p_path,abort_callback & p_abort);
+ //! Attempts to remove file at specified path; if the operation fails with a sharing violation error, keeps retrying (with short sleep period between retries) for specified amount of time.
+ static void g_remove_timeout(const char * p_path,double p_timeout,abort_callback & p_abort);
+ //! Moves file from one path to another.
+ static void g_move(const char * p_src,const char * p_dst,abort_callback & p_abort);
+ //! Attempts to move file from one path to another; if the operation fails with a sharing violation error, keeps retrying (with short sleep period between retries) for specified amount of time.
+ static void g_move_timeout(const char * p_src,const char * p_dst,double p_timeout,abort_callback & p_abort);
+
+ static void g_copy(const char * p_src,const char * p_dst,abort_callback & p_abort);//needs canonical path
+ static void g_copy_timeout(const char * p_src,const char * p_dst,double p_timeout,abort_callback & p_abort);//needs canonical path
+ static void g_copy_directory(const char * p_src,const char * p_dst,abort_callback & p_abort);//needs canonical path
+ static void g_get_stats(const char * p_path,t_filestats & p_stats,bool & p_is_writeable,abort_callback & p_abort);
+ static bool g_relative_path_create(const char * p_file_path,const char * p_playlist_path,pfc::string_base & out);
+ static bool g_relative_path_parse(const char * p_relative_path,const char * p_playlist_path,pfc::string_base & out);
+
+ static void g_create_directory(const char * p_path,abort_callback & p_abort);
+
+ //! If for some bloody reason you ever need stream io compatibility, use this, INSTEAD of calling fopen() on the path string you've got; will only work with file:// (and not with http://, unpack:// or whatever)
+ static FILE * streamio_open(const char * p_path,const char * p_flags);
+
+ static void g_open_temp(service_ptr_t<file> & p_out,abort_callback & p_abort);
+ static void g_open_tempmem(service_ptr_t<file> & p_out,abort_callback & p_abort);
+
+ static void g_list_directory(const char * p_path,directory_callback & p_out,abort_callback & p_abort);// path must be canonical
+
+ static bool g_is_valid_directory(const char * path,abort_callback & p_abort);
+ static bool g_is_empty_directory(const char * path,abort_callback & p_abort);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(filesystem);
+ };
+
+ class directory_callback_impl : public directory_callback
+ {
+ struct t_entry
+ {
+ pfc::string_simple m_path;
+ t_filestats m_stats;
+ t_entry(const char * p_path, const t_filestats & p_stats) : m_path(p_path), m_stats(p_stats) {}
+ };
+
+
+ pfc::list_t<pfc::rcptr_t<t_entry> > m_data;
+ bool m_recur;
+
+ static int sortfunc(const pfc::rcptr_const_t<t_entry> & p1, const pfc::rcptr_const_t<t_entry> & p2) {return stricmp_utf8(p1->m_path,p2->m_path);}
+ public:
+ bool on_entry(filesystem * owner,abort_callback & p_abort,const char * url,bool is_subdirectory,const t_filestats & p_stats);
+
+ directory_callback_impl(bool p_recur) : m_recur(p_recur) {}
+ t_size get_count() {return m_data.get_count();}
+ const char * operator[](t_size n) const {return m_data[n]->m_path;}
+ const char * get_item(t_size n) const {return m_data[n]->m_path;}
+ const t_filestats & get_item_stats(t_size n) const {return m_data[n]->m_stats;}
+ void sort() {m_data.sort_t(sortfunc);}
+ };
+
+ class archive;
+
+ class NOVTABLE archive_callback : public abort_callback {
+ public:
+ virtual bool on_entry(archive * owner,const char * url,const t_filestats & p_stats,const service_ptr_t<file> & p_reader) = 0;
+ };
+
+ //! Interface for archive reader services. When implementing, derive from archive_impl rather than from deriving from archive directly.
+ class NOVTABLE archive : public filesystem {
+ public:
+ virtual void archive_list(const char * p_path,const service_ptr_t<file> & p_reader,archive_callback & p_callback,bool p_want_readers) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(archive,filesystem);
+ };
+
+ //! Root class for archive implementations. Derive from this instead of from archive directly.
+ class NOVTABLE archive_impl : public archive {
+ private:
+ //do not override these
+ bool get_canonical_path(const char * path,pfc::string_base & out);
+ bool is_our_path(const char * path);
+ bool get_display_path(const char * path,pfc::string_base & out);
+ void remove(const char * path,abort_callback & p_abort);
+ void move(const char * src,const char * dst,abort_callback & p_abort);
+ bool is_remote(const char * src);
+ bool relative_path_create(const char * file_path,const char * playlist_path,pfc::string_base & out);
+ bool relative_path_parse(const char * relative_path,const char * playlist_path,pfc::string_base & out);
+ void open(service_ptr_t<file> & p_out,const char * path, t_open_mode mode,abort_callback & p_abort);
+ void create_directory(const char * path,abort_callback &);
+ void list_directory(const char * p_path,directory_callback & p_out,abort_callback & p_abort);
+ void get_stats(const char * p_path,t_filestats & p_stats,bool & p_is_writeable,abort_callback & p_abort);
+ protected:
+ //override these
+ virtual const char * get_archive_type()=0;//eg. "zip", must be lowercase
+ virtual t_filestats get_stats_in_archive(const char * p_archive,const char * p_file,abort_callback & p_abort) = 0;
+ virtual void open_archive(service_ptr_t<file> & p_out,const char * archive,const char * file, abort_callback & p_abort)=0;//opens for reading
+ public:
+ //override these
+
+ virtual void archive_list(const char * path,const service_ptr_t<file> & p_reader,archive_callback & p_out,bool p_want_readers)=0;
+ //playlist_loader_callback ONLY for on_progress calls
+
+
+ static bool g_parse_unpack_path(const char * path,pfc::string8 & archive,pfc::string8 & file);
+ static void g_make_unpack_path(pfc::string_base & path,const char * archive,const char * file,const char * name);
+ void make_unpack_path(pfc::string_base & path,const char * archive,const char * file);
+
+
+ };
+
+ template<typename T>
+ class archive_factory_t : public service_factory_single_t<T> {};
+
+
+ t_filetimestamp filetimestamp_from_system_timer();
+
+ //! Warning: this formats according to system timezone settings, created strings should be used for display only, never for storage.
+ class format_filetimestamp {
+ public:
+ format_filetimestamp(t_filetimestamp p_timestamp);
+ operator const char*() const {return m_buffer;}
+ const char * get_ptr() const {return m_buffer;}
+ private:
+ pfc::string_fixed_t<32> m_buffer;
+ };
+
+ void generate_temp_location_for_file(pfc::string_base & p_out, const char * p_origpath,const char * p_extension,const char * p_magic);
+}
+
+using namespace foobar2000_io;
+
+#include "filesystem_helper.h"
+
+#endif//_FOOBAR2000_SDK_FILESYSTEM_H_
+
+
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem_helper.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem_helper.cpp
new file mode 100644
index 0000000..51f2ecd
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem_helper.cpp
@@ -0,0 +1,106 @@
+#include "foobar2000.h"
+
+void stream_writer_chunk::write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ t_size remaining = p_bytes, written = 0;
+ while(remaining > 0) {
+ t_size delta = sizeof(m_buffer) - m_buffer_state;
+ if (delta > remaining) delta = remaining;
+ memcpy(m_buffer,(const t_uint8*)p_buffer + written,delta);
+ written += delta;
+ remaining -= delta;
+
+ if (m_buffer_state == sizeof(m_buffer)) {
+ m_writer->write_lendian_t((t_uint8)m_buffer_state,p_abort);
+ m_writer->write_object(m_buffer,m_buffer_state,p_abort);
+ m_buffer_state = 0;
+ }
+ }
+}
+
+void stream_writer_chunk::flush(abort_callback & p_abort)
+{
+ m_writer->write_lendian_t((t_uint8)m_buffer_state,p_abort);
+ if (m_buffer_state > 0) {
+ m_writer->write_object(m_buffer,m_buffer_state,p_abort);
+ m_buffer_state = 0;
+ }
+}
+
+/*
+ stream_writer * m_writer;
+ unsigned m_buffer_state;
+ unsigned char m_buffer[255];
+*/
+
+t_size stream_reader_chunk::read(void * p_buffer,t_size p_bytes,abort_callback & p_abort)
+{
+ t_size todo = p_bytes, done = 0;
+ while(todo > 0) {
+ if (m_buffer_size == m_buffer_state) {
+ if (m_eof) break;
+ t_uint8 temp;
+ m_reader->read_lendian_t(temp,p_abort);
+ m_buffer_size = temp;
+ if (temp != sizeof(m_buffer)) m_eof = true;
+ m_buffer_state = 0;
+ if (m_buffer_size>0) {
+ m_reader->read_object(m_buffer,m_buffer_size,p_abort);
+ }
+ }
+
+
+ t_size delta = m_buffer_size - m_buffer_state;
+ if (delta > todo) delta = todo;
+ if (delta > 0) {
+ memcpy((unsigned char*)p_buffer + done,m_buffer + m_buffer_state,delta);
+ todo -= delta;
+ done += delta;
+ m_buffer_state += delta;
+ }
+ }
+ return done;
+}
+
+void stream_reader_chunk::flush(abort_callback & p_abort) {
+ while(!m_eof) {
+ p_abort.check_e();
+ t_uint8 temp;
+ m_reader->read_lendian_t(temp,p_abort);
+ m_buffer_size = temp;
+ if (temp != sizeof(m_buffer)) m_eof = true;
+ m_buffer_state = 0;
+ if (m_buffer_size>0) {
+ m_reader->skip_object(m_buffer_size,p_abort);
+ }
+ }
+}
+
+/*
+ stream_reader * m_reader;
+ unsigned m_buffer_state, m_buffer_size;
+ bool m_eof;
+ unsigned char m_buffer[255];
+*/
+
+void stream_reader_chunk::g_skip(stream_reader * p_stream,abort_callback & p_abort) {
+ stream_reader_chunk(p_stream).flush(p_abort);
+}
+
+t_size reader_membuffer_base::read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ p_abort.check_e();
+ t_size max = get_buffer_size();
+ if (max < m_offset) throw pfc::exception_bug_check();
+ max -= m_offset;
+ t_size delta = p_bytes;
+ if (delta > max) delta = max;
+ memcpy(p_buffer,(char*)get_buffer() + m_offset,delta);
+ m_offset += delta;
+ return delta;
+}
+
+void reader_membuffer_base::seek(t_filesize position,abort_callback & p_abort) {
+ p_abort.check_e();
+ t_filesize max = get_buffer_size();
+ if (position == filesize_invalid || position > max) throw exception_io_seek_out_of_range();
+ m_offset = (t_size)position;
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem_helper.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem_helper.h
new file mode 100644
index 0000000..07ae3dc
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/filesystem_helper.h
@@ -0,0 +1,265 @@
+#ifndef _FILESYSTEM_HELPER_H_
+#define _FILESYSTEM_HELPER_H_
+
+//helper
+class file_path_canonical {
+public:
+ file_path_canonical(const char * src) {filesystem::g_get_canonical_path(src,m_data);}
+ operator const char * () const {return m_data.get_ptr();}
+ const char * get_ptr() const {return m_data.get_ptr();}
+ t_size get_length() const {return m_data.get_length();}
+private:
+ pfc::string8 m_data;
+};
+
+class file_path_display {
+public:
+ file_path_display(const char * src) {filesystem::g_get_display_path(src,m_data);}
+ operator const char * () const {return m_data.get_ptr();}
+ const char * get_ptr() const {return m_data.get_ptr();}
+ t_size get_length() const {return m_data.get_length();}
+private:
+ pfc::string8 m_data;
+};
+
+
+class NOVTABLE reader_membuffer_base : public file_readonly {
+public:
+ reader_membuffer_base() : m_offset(0) {}
+
+ t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort);
+
+ void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {throw exception_io_sharing_violation();}
+
+ t_filesize get_size(abort_callback & p_abort) {return get_buffer_size();}
+ t_filesize get_position(abort_callback & p_abort) {return m_offset;}
+ void seek(t_filesize position,abort_callback & p_abort);
+ void reopen(abort_callback & p_abort) {seek(0,p_abort);}
+
+ bool can_seek() {return true;}
+ bool is_in_memory() {return true;}
+
+protected:
+ virtual const void * get_buffer() = 0;
+ virtual t_size get_buffer_size() = 0;
+ virtual t_filetimestamp get_timestamp(abort_callback & p_abort) = 0;
+ virtual bool get_content_type(pfc::string_base &) {return false;}
+ inline void seek_internal(t_size p_offset) {if (p_offset > get_buffer_size()) throw exception_io_seek_out_of_range(); m_offset = p_offset;}
+private:
+ t_size m_offset;
+};
+
+class reader_membuffer_mirror : public reader_membuffer_base
+{
+public:
+ t_filetimestamp get_timestamp(abort_callback & p_abort) {return m_timestamp;}
+ bool is_remote() {return m_remote;}
+
+ //! Returns false when the object could not be mirrored (too big) or did not need mirroring.
+ static bool g_create(service_ptr_t<file> & p_out,const service_ptr_t<file> & p_src,abort_callback & p_abort) {
+ service_ptr_t<reader_membuffer_mirror> ptr = new service_impl_t<reader_membuffer_mirror>();
+ if (!ptr->init(p_src,p_abort)) return false;
+ p_out = ptr.get_ptr();
+ return true;
+ }
+
+private:
+ const void * get_buffer() {return m_buffer.get_ptr();}
+ t_size get_buffer_size() {return m_buffer.get_size();}
+
+ bool init(const service_ptr_t<file> & p_src,abort_callback & p_abort) {
+ if (p_src->is_in_memory()) return false;//already buffered
+ m_remote = p_src->is_remote();
+
+ t_size size = pfc::downcast_guarded<t_size>(p_src->get_size(p_abort));
+
+ m_buffer.set_size(size);
+
+ p_src->reopen(p_abort);
+
+ p_src->read_object(m_buffer.get_ptr(),size,p_abort);
+
+ m_timestamp = p_src->get_timestamp(p_abort);
+
+ return true;
+ }
+
+
+ t_filetimestamp m_timestamp;
+ pfc::array_t<char> m_buffer;
+ bool m_remote;
+
+};
+
+class reader_limited : public file_readonly {
+ service_ptr_t<file> r;
+ t_filesize begin;
+ t_filesize end;
+
+public:
+ reader_limited() {begin=0;end=0;}
+ reader_limited(const service_ptr_t<file> & p_r,t_filesize p_begin,t_filesize p_end,abort_callback & p_abort) {
+ r = p_r;
+ begin = p_begin;
+ end = p_end;
+ r->seek(begin,p_abort);
+ }
+
+ void init(const service_ptr_t<file> & p_r,t_filesize p_begin,t_filesize p_end,abort_callback & p_abort) {
+ r = p_r;
+ begin = p_begin;
+ end = p_end;
+ r->seek(begin,p_abort);
+ }
+
+ t_filetimestamp get_timestamp(abort_callback & p_abort) {return r->get_timestamp(p_abort);}
+
+ t_size read(void *p_buffer, t_size p_bytes,abort_callback & p_abort) {
+ t_filesize pos;
+ pos = r->get_position(p_abort);
+ if (p_bytes > end - pos) p_bytes = (t_size)(end - pos);
+ return r->read(p_buffer,p_bytes,p_abort);
+ }
+
+ t_filesize get_size(abort_callback & p_abort) {return end-begin;}
+
+ t_filesize get_position(abort_callback & p_abort) {
+ return r->get_position(p_abort) - begin;
+ }
+
+ void seek(t_filesize position,abort_callback & p_abort) {
+ r->seek(position+begin,p_abort);
+ }
+ bool can_seek() {return r->can_seek();}
+ bool is_remote() {return r->is_remote();}
+
+ bool get_content_type(pfc::string_base &) {return false;}
+
+ void reopen(abort_callback & p_abort) {seek(0,p_abort);}
+};
+
+class stream_reader_memblock_ref : public stream_reader
+{
+public:
+ stream_reader_memblock_ref(const void * p_data,t_size p_data_size) : m_data((const unsigned char*)p_data), m_data_size(p_data_size), m_pointer(0) {}
+ t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ t_size remaining = m_data_size - m_pointer;
+ t_size toread = p_bytes;
+ if (toread > remaining) toread = remaining;
+ if (toread > 0) {
+ memcpy(p_buffer,m_data+m_pointer,toread);
+ m_pointer += toread;
+ }
+
+ return toread;
+ }
+private:
+ const unsigned char * m_data;
+ t_size m_data_size,m_pointer;
+};
+
+template<class t_storage>
+class stream_writer_buffer_append_ref_t : public stream_writer
+{
+public:
+ stream_writer_buffer_append_ref_t(t_storage & p_output) : m_output(p_output) {}
+ void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ pfc::static_assert< sizeof(m_output[0]) == 1>();
+ t_size base = m_output.get_size();
+ if (base + p_bytes < base) throw std::bad_alloc();
+ m_output.set_size(base + p_bytes);
+ memcpy( (t_uint8*) m_output.get_ptr() + base, p_buffer, p_bytes );
+ }
+private:
+ t_storage & m_output;
+};
+
+class stream_reader_limited_ref : public stream_reader
+{
+public:
+ stream_reader_limited_ref(stream_reader * p_reader,t_size p_limit) : m_reader(p_reader), m_remaining(p_limit) {}
+
+ t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ if (p_bytes > m_remaining) p_bytes = m_remaining;
+
+ t_size done = m_reader->read(p_buffer,p_bytes,p_abort);
+ m_remaining -= done;
+ return done;
+ }
+
+ inline t_size get_remaining() const {return m_remaining;}
+
+ void flush_remaining(abort_callback & p_abort)
+ {
+ if (m_remaining > 0) return skip_object(m_remaining,p_abort);
+ }
+
+private:
+ stream_reader * m_reader;
+ t_size m_remaining;
+};
+
+class stream_writer_chunk_dwordheader : public stream_writer
+{
+public:
+ stream_writer_chunk_dwordheader(const service_ptr_t<file> & p_writer) : m_writer(p_writer) {}
+
+ void initialize(abort_callback & p_abort) {
+ m_headerposition = m_writer->get_position(p_abort);
+ m_written = 0;
+ m_writer->write_lendian_t((t_uint32)0,p_abort);
+ }
+
+ void finalize(abort_callback & p_abort) {
+ t_filesize end_offset;
+ end_offset = m_writer->get_position(p_abort);
+ m_writer->seek(m_headerposition,p_abort);
+ m_writer->write_lendian_t(pfc::downcast_guarded<t_uint32>(m_written),p_abort);
+ m_writer->seek(end_offset,p_abort);
+ }
+
+ void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ m_writer->write(p_buffer,p_bytes,p_abort);
+ m_written += p_bytes;
+ }
+
+private:
+ service_ptr_t<file> m_writer;
+ t_filesize m_headerposition;
+ t_filesize m_written;
+};
+
+class stream_writer_chunk : public stream_writer
+{
+public:
+ stream_writer_chunk(stream_writer * p_writer) : m_writer(p_writer), m_buffer_state(0) {}
+
+ void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort);
+
+ void flush(abort_callback & p_abort);//must be called after writing before object is destroyed
+
+private:
+ stream_writer * m_writer;
+ unsigned m_buffer_state;
+ unsigned char m_buffer[255];
+};
+
+class stream_reader_chunk : public stream_reader
+{
+public:
+ stream_reader_chunk(stream_reader * p_reader) : m_reader(p_reader), m_buffer_state(0), m_buffer_size(0), m_eof(false) {}
+
+ t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort);
+
+ void flush(abort_callback & p_abort);//must be called after reading before object is destroyed
+
+ static void g_skip(stream_reader * p_stream,abort_callback & p_abort);
+
+private:
+ stream_reader * m_reader;
+ t_size m_buffer_state, m_buffer_size;
+ bool m_eof;
+ unsigned char m_buffer[255];
+};
+
+#endif//_FILESYSTEM_HELPER_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/foobar2000.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/foobar2000.h
new file mode 100644
index 0000000..25ea044
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/foobar2000.h
@@ -0,0 +1,87 @@
+#ifndef _FOOBAR2000_H_
+#define _FOOBAR2000_H_
+
+#ifndef UNICODE
+#error Only UNICODE environment supported.
+#endif
+
+#include "../../pfc/pfc.h"
+
+#include "shared.h"
+
+#ifndef NOTHROW
+#ifdef _MSC_VER
+#define NOTHROW __declspec(nothrow)
+#else
+#define NOTHROW
+#endif
+#endif
+
+#define FB2KAPI /*NOTHROW*/
+
+typedef const char * pcchar;
+
+#include "core_api.h"
+#include "service.h"
+
+#include "completion_notify.h"
+#include "abort_callback.h"
+#include "audio_chunk.h"
+#include "componentversion.h"
+#include "preferences_page.h"
+#include "coreversion.h"
+#include "filesystem.h"
+#include "cfg_var.h"
+#include "mem_block_container.h"
+#include "audio_postprocessor.h"
+#include "playable_location.h"
+#include "file_info.h"
+#include "file_info_impl.h"
+#include "metadb_handle.h"
+#include "metadb.h"
+#include "console.h"
+#include "dsp.h"
+#include "dsp_manager.h"
+#include "initquit.h"
+#include "input.h"
+#include "input_impl.h"
+#include "menu.h"
+#include "contextmenu.h"
+#include "contextmenu_manager.h"
+#include "menu_helpers.h"
+#include "modeless_dialog.h"
+#include "playback_control.h"
+#include "play_callback.h"
+#include "playlist.h"
+#include "playlist_loader.h"
+#include "replaygain.h"
+#include "resampler.h"
+#include "tag_processor.h"
+#include "titleformat.h"
+#include "titleformat_config.h"
+#include "ui.h"
+#include "unpack.h"
+#include "vis.h"
+#include "packet_decoder.h"
+#include "commandline.h"
+#include "genrand.h"
+#include "file_operation_callback.h"
+#include "library_manager.h"
+#include "config_io_callback.h"
+#include "popup_message.h"
+#include "app_close_blocker.h"
+#include "config_object.h"
+#include "config_object_impl.h"
+#include "threaded_process.h"
+#include "hasher_md5.h"
+#include "message_loop.h"
+#include "input_file_type.h"
+#include "masstagger_action.h"
+#include "chapterizer.h"
+#include "link_resolver.h"
+#include "main_thread_callback.h"
+#include "advconfig.h"
+#include "info_lookup_handler.h"
+#include "track_property.h"
+
+#endif //_FOOBAR2000_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/foobar2000_SDK.vcproj b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/foobar2000_SDK.vcproj
new file mode 100644
index 0000000..0dd5ed1
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/foobar2000_SDK.vcproj
@@ -0,0 +1,2280 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="foobar2000_SDK"
+ ProjectGUID="{E8091321-D79D-4575-86EF-064EA1A4A20D}"
+ RootNamespace="foobar2000_SDK"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="foobar2000.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="foobar2000.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="true"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="foobar2000.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="true"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="foobar2000.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="*.cpp"
+ >
+ <File
+ RelativePath="abort_callback.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="app_close_blocker.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="audio_chunk.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="audio_chunk_channel_config.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\cfg_var.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\chapterizer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="commandline.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\completion_notify.cpp"
+ >
+ </File>
+ <File
+ RelativePath="config_io_callback.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="config_object.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="console.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="dsp.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="dsp_manager.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="file_info.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="file_info_impl.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="file_info_merge.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="file_operation_callback.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="filesystem.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\filesystem_helper.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="guids.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="hasher_md5.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="input.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\input_file_type.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\link_resolver.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mainmenu.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mem_block_container.cpp"
+ >
+ </File>
+ <File
+ RelativePath="menu_helpers.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="menu_item.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="menu_manager.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="metadb.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="metadb_handle.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="metadb_handle_list.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="modeless_dialog.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="packet_decoder.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="playable_location.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\playback_control.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="playlist.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="playlist_loader.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="playlist_lock.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="popup_message.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\preferences_page.cpp"
+ >
+ </File>
+ <File
+ RelativePath="replaygain.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="replaygain_info.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="service.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="stdafx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="tag_processor.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="tag_processor_id3v2.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="threaded_process.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="titleformat.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="titleformat_config.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="ui.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="utf8api.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="*.h"
+ >
+ <File
+ RelativePath="abort_callback.h"
+ >
+ </File>
+ <File
+ RelativePath=".\advconfig.h"
+ >
+ </File>
+ <File
+ RelativePath="app_close_blocker.h"
+ >
+ </File>
+ <File
+ RelativePath="audio_chunk.h"
+ >
+ </File>
+ <File
+ RelativePath=".\audio_postprocessor.h"
+ >
+ </File>
+ <File
+ RelativePath=".\cfg_var.h"
+ >
+ </File>
+ <File
+ RelativePath=".\chapterizer.h"
+ >
+ </File>
+ <File
+ RelativePath="commandline.h"
+ >
+ </File>
+ <File
+ RelativePath=".\completion_notify.h"
+ >
+ </File>
+ <File
+ RelativePath="component.h"
+ >
+ </File>
+ <File
+ RelativePath="componentversion.h"
+ >
+ </File>
+ <File
+ RelativePath="config_io_callback.h"
+ >
+ </File>
+ <File
+ RelativePath="config_object.h"
+ >
+ </File>
+ <File
+ RelativePath="config_object_impl.h"
+ >
+ </File>
+ <File
+ RelativePath="console.h"
+ >
+ </File>
+ <File
+ RelativePath=".\contextmenu.h"
+ >
+ </File>
+ <File
+ RelativePath=".\contextmenu_manager.h"
+ >
+ </File>
+ <File
+ RelativePath="core_api.h"
+ >
+ </File>
+ <File
+ RelativePath="coreversion.h"
+ >
+ </File>
+ <File
+ RelativePath="dsp.h"
+ >
+ </File>
+ <File
+ RelativePath="dsp_manager.h"
+ >
+ </File>
+ <File
+ RelativePath="file_info.h"
+ >
+ </File>
+ <File
+ RelativePath="file_info_impl.h"
+ >
+ </File>
+ <File
+ RelativePath="file_operation_callback.h"
+ >
+ </File>
+ <File
+ RelativePath="filesystem.h"
+ >
+ </File>
+ <File
+ RelativePath=".\filesystem_helper.h"
+ >
+ </File>
+ <File
+ RelativePath="foobar2000.h"
+ >
+ </File>
+ <File
+ RelativePath="genrand.h"
+ >
+ </File>
+ <File
+ RelativePath="hasher_md5.h"
+ >
+ </File>
+ <File
+ RelativePath=".\info_lookup_handler.h"
+ >
+ </File>
+ <File
+ RelativePath="initquit.h"
+ >
+ </File>
+ <File
+ RelativePath="input.h"
+ >
+ </File>
+ <File
+ RelativePath=".\input_file_type.h"
+ >
+ </File>
+ <File
+ RelativePath=".\input_impl.h"
+ >
+ </File>
+ <File
+ RelativePath="library_manager.h"
+ >
+ </File>
+ <File
+ RelativePath=".\link_resolver.h"
+ >
+ </File>
+ <File
+ RelativePath=".\main_thread_callback.h"
+ >
+ </File>
+ <File
+ RelativePath=".\masstagger_action.h"
+ >
+ </File>
+ <File
+ RelativePath=".\mem_block_container.h"
+ >
+ </File>
+ <File
+ RelativePath=".\menu.h"
+ >
+ </File>
+ <File
+ RelativePath="menu_helpers.h"
+ >
+ </File>
+ <File
+ RelativePath=".\message_loop.h"
+ >
+ </File>
+ <File
+ RelativePath="metadb.h"
+ >
+ </File>
+ <File
+ RelativePath="metadb_handle.h"
+ >
+ </File>
+ <File
+ RelativePath="modeless_dialog.h"
+ >
+ </File>
+ <File
+ RelativePath="packet_decoder.h"
+ >
+ </File>
+ <File
+ RelativePath="play_callback.h"
+ >
+ </File>
+ <File
+ RelativePath="playable_location.h"
+ >
+ </File>
+ <File
+ RelativePath=".\playback_control.h"
+ >
+ </File>
+ <File
+ RelativePath="playlist.h"
+ >
+ </File>
+ <File
+ RelativePath="playlist_loader.h"
+ >
+ </File>
+ <File
+ RelativePath="popup_message.h"
+ >
+ </File>
+ <File
+ RelativePath="preferences_page.h"
+ >
+ </File>
+ <File
+ RelativePath="replaygain.h"
+ >
+ </File>
+ <File
+ RelativePath="resampler.h"
+ >
+ </File>
+ <File
+ RelativePath="service.h"
+ >
+ </File>
+ <File
+ RelativePath="service_impl.h"
+ >
+ </File>
+ <File
+ RelativePath=".\shared.h"
+ >
+ </File>
+ <File
+ RelativePath="tag_processor.h"
+ >
+ </File>
+ <File
+ RelativePath="threaded_process.h"
+ >
+ </File>
+ <File
+ RelativePath="titleformat.h"
+ >
+ </File>
+ <File
+ RelativePath="titleformat_config.h"
+ >
+ </File>
+ <File
+ RelativePath=".\track_property.h"
+ >
+ </File>
+ <File
+ RelativePath="ui.h"
+ >
+ </File>
+ <File
+ RelativePath="unpack.h"
+ >
+ </File>
+ <File
+ RelativePath="vis.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/genrand.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/genrand.h
new file mode 100644
index 0000000..288db1b
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/genrand.h
@@ -0,0 +1,19 @@
+#ifndef _SDK_GENRAND_H_
+#define _SDK_GENRAND_H_
+
+//! PRNG service. Implemented by the core, do not reimplement. Use g_create() helper function to instantiate.
+class NOVTABLE genrand_service : public service_base
+{
+public:
+ //! Seeds the PRNG with specified value.
+ virtual void seed(unsigned val) = 0;
+ //! Returns random value N, where 0 <= N < range.
+ virtual unsigned genrand(unsigned range)=0;
+
+ static service_ptr_t<genrand_service> g_create() {return standard_api_create_t<genrand_service>();}
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(genrand_service);
+};
+
+
+#endif //_SDK_GENRAND_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/guids.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/guids.cpp
new file mode 100644
index 0000000..063d1a5
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/guids.cpp
@@ -0,0 +1,1042 @@
+#include "foobar2000.h"
+
+// {4B897EC8-A2F9-478d-A95E-1A2110A40078}
+FOOGUIDDECL const GUID hasher_md5::class_guid =
+{ 0x4b897ec8, 0xa2f9, 0x478d, { 0xa9, 0x5e, 0x1a, 0x21, 0x10, 0xa4, 0x0, 0x78 } };
+
+// {74497D81-6158-48ba-9657-386A5520D0FF}
+FOOGUIDDECL const GUID config_io_callback::class_guid =
+{ 0x74497d81, 0x6158, 0x48ba, { 0x96, 0x57, 0x38, 0x6a, 0x55, 0x20, 0xd0, 0xff } };
+
+// {10BB3EBD-DDF7-4975-A3CC-23084829453E}
+FOOGUIDDECL const GUID componentversion::class_guid =
+{ 0x10bb3ebd, 0xddf7, 0x4975, { 0xa3, 0xcc, 0x23, 0x8, 0x48, 0x29, 0x45, 0x3e } };
+
+// {7255E8D0-3FCF-4781-B93B-D06CB88DFAFA}
+FOOGUIDDECL const GUID preferences_page::class_guid =
+{ 0x7255e8d0, 0x3fcf, 0x4781, { 0xb9, 0x3b, 0xd0, 0x6c, 0xb8, 0x8d, 0xfa, 0xfa } };
+
+// {8146A883-F146-401b-BAF6-4FB2E306F2EB}
+FOOGUIDDECL const GUID preferences_branch::class_guid =
+{ 0x8146a883, 0xf146, 0x401b, { 0xba, 0xf6, 0x4f, 0xb2, 0xe3, 0x6, 0xf2, 0xeb } };
+
+// {90DF5270-65BB-4dba-BAF5-86BE9E59DC20}
+FOOGUIDDECL const GUID console_receiver::class_guid =
+{ 0x90df5270, 0x65bb, 0x4dba, { 0xba, 0xf5, 0x86, 0xbe, 0x9e, 0x59, 0xdc, 0x20 } };
+
+// {0C36A649-9EA0-4f48-B229-0CB2AA9AB6F4}
+FOOGUIDDECL const GUID core_version_info::class_guid =
+{ 0xc36a649, 0x9ea0, 0x4f48, { 0xb2, 0x29, 0xc, 0xb2, 0xaa, 0x9a, 0xb6, 0xf4 } };
+
+// {61C4E6E4-C31E-4c89-A759-BF0949DFC528}
+FOOGUIDDECL const GUID audio_postprocessor::class_guid =
+{ 0x61c4e6e4, 0xc31e, 0x4c89, { 0xa7, 0x59, 0xbf, 0x9, 0x49, 0xdf, 0xc5, 0x28 } };
+
+// {EE65D408-70D6-40f6-940D-D9F537F1BEF1}
+FOOGUIDDECL const GUID dsp_config_manager::class_guid =
+{ 0xee65d408, 0x70d6, 0x40f6, { 0x94, 0xd, 0xd9, 0xf5, 0x37, 0xf1, 0xbe, 0xf1 } };
+
+// {F8F03D26-C2DA-47ed-8748-1DBACBCEA508}
+FOOGUIDDECL const GUID dsp_config_callback::class_guid =
+{ 0xf8f03d26, 0xc2da, 0x47ed, { 0x87, 0x48, 0x1d, 0xba, 0xcb, 0xce, 0xa5, 0x8 } };
+
+// {0D048731-8AA8-4704-8AD6-189E24D48C88}
+FOOGUIDDECL const GUID dsp_entry::class_guid =
+{ 0xd048731, 0x8aa8, 0x4704, { 0x8a, 0xd6, 0x18, 0x9e, 0x24, 0xd4, 0x8c, 0x88 } };
+
+// {2A42AFEA-940B-455b-AEFF-CFDACAF52AFF}
+FOOGUIDDECL const GUID dsp::class_guid =
+{ 0x2a42afea, 0x940b, 0x455b, { 0xae, 0xff, 0xcf, 0xda, 0xca, 0xf5, 0x2a, 0xff } };
+
+// {113773C4-B387-4b48-8BDF-AB58BC6CE538}
+FOOGUIDDECL const GUID initquit::class_guid =
+{ 0x113773c4, 0xb387, 0x4b48, { 0x8b, 0xdf, 0xab, 0x58, 0xbc, 0x6c, 0xe5, 0x38 } };
+
+// {4560C877-C41A-4c71-BB75-A7A5BAFC18D8}
+FOOGUIDDECL const GUID metadb_display_hook::class_guid =
+{ 0x4560c877, 0xc41a, 0x4c71, { 0xbb, 0x75, 0xa7, 0xa5, 0xba, 0xfc, 0x18, 0xd8 } };
+
+// {609D48C8-C6A6-4784-8BBD-FDD32BF0740E}
+FOOGUIDDECL const GUID metadb::class_guid =
+{ 0x609d48c8, 0xc6a6, 0x4784, { 0x8b, 0xbd, 0xfd, 0xd3, 0x2b, 0xf0, 0x74, 0xe } };
+
+// {D5286BB4-FDED-47ef-A623-4C3FF056DEC1}
+FOOGUIDDECL const GUID metadb_io_callback::class_guid =
+{ 0xd5286bb4, 0xfded, 0x47ef, { 0xa6, 0x23, 0x4c, 0x3f, 0xf0, 0x56, 0xde, 0xc1 } };
+
+// {1C0802F7-CF24-49ef-B914-8B9866F19779}
+FOOGUIDDECL const GUID contextmenu_item::class_guid =
+{ 0x1c0802f7, 0xcf24, 0x49ef, { 0xb9, 0x14, 0x8b, 0x98, 0x66, 0xf1, 0x97, 0x79 } };
+
+// {98B00B13-8C0E-49ff-B17C-5E537D3AE4B7}
+FOOGUIDDECL const GUID visualisation_manager::class_guid =
+{ 0x98b00b13, 0x8c0e, 0x49ff, { 0xb1, 0x7c, 0x5e, 0x53, 0x7d, 0x3a, 0xe4, 0xb7 } };
+
+// {4A4B1DD8-82FF-4071-A6E2-BD043F4C251C}
+FOOGUIDDECL const GUID visualisation_stream::class_guid =
+{ 0x4a4b1dd8, 0x82ff, 0x4071, { 0xa6, 0xe2, 0xbd, 0x4, 0x3f, 0x4c, 0x25, 0x1c } };
+
+// {015A6C0E-1571-49bd-A367-30B4BD889C34}
+FOOGUIDDECL const GUID packet_decoder::class_guid =
+{ 0x15a6c0e, 0x1571, 0x49bd, { 0xa3, 0x67, 0x30, 0xb4, 0xbd, 0x88, 0x9c, 0x34 } };
+
+// {D815032D-AFEB-46c6-8AA3-6FD530A4CE67}
+FOOGUIDDECL const GUID packet_decoder_streamparse::class_guid =
+{ 0xd815032d, 0xafeb, 0x46c6, { 0x8a, 0xa3, 0x6f, 0xd5, 0x30, 0xa4, 0xce, 0x67 } };
+
+// {53006A71-C03C-4c38-822F-9A34A5655095}
+FOOGUIDDECL const GUID packet_decoder_entry::class_guid =
+{ 0x53006a71, 0xc03c, 0x4c38, { 0x82, 0x2f, 0x9a, 0x34, 0xa5, 0x65, 0x50, 0x95 } };
+
+// {D3BD5F53-A6D6-4346-991F-CF14DFAD2B3A}
+FOOGUIDDECL const GUID contextmenu_manager::class_guid =
+{ 0xd3bd5f53, 0xa6d6, 0x4346, { 0x99, 0x1f, 0xcf, 0x14, 0xdf, 0xad, 0x2b, 0x3a } };
+
+// {640E006E-2934-4d6c-8327-4FA9F341ECF2}
+FOOGUIDDECL const GUID input_file_type::class_guid =
+{ 0x640e006e, 0x2934, 0x4d6c, { 0x83, 0x27, 0x4f, 0xa9, 0xf3, 0x41, 0xec, 0xf2 } };
+
+// {2DC57FF7-476D-42f5-A05A-60499896134A}
+FOOGUIDDECL const GUID ui_control::class_guid =
+{ 0x2dc57ff7, 0x476d, 0x42f5, { 0xa0, 0x5a, 0x60, 0x49, 0x98, 0x96, 0x13, 0x4a } };
+
+// {392B88DE-50FC-43b0-9F03-2D79B071CAF6}
+FOOGUIDDECL const GUID ui_status_text_override::class_guid =
+{ 0x392b88de, 0x50fc, 0x43b0, { 0x9f, 0x3, 0x2d, 0x79, 0xb0, 0x71, 0xca, 0xf6 } };
+
+// {52BD7A17-540C-4a97-B812-72BC84EC4FF5}
+FOOGUIDDECL const GUID ui_drop_item_callback::class_guid =
+{ 0x52bd7a17, 0x540c, 0x4a97, { 0xb8, 0x12, 0x72, 0xbc, 0x84, 0xec, 0x4f, 0xf5 } };
+
+// {550B3A19-42A4-4c0f-91F2-90550189CBFF}
+FOOGUIDDECL const GUID commandline_handler::class_guid =
+{ 0x550b3a19, 0x42a4, 0x4c0f, { 0x91, 0xf2, 0x90, 0x55, 0x1, 0x89, 0xcb, 0xff } };
+
+// {C71B99BD-12C5-48fe-A9C0-469F6FEA88BF}
+FOOGUIDDECL const GUID modeless_dialog_manager::class_guid =
+{ 0xc71b99bd, 0x12c5, 0x48fe, { 0xa9, 0xc0, 0x46, 0x9f, 0x6f, 0xea, 0x88, 0xbf } };
+
+// {78BCBFA1-DFB9-487f-AB16-CD82BF90CCF7}
+FOOGUIDDECL const GUID play_callback_manager::class_guid =
+{ 0x78bcbfa1, 0xdfb9, 0x487f, { 0xab, 0x16, 0xcd, 0x82, 0xbf, 0x90, 0xcc, 0xf7 } };
+
+// {8E4EED7A-C6B8-49c7-99FE-97E04AAA63A8}
+FOOGUIDDECL const GUID play_callback_static::class_guid =
+{ 0x8e4eed7a, 0xc6b8, 0x49c7, { 0x99, 0xfe, 0x97, 0xe0, 0x4a, 0xaa, 0x63, 0xa8 } };
+
+// {BF803668-2977-4c71-B9AB-5C77C338C970}
+FOOGUIDDECL const GUID playback_control::class_guid =
+{ 0xbf803668, 0x2977, 0x4c71, { 0xb9, 0xab, 0x5c, 0x77, 0xc3, 0x38, 0xc9, 0x70 } };
+
+// {242D9341-211A-4637-A69F-F6684B52F9D6}
+FOOGUIDDECL const GUID playlist_callback_static::class_guid =
+{ 0x242d9341, 0x211a, 0x4637, { 0xa6, 0x9f, 0xf6, 0x68, 0x4b, 0x52, 0xf9, 0xd6 } };
+
+// {95E9F11B-4C99-4d0a-AB9F-367196B10925}
+FOOGUIDDECL const GUID playlist_callback_single_static::class_guid =
+{ 0x95e9f11b, 0x4c99, 0x4d0a, { 0xab, 0x9f, 0x36, 0x71, 0x96, 0xb1, 0x9, 0x25 } };
+
+// {88D7EDB1-A850-42a4-BBAB-49E955F4B81F}
+FOOGUIDDECL const GUID playlist_lock::class_guid =
+{ 0x88d7edb1, 0xa850, 0x42a4, { 0xbb, 0xab, 0x49, 0xe9, 0x55, 0xf4, 0xb8, 0x1f } };
+
+// {D2E5F92B-3424-4822-AE60-8663E6D26EAB}
+FOOGUIDDECL const GUID playlist_loader::class_guid =
+{ 0xd2e5f92b, 0x3424, 0x4822, { 0xae, 0x60, 0x86, 0x63, 0xe6, 0xd2, 0x6e, 0xab } };
+
+// {2FBCE1E5-902E-49e0-B9CF-CE0FBA765348}
+FOOGUIDDECL const GUID filesystem::class_guid =
+{ 0x2fbce1e5, 0x902e, 0x49e0, { 0xb9, 0xcf, 0xce, 0xf, 0xba, 0x76, 0x53, 0x48 } };
+
+// {9098AF12-61A3-4caa-8AA9-BB95C2EF8346}
+FOOGUIDDECL const GUID unpacker::class_guid =
+{ 0x9098af12, 0x61a3, 0x4caa, { 0x8a, 0xa9, 0xbb, 0x95, 0xc2, 0xef, 0x83, 0x46 } };
+
+// {EC707440-FA3E-4d12-9876-FC369F04D4A4}
+FOOGUIDDECL const GUID archive::class_guid =
+{ 0xec707440, 0xfa3e, 0x4d12, { 0x98, 0x76, 0xfc, 0x36, 0x9f, 0x4, 0xd4, 0xa4 } };
+
+// {B2F9FC40-3E55-4b23-A2C9-22BAAD8795B1}
+FOOGUIDDECL const GUID file::class_guid =
+{ 0xb2f9fc40, 0x3e55, 0x4b23, { 0xa2, 0xc9, 0x22, 0xba, 0xad, 0x87, 0x95, 0xb1 } };
+
+// {6374340F-82D4-4471-A24B-A754B1398285}
+FOOGUIDDECL const GUID file_dynamicinfo::class_guid =
+{ 0x6374340f, 0x82d4, 0x4471, { 0xa2, 0x4b, 0xa7, 0x54, 0xb1, 0x39, 0x82, 0x85 } };
+
+// {A00CB77D-ED72-4031-806B-4E45AF995241}
+FOOGUIDDECL const GUID replaygain_manager::class_guid =
+{ 0xa00cb77d, 0xed72, 0x4031, { 0x80, 0x6b, 0x4e, 0x45, 0xaf, 0x99, 0x52, 0x41 } };
+
+// {3FEED4FC-A400-4a30-8E73-F0ECD114D7E8}
+FOOGUIDDECL const GUID resampler_entry::class_guid =
+{ 0x3feed4fc, 0xa400, 0x4a30, { 0x8e, 0x73, 0xf0, 0xec, 0xd1, 0x14, 0xd7, 0xe8 } };
+
+// {3F7674AB-044C-4796-8801-6C443C244D88}
+FOOGUIDDECL const GUID titleformat_compiler::class_guid =
+{ 0x3f7674ab, 0x44c, 0x4796, { 0x88, 0x1, 0x6c, 0x44, 0x3c, 0x24, 0x4d, 0x88 } };
+
+// {1ADD4DC4-B278-4a0c-A105-2629F4B312F4}
+FOOGUIDDECL const GUID user_interface::class_guid =
+{ 0x1add4dc4, 0xb278, 0x4a0c, { 0xa1, 0x5, 0x26, 0x29, 0xf4, 0xb3, 0x12, 0xf4 } };
+
+// {994C0D0E-319E-45f3-92FC-518616E73ADC}
+FOOGUIDDECL const GUID contextmenu_item::caller_now_playing =
+{ 0x994c0d0e, 0x319e, 0x45f3, { 0x92, 0xfc, 0x51, 0x86, 0x16, 0xe7, 0x3a, 0xdc } };
+
+// {47502BA1-816D-4a3e-ADE5-A7A9860A67DB}
+FOOGUIDDECL const GUID contextmenu_item::caller_playlist =
+{ 0x47502ba1, 0x816d, 0x4a3e, { 0xad, 0xe5, 0xa7, 0xa9, 0x86, 0xa, 0x67, 0xdb } };
+
+// {00000000-0000-0000-0000-000000000000}
+FOOGUIDDECL const GUID contextmenu_item::caller_undefined =
+{ 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
+
+// {FABEE3E9-8901-4df4-A2D7-B9898D86C39B}
+FOOGUIDDECL const GUID contextmenu_item::caller_keyboard_shortcut_list =
+{ 0xfabee3e9, 0x8901, 0x4df4, { 0xa2, 0xd7, 0xb9, 0x89, 0x8d, 0x86, 0xc3, 0x9b } };
+
+// {95DE5842-30F5-4f72-B40C-191663782F80}
+FOOGUIDDECL const GUID keyboard_shortcut_manager::class_guid =
+{ 0x95de5842, 0x30f5, 0x4f72, { 0xb4, 0xc, 0x19, 0x16, 0x63, 0x78, 0x2f, 0x80 } };
+
+// {30F95BEB-FDF4-4a75-B597-60CAF93B39C4}
+FOOGUIDDECL const GUID packet_decoder::owner_MP4 =
+{ 0x30f95beb, 0xfdf4, 0x4a75, { 0xb5, 0x97, 0x60, 0xca, 0xf9, 0x3b, 0x39, 0xc4 } };
+
+// {8F450CB3-A083-4b83-8D85-ADCE5EA6D57F}
+FOOGUIDDECL const GUID packet_decoder::owner_MP4_ALAC =
+{ 0x8f450cb3, 0xa083, 0x4b83, { 0x8d, 0x85, 0xad, 0xce, 0x5e, 0xa6, 0xd5, 0x7f } };
+
+// {40017871-50A9-48b6-BF60-BD181A227F9B}
+FOOGUIDDECL const GUID packet_decoder::owner_MP4_AMR =
+{ 0x40017871, 0x50a9, 0x48b6, { 0xbf, 0x60, 0xbd, 0x18, 0x1a, 0x22, 0x7f, 0x9b } };
+
+// {2E729EA0-6BEB-4392-BF24-75C69B60166D}
+FOOGUIDDECL const GUID packet_decoder::owner_MP4_AMR_WB =
+{ 0x2e729ea0, 0x6beb, 0x4392, { 0xbf, 0x24, 0x75, 0xc6, 0x9b, 0x60, 0x16, 0x6d } };
+
+// {AF5B7CB0-A08E-404a-A3C0-5C5EA1A8A05C}
+FOOGUIDDECL const GUID packet_decoder::owner_ADTS =
+{ 0xaf5b7cb0, 0xa08e, 0x404a, { 0xa3, 0xc0, 0x5c, 0x5e, 0xa1, 0xa8, 0xa0, 0x5c } };
+
+// {F72D2EAE-835C-4dfb-97C6-624343EFAFB0}
+FOOGUIDDECL const GUID packet_decoder::owner_ADIF =
+{ 0xf72d2eae, 0x835c, 0x4dfb, { 0x97, 0xc6, 0x62, 0x43, 0x43, 0xef, 0xaf, 0xb0 } };
+
+// {5C2DE804-EAEE-4b8e-8C14-9207A2549BBE}
+FOOGUIDDECL const GUID packet_decoder::owner_matroska =
+{ 0x5c2de804, 0xeaee, 0x4b8e, { 0x8c, 0x14, 0x92, 0x7, 0xa2, 0x54, 0x9b, 0xbe } };
+
+// {7B741A69-1AC7-440d-A01D-88536DD4DE1C}
+FOOGUIDDECL const GUID packet_decoder::owner_MP3 =
+{ 0x7b741a69, 0x1ac7, 0x440d, { 0xa0, 0x1d, 0x88, 0x53, 0x6d, 0xd4, 0xde, 0x1c } };
+
+// {17B300A0-3110-4400-A434-C18FBEEABA81}
+FOOGUIDDECL const GUID packet_decoder::owner_MP2 =
+{ 0x17b300a0, 0x3110, 0x4400, { 0xa4, 0x34, 0xc1, 0x8f, 0xbe, 0xea, 0xba, 0x81 } };
+
+// {1C068E5E-DD65-4639-BF85-78B297C8FFAC}
+FOOGUIDDECL const GUID packet_decoder::owner_MP1 =
+{ 0x1c068e5e, 0xdd65, 0x4639, { 0xbf, 0x85, 0x78, 0xb2, 0x97, 0xc8, 0xff, 0xac } };
+
+// {BC73F9FC-0107-480e-BF0E-BE58AF7AF328}
+FOOGUIDDECL const GUID packet_decoder::property_samplerate =
+{ 0xbc73f9fc, 0x107, 0x480e, { 0xbf, 0xe, 0xbe, 0x58, 0xaf, 0x7a, 0xf3, 0x28 } };
+
+// {E5D19AAD-931B-48ac-AA6E-95E2C23BEC37}
+FOOGUIDDECL const GUID packet_decoder::property_bitspersample =
+{ 0xe5d19aad, 0x931b, 0x48ac, { 0xaa, 0x6e, 0x95, 0xe2, 0xc2, 0x3b, 0xec, 0x37 } };
+
+// {1AFA1145-E774-4c26-91D6-3F5DD61E260E}
+FOOGUIDDECL const GUID packet_decoder::property_channels =
+{ 0x1afa1145, 0xe774, 0x4c26, { 0x91, 0xd6, 0x3f, 0x5d, 0xd6, 0x1e, 0x26, 0xe } };
+
+// {29C556DA-065A-4d24-8A11-0F9DBC05A817}
+FOOGUIDDECL const GUID packet_decoder::property_byteorder =
+{ 0x29c556da, 0x65a, 0x4d24, { 0x8a, 0x11, 0xf, 0x9d, 0xbc, 0x5, 0xa8, 0x17 } };
+
+// {0759C32F-E78E-4479-B0C0-B653DFA014D8}
+FOOGUIDDECL const GUID packet_decoder::property_signed =
+{ 0x759c32f, 0xe78e, 0x4479, { 0xb0, 0xc0, 0xb6, 0x53, 0xdf, 0xa0, 0x14, 0xd8 } };
+
+// {BB31669E-0C30-4c5f-AAF0-20CD49D46058}
+FOOGUIDDECL const GUID packet_decoder::property_channelmask =
+{ 0xbb31669e, 0xc30, 0x4c5f, { 0xaa, 0xf0, 0x20, 0xcd, 0x49, 0xd4, 0x60, 0x58 } };
+
+// {6F441057-1D18-4a58-9AC4-8F409CDA7DFD}
+FOOGUIDDECL const GUID standard_commands::guid_context_file_properties =
+{ 0x6f441057, 0x1d18, 0x4a58, { 0x9a, 0xc4, 0x8f, 0x40, 0x9c, 0xda, 0x7d, 0xfd } };
+
+// {EFC1E9C8-EEEF-427a-8F42-E5781605846D}
+FOOGUIDDECL const GUID standard_commands::guid_context_file_open_directory =
+{ 0xefc1e9c8, 0xeeef, 0x427a, { 0x8f, 0x42, 0xe5, 0x78, 0x16, 0x5, 0x84, 0x6d } };
+
+// {FFE18008-BCA2-4b29-AB88-8816B492C434}
+FOOGUIDDECL const GUID standard_commands::guid_context_copy_names =
+{ 0xffe18008, 0xbca2, 0x4b29, { 0xab, 0x88, 0x88, 0x16, 0xb4, 0x92, 0xc4, 0x34 } };
+
+// {44B8F02B-5408-4361-8240-18DEC881B95E}
+FOOGUIDDECL const GUID standard_commands::guid_context_send_to_playlist =
+{ 0x44b8f02b, 0x5408, 0x4361, { 0x82, 0x40, 0x18, 0xde, 0xc8, 0x81, 0xb9, 0x5e } };
+
+// {8C3BA2CB-BC4D-4752-8282-C6F9AED75A78}
+FOOGUIDDECL const GUID standard_commands::guid_context_reload_info =
+{ 0x8c3ba2cb, 0xbc4d, 0x4752, { 0x82, 0x82, 0xc6, 0xf9, 0xae, 0xd7, 0x5a, 0x78 } };
+
+// {BD045EA4-E5E9-4206-8FF9-12AD9F5DCDE1}
+FOOGUIDDECL const GUID standard_commands::guid_context_reload_info_if_changed =
+{ 0xbd045ea4, 0xe5e9, 0x4206, { 0x8f, 0xf9, 0x12, 0xad, 0x9f, 0x5d, 0xcd, 0xe1 } };
+
+// {684D9FBB-4383-44a2-9789-7EE1376209C6}
+FOOGUIDDECL const GUID standard_commands::guid_context_rewrite_info =
+{ 0x684d9fbb, 0x4383, 0x44a2, { 0x97, 0x89, 0x7e, 0xe1, 0x37, 0x62, 0x9, 0xc6 } };
+
+// {860179B7-962F-4340-ACAD-0DDAF060A6B8}
+FOOGUIDDECL const GUID standard_commands::guid_context_remove_tags =
+{ 0x860179b7, 0x962f, 0x4340, { 0xac, 0xad, 0xd, 0xda, 0xf0, 0x60, 0xa6, 0xb8 } };
+
+// {4DD1E1AD-F481-480c-BC3E-DD9C878EAFC3}
+FOOGUIDDECL const GUID standard_commands::guid_context_remove_from_database =
+{ 0x4dd1e1ad, 0xf481, 0x480c, { 0xbc, 0x3e, 0xdd, 0x9c, 0x87, 0x8e, 0xaf, 0xc3 } };
+
+// {A7E7ECB7-1943-4907-83B3-60E92353C7FA}
+FOOGUIDDECL const GUID standard_commands::guid_context_convert_run =
+{ 0xa7e7ecb7, 0x1943, 0x4907, { 0x83, 0xb3, 0x60, 0xe9, 0x23, 0x53, 0xc7, 0xfa } };
+
+// {BED4FB6E-C4F2-40dd-B528-1DE1450DDFE9}
+FOOGUIDDECL const GUID standard_commands::guid_context_convert_run_withcue =
+{ 0xbed4fb6e, 0xc4f2, 0x40dd, { 0xb5, 0x28, 0x1d, 0xe1, 0x45, 0xd, 0xdf, 0xe9 } };
+
+// {A58AE6EA-A34F-4879-B25C-F31F2CBC4DA9}
+FOOGUIDDECL const GUID standard_commands::guid_context_convert_run_singlefile =
+{ 0xa58ae6ea, 0xa34f, 0x4879, { 0xb2, 0x5c, 0xf3, 0x1f, 0x2c, 0xbc, 0x4d, 0xa9 } };
+
+// {A8EFA42D-76CB-42bc-8803-70516567B13D}
+FOOGUIDDECL const GUID standard_commands::guid_context_write_cd =
+{ 0xa8efa42d, 0x76cb, 0x42bc, { 0x88, 0x3, 0x70, 0x51, 0x65, 0x67, 0xb1, 0x3d } };
+
+// {487DAED1-02FB-4336-A813-5E90317AB041}
+FOOGUIDDECL const GUID standard_commands::guid_context_rg_scan_track =
+{ 0x487daed1, 0x2fb, 0x4336, { 0xa8, 0x13, 0x5e, 0x90, 0x31, 0x7a, 0xb0, 0x41 } };
+
+// {3850F34C-F619-4296-B8A0-26C617B1D16C}
+FOOGUIDDECL const GUID standard_commands::guid_context_rg_scan_album =
+{ 0x3850f34c, 0xf619, 0x4296, { 0xb8, 0xa0, 0x26, 0xc6, 0x17, 0xb1, 0xd1, 0x6c } };
+
+// {6A2DBA02-260C-436f-8F41-0190A4298266}
+FOOGUIDDECL const GUID standard_commands::guid_context_rg_scan_album_multi =
+{ 0x6a2dba02, 0x260c, 0x436f, { 0x8f, 0x41, 0x1, 0x90, 0xa4, 0x29, 0x82, 0x66 } };
+
+// {54C82A92-5824-4381-8D1B-79FBB1E2ABB8}
+FOOGUIDDECL const GUID standard_commands::guid_context_rg_remove =
+{ 0x54c82a92, 0x5824, 0x4381, { 0x8d, 0x1b, 0x79, 0xfb, 0xb1, 0xe2, 0xab, 0xb8 } };
+
+// {69EAA594-13D9-4237-9BD7-11A39FDD1454}
+FOOGUIDDECL const GUID standard_commands::guid_context_save_playlist =
+{ 0x69eaa594, 0x13d9, 0x4237, { 0x9b, 0xd7, 0x11, 0xa3, 0x9f, 0xdd, 0x14, 0x54 } };
+
+// {2BEB6836-C657-40ef-BB6E-D5B222AB89CE}
+FOOGUIDDECL const GUID standard_commands::guid_context_masstag_edit =
+{ 0x2beb6836, 0xc657, 0x40ef, { 0xbb, 0x6e, 0xd5, 0xb2, 0x22, 0xab, 0x89, 0xce } };
+
+// {A579FF07-5D0B-48ed-A071-B6FCE4385AA9}
+FOOGUIDDECL const GUID standard_commands::guid_context_masstag_rename =
+{ 0xa579ff07, 0x5d0b, 0x48ed, { 0xa0, 0x71, 0xb6, 0xfc, 0xe4, 0x38, 0x5a, 0xa9 } };
+
+// {77CFBCD0-98DC-4015-B327-D7142C664806}
+FOOGUIDDECL const GUID standard_commands::guid_main_always_on_top =
+{ 0x77cfbcd0, 0x98dc, 0x4015, { 0xb3, 0x27, 0xd7, 0x14, 0x2c, 0x66, 0x48, 0x6 } };
+
+// {11213A01-9F36-4e69-A1BB-7A72F418DE3A}
+FOOGUIDDECL const GUID standard_commands::guid_main_preferences =
+{ 0x11213a01, 0x9f36, 0x4e69, { 0xa1, 0xbb, 0x7a, 0x72, 0xf4, 0x18, 0xde, 0x3a } };
+
+// {EDA23441-5D38-4499-A22C-FE0CE0A987D9}
+FOOGUIDDECL const GUID standard_commands::guid_main_about =
+{ 0xeda23441, 0x5d38, 0x4499, { 0xa2, 0x2c, 0xfe, 0xc, 0xe0, 0xa9, 0x87, 0xd9 } };
+
+// {6D38C73A-15D8-472c-8E68-6F946B82ECB4}
+FOOGUIDDECL const GUID standard_commands::guid_main_exit =
+{ 0x6d38c73a, 0x15d8, 0x472c, { 0x8e, 0x68, 0x6f, 0x94, 0x6b, 0x82, 0xec, 0xb4 } };
+
+// {EF9B60FE-CB03-4c40-A8FD-3F1821020B37}
+FOOGUIDDECL const GUID standard_commands::guid_main_restart =
+{ 0xef9b60fe, 0xcb03, 0x4c40, { 0xa8, 0xfd, 0x3f, 0x18, 0x21, 0x2, 0xb, 0x37 } };
+
+// {90500F09-F16F-415e-A047-AC5045C95FFE}
+FOOGUIDDECL const GUID standard_commands::guid_main_activate =
+{ 0x90500f09, 0xf16f, 0x415e, { 0xa0, 0x47, 0xac, 0x50, 0x45, 0xc9, 0x5f, 0xfe } };
+
+// {13C17E8D-0D6F-41a4-B24A-59371043E925}
+FOOGUIDDECL const GUID standard_commands::guid_main_hide =
+{ 0x13c17e8d, 0xd6f, 0x41a4, { 0xb2, 0x4a, 0x59, 0x37, 0x10, 0x43, 0xe9, 0x25 } };
+
+// {D9473FB2-BF11-4be0-972F-0E43F166A118}
+FOOGUIDDECL const GUID standard_commands::guid_main_activate_or_hide =
+{ 0xd9473fb2, 0xbf11, 0x4be0, { 0x97, 0x2f, 0xe, 0x43, 0xf1, 0x66, 0xa1, 0x18 } };
+
+// {91E349DA-8800-42e5-BC8C-F3A92577AE84}
+FOOGUIDDECL const GUID standard_commands::guid_main_titleformat_help =
+{ 0x91e349da, 0x8800, 0x42e5, { 0xbc, 0x8c, 0xf3, 0xa9, 0x25, 0x77, 0xae, 0x84 } };
+
+// {FBCFE01C-6C57-4e6a-A9F1-62334640DC91}
+FOOGUIDDECL const GUID standard_commands::guid_main_playback_follows_cursor=
+{ 0xfbcfe01c, 0x6c57, 0x4e6a, { 0xa9, 0xf1, 0x62, 0x33, 0x46, 0x40, 0xdc, 0x91 } };
+
+// {0E1C730A-1EA9-41cc-9C30-25700ABDD9FA}
+FOOGUIDDECL const GUID standard_commands::guid_main_cursor_follows_playback=
+{ 0xe1c730a, 0x1ea9, 0x41cc, { 0x9c, 0x30, 0x25, 0x70, 0xa, 0xbd, 0xd9, 0xfa } };
+
+// {E58895A0-A2F0-45b6-8799-1440E4DB7284}
+FOOGUIDDECL const GUID standard_commands::guid_main_next =
+{ 0xe58895a0, 0xa2f0, 0x45b6, { 0x87, 0x99, 0x14, 0x40, 0xe4, 0xdb, 0x72, 0x84 } };
+
+// {059C4566-4708-4ebf-8139-6A8EA5A9DFC8}
+FOOGUIDDECL const GUID standard_commands::guid_main_previous =
+{ 0x59c4566, 0x4708, 0x4ebf, { 0x81, 0x39, 0x6a, 0x8e, 0xa5, 0xa9, 0xdf, 0xc8 } };
+
+// {18B1278A-F1BB-4b48-BC3D-6EC9EF80AD19}
+FOOGUIDDECL const GUID standard_commands::guid_main_next_or_random =
+{ 0x18b1278a, 0xf1bb, 0x4b48, { 0xbc, 0x3d, 0x6e, 0xc9, 0xef, 0x80, 0xad, 0x19 } };
+
+// {42BDA765-30A8-40fa-BFA4-6A4E2F2B2CE9}
+FOOGUIDDECL const GUID standard_commands::guid_main_random =
+{ 0x42bda765, 0x30a8, 0x40fa, { 0xbf, 0xa4, 0x6a, 0x4e, 0x2f, 0x2b, 0x2c, 0xe9 } };
+
+// {FCEF5262-7FA5-452e-A527-C14E0CB582DE}
+FOOGUIDDECL const GUID standard_commands::guid_main_pause =
+{ 0xfcef5262, 0x7fa5, 0x452e, { 0xa5, 0x27, 0xc1, 0x4e, 0xc, 0xb5, 0x82, 0xde } };
+
+// {D3F83B15-D4AF-4586-8BD0-4EA415E31FE1}
+FOOGUIDDECL const GUID standard_commands::guid_main_play =
+{ 0xd3f83b15, 0xd4af, 0x4586, { 0x8b, 0xd0, 0x4e, 0xa4, 0x15, 0xe3, 0x1f, 0xe1 } };
+
+// {8DEBC44E-EDA2-48d4-8696-31FC29D1F383}
+FOOGUIDDECL const GUID standard_commands::guid_main_play_or_pause =
+{ 0x8debc44e, 0xeda2, 0x48d4, { 0x86, 0x96, 0x31, 0xfc, 0x29, 0xd1, 0xf3, 0x83 } };
+
+// {2DF17F25-80B9-4a43-B21D-620458FDDE1E}
+FOOGUIDDECL const GUID standard_commands::guid_main_rg_set_album =
+{ 0x2df17f25, 0x80b9, 0x4a43, { 0xb2, 0x1d, 0x62, 0x4, 0x58, 0xfd, 0xde, 0x1e } };
+
+// {C26F1955-5753-4836-887F-84A563DD6DD9}
+FOOGUIDDECL const GUID standard_commands::guid_main_rg_set_track =
+{ 0xc26f1955, 0x5753, 0x4836, { 0x88, 0x7f, 0x84, 0xa5, 0x63, 0xdd, 0x6d, 0xd9 } };
+
+// {8D2D808E-6AA2-455b-A2F1-CDB019328140}
+FOOGUIDDECL const GUID standard_commands::guid_main_rg_disable =
+{ 0x8d2d808e, 0x6aa2, 0x455b, { 0xa2, 0xf1, 0xcd, 0xb0, 0x19, 0x32, 0x81, 0x40 } };
+
+// {C3378028-165F-4374-966C-2FA2E0FCD3A8}
+FOOGUIDDECL const GUID standard_commands::guid_main_stop =
+{ 0xc3378028, 0x165f, 0x4374, { 0x96, 0x6c, 0x2f, 0xa2, 0xe0, 0xfc, 0xd3, 0xa8 } };
+
+// {EE057982-22F9-4862-A986-859E463316FB}
+FOOGUIDDECL const GUID standard_commands::guid_main_stop_after_current =
+{ 0xee057982, 0x22f9, 0x4862, { 0xa9, 0x86, 0x85, 0x9e, 0x46, 0x33, 0x16, 0xfb } };
+
+// {11DC6526-73C4-44f0-91B1-DE5C2D26B0C7}
+FOOGUIDDECL const GUID standard_commands::guid_main_volume_down =
+{ 0x11dc6526, 0x73c4, 0x44f0, { 0x91, 0xb1, 0xde, 0x5c, 0x2d, 0x26, 0xb0, 0xc7 } };
+
+// {A313E630-A04A-4ae8-B5B4-0A944AC964FF}
+FOOGUIDDECL const GUID standard_commands::guid_main_volume_up =
+{ 0xa313e630, 0xa04a, 0x4ae8, { 0xb5, 0xb4, 0xa, 0x94, 0x4a, 0xc9, 0x64, 0xff } };
+
+// {4A36285B-B4AF-46ed-A1AA-6333057F485B}
+FOOGUIDDECL const GUID standard_commands::guid_main_volume_mute =
+{ 0x4a36285b, 0xb4af, 0x46ed, { 0xa1, 0xaa, 0x63, 0x33, 0x5, 0x7f, 0x48, 0x5b } };
+
+// {2DC43C22-CA09-4ef9-A61E-7A0C1DAAE21E}
+FOOGUIDDECL const GUID standard_commands::guid_main_add_directory =
+{ 0x2dc43c22, 0xca09, 0x4ef9, { 0xa6, 0x1e, 0x7a, 0xc, 0x1d, 0xaa, 0xe2, 0x1e } };
+
+// {FC89C278-4475-4853-96C9-F7F05E8CC837}
+FOOGUIDDECL const GUID standard_commands::guid_main_add_files =
+{ 0xfc89c278, 0x4475, 0x4853, { 0x96, 0xc9, 0xf7, 0xf0, 0x5e, 0x8c, 0xc8, 0x37 } };
+
+// {9CA39D38-AC9B-4cca-B0CE-C0F62D188114}
+FOOGUIDDECL const GUID standard_commands::guid_main_add_location =
+{ 0x9ca39d38, 0xac9b, 0x4cca, { 0xb0, 0xce, 0xc0, 0xf6, 0x2d, 0x18, 0x81, 0x14 } };
+
+// {73D6E69D-0DC9-4d5c-A7EE-FF4BE3896B08}
+FOOGUIDDECL const GUID standard_commands::guid_main_add_playlist =
+{ 0x73d6e69d, 0xdc9, 0x4d5c, { 0xa7, 0xee, 0xff, 0x4b, 0xe3, 0x89, 0x6b, 0x8 } };
+
+// {55559142-7AEA-4c20-9B72-1D48E970A274}
+FOOGUIDDECL const GUID standard_commands::guid_main_clear_playlist =
+{ 0x55559142, 0x7aea, 0x4c20, { 0x9b, 0x72, 0x1d, 0x48, 0xe9, 0x70, 0xa2, 0x74 } };
+
+// {BF72488F-36AC-46b3-A36D-193E60C79BC5}
+FOOGUIDDECL const GUID standard_commands::guid_main_create_playlist =
+{ 0xbf72488f, 0x36ac, 0x46b3, { 0xa3, 0x6d, 0x19, 0x3e, 0x60, 0xc7, 0x9b, 0xc5 } };
+
+// {59E99BEE-42A3-4526-B06D-56C0C49F0BC1}
+FOOGUIDDECL const GUID standard_commands::guid_main_highlight_playing =
+{ 0x59e99bee, 0x42a3, 0x4526, { 0xb0, 0x6d, 0x56, 0xc0, 0xc4, 0x9f, 0xb, 0xc1 } };
+
+// {D94393D4-9DBB-4e5c-BE8C-BE9CA80E214D}
+FOOGUIDDECL const GUID standard_commands::guid_main_load_playlist =
+{ 0xd94393d4, 0x9dbb, 0x4e5c, { 0xbe, 0x8c, 0xbe, 0x9c, 0xa8, 0xe, 0x21, 0x4d } };
+
+// {EE1308C5-EBD2-48f1-959D-2627069C2E0F}
+FOOGUIDDECL const GUID standard_commands::guid_main_next_playlist =
+{ 0xee1308c5, 0xebd2, 0x48f1, { 0x95, 0x9d, 0x26, 0x27, 0x6, 0x9c, 0x2e, 0xf } };
+
+// {486ECDA3-7BA2-49e9-BB44-4DB9DF9320C7}
+FOOGUIDDECL const GUID standard_commands::guid_main_previous_playlist =
+{ 0x486ecda3, 0x7ba2, 0x49e9, { 0xbb, 0x44, 0x4d, 0xb9, 0xdf, 0x93, 0x20, 0xc7 } };
+
+// {69C778AA-B836-40a0-89CD-7A2E50C102CB}
+FOOGUIDDECL const GUID standard_commands::guid_main_open =
+{ 0x69c778aa, 0xb836, 0x40a0, { 0x89, 0xcd, 0x7a, 0x2e, 0x50, 0xc1, 0x2, 0xcb } };
+
+// {EB7FB5A4-5904-4d2c-B66C-D882A3B15277}
+FOOGUIDDECL const GUID standard_commands::guid_main_remove_playlist =
+{ 0xeb7fb5a4, 0x5904, 0x4d2c, { 0xb6, 0x6c, 0xd8, 0x82, 0xa3, 0xb1, 0x52, 0x77 } };
+
+// {C297BADB-8098-45a9-A5E8-B53A0D780CE3}
+FOOGUIDDECL const GUID standard_commands::guid_main_remove_dead_entries =
+{ 0xc297badb, 0x8098, 0x45a9, { 0xa5, 0xe8, 0xb5, 0x3a, 0xd, 0x78, 0xc, 0xe3 } };
+
+// {D08C2921-7750-4979-98F9-3A513A31FF96}
+FOOGUIDDECL const GUID standard_commands::guid_main_remove_duplicates =
+{ 0xd08c2921, 0x7750, 0x4979, { 0x98, 0xf9, 0x3a, 0x51, 0x3a, 0x31, 0xff, 0x96 } };
+
+// {D3A25E47-BA98-4e6b-95AD-A7502919EB75}
+FOOGUIDDECL const GUID standard_commands::guid_main_rename_playlist =
+{ 0xd3a25e47, 0xba98, 0x4e6b, { 0x95, 0xad, 0xa7, 0x50, 0x29, 0x19, 0xeb, 0x75 } };
+
+// {0FDCFC65-9B39-445a-AA88-4D245F217480}
+FOOGUIDDECL const GUID standard_commands::guid_main_save_all_playlists =
+{ 0xfdcfc65, 0x9b39, 0x445a, { 0xaa, 0x88, 0x4d, 0x24, 0x5f, 0x21, 0x74, 0x80 } };
+
+// {370B720B-4CF7-465b-908C-2D2ADD027900}
+FOOGUIDDECL const GUID standard_commands::guid_main_save_playlist =
+{ 0x370b720b, 0x4cf7, 0x465b, { 0x90, 0x8c, 0x2d, 0x2a, 0xdd, 0x2, 0x79, 0x0 } };
+
+// {A6CFC2A8-56B3-4d12-88E7-0237961AC47E}
+FOOGUIDDECL const GUID standard_commands::guid_main_playlist_search =
+{ 0xa6cfc2a8, 0x56b3, 0x4d12, { 0x88, 0xe7, 0x2, 0x37, 0x96, 0x1a, 0xc4, 0x7e } };
+
+// {383D4E8D-7E30-4fb8-B5DD-8C975D89E58E}
+FOOGUIDDECL const GUID standard_commands::guid_main_playlist_sel_crop =
+{ 0x383d4e8d, 0x7e30, 0x4fb8, { 0xb5, 0xdd, 0x8c, 0x97, 0x5d, 0x89, 0xe5, 0x8e } };
+
+// {E0EEA319-E282-4e6c-8B82-4DFD42A1D4ED}
+FOOGUIDDECL const GUID standard_commands::guid_main_playlist_sel_remove =
+{ 0xe0eea319, 0xe282, 0x4e6c, { 0x8b, 0x82, 0x4d, 0xfd, 0x42, 0xa1, 0xd4, 0xed } };
+
+// {F0845920-7F6D-40ac-B2EB-3D00C2C8260B}
+FOOGUIDDECL const GUID standard_commands::guid_main_playlist_sel_invert =
+{ 0xf0845920, 0x7f6d, 0x40ac, { 0xb2, 0xeb, 0x3d, 0x0, 0xc2, 0xc8, 0x26, 0xb } };
+
+// {29910B33-79E9-40da-992B-5A4AA4281F78}
+FOOGUIDDECL const GUID standard_commands::guid_main_playlist_undo =
+{ 0x29910b33, 0x79e9, 0x40da, { 0x99, 0x2b, 0x5a, 0x4a, 0xa4, 0x28, 0x1f, 0x78 } };
+
+// {7A9D9450-A8BF-4a88-B44F-DCD83A49DD7A}
+FOOGUIDDECL const GUID standard_commands::guid_main_playlist_redo =
+{ 0x7a9d9450, 0xa8bf, 0x4a88, { 0xb4, 0x4f, 0xdc, 0xd8, 0x3a, 0x49, 0xdd, 0x7a } };
+
+// {02D89A8A-5F7D-41c3-A215-6731D8621036}
+FOOGUIDDECL const GUID standard_commands::guid_main_show_console =
+{ 0x2d89a8a, 0x5f7d, 0x41c3, { 0xa2, 0x15, 0x67, 0x31, 0xd8, 0x62, 0x10, 0x36 } };
+
+// {E6970E91-33BE-4288-AC01-4B02F07B5D38}
+FOOGUIDDECL const GUID standard_commands::guid_main_play_cd =
+{ 0xe6970e91, 0x33be, 0x4288, { 0xac, 0x1, 0x4b, 0x2, 0xf0, 0x7b, 0x5d, 0x38 } };
+
+// {1073AB1D-38ED-4957-8B06-38BC878C1F40}
+FOOGUIDDECL const GUID standard_commands::guid_main_restart_resetconfig =
+{ 0x1073ab1d, 0x38ed, 0x4957, { 0x8b, 0x6, 0x38, 0xbc, 0x87, 0x8c, 0x1f, 0x40 } };
+
+// {FDC8A1C2-93EF-4415-8C20-60B6517F0B5F}
+FOOGUIDDECL const GUID standard_commands::guid_main_record =
+{ 0xfdc8a1c2, 0x93ef, 0x4415, { 0x8c, 0x20, 0x60, 0xb6, 0x51, 0x7f, 0xb, 0x5f } };
+
+// {45EB37D2-3CD9-4f0a-9B20-8EAE649D7A9F}
+FOOGUIDDECL const GUID standard_commands::guid_main_playlist_moveback =
+{ 0x45eb37d2, 0x3cd9, 0x4f0a, { 0x9b, 0x20, 0x8e, 0xae, 0x64, 0x9d, 0x7a, 0x9f } };
+
+// {02298938-596A-41f7-A398-19766A06E6EB}
+FOOGUIDDECL const GUID standard_commands::guid_main_playlist_moveforward =
+{ 0x2298938, 0x596a, 0x41f7, { 0xa3, 0x98, 0x19, 0x76, 0x6a, 0x6, 0xe6, 0xeb } };
+
+// {E910ACC6-A81A-4a20-9F62-19015BCD1013}
+FOOGUIDDECL const GUID standard_commands::guid_main_saveconfig =
+{ 0xe910acc6, 0xa81a, 0x4a20, { 0x9f, 0x62, 0x19, 0x1, 0x5b, 0xcd, 0x10, 0x13 } };
+
+// {03445FCC-71D9-4e01-AE02-A557D30B4CD7}
+FOOGUIDDECL const GUID standard_commands::guid_main_playlist_select_all =
+{ 0x3445fcc, 0x71d9, 0x4e01, { 0xae, 0x2, 0xa5, 0x57, 0xd3, 0xb, 0x4c, 0xd7 } };
+
+// {919FA72B-1DF9-49ee-A8F1-D8BA1DEAA7E9}
+FOOGUIDDECL const GUID standard_commands::guid_main_show_now_playing =
+{ 0x919fa72b, 0x1df9, 0x49ee, { 0xa8, 0xf1, 0xd8, 0xba, 0x1d, 0xea, 0xa7, 0xe9 } };
+
+// {D8D51855-D79D-49b8-97A8-065785FA2426}
+FOOGUIDDECL const GUID playlist_manager::class_guid=
+{ 0xd8d51855, 0xd79d, 0x49b8, { 0x97, 0xa8, 0x6, 0x57, 0x85, 0xfa, 0x24, 0x26 } };
+
+// {C303A0F1-8E88-4539-87E5-9E455B7D548C}
+FOOGUIDDECL const GUID genrand_service::class_guid=
+{ 0xc303a0f1, 0x8e88, 0x4539, { 0x87, 0xe5, 0x9e, 0x45, 0x5b, 0x7d, 0x54, 0x8c } };
+
+// {EB8FA333-F365-46ad-8621-345671567BAA}
+FOOGUIDDECL const GUID playlist_incoming_item_filter::class_guid=
+{ 0xeb8fa333, 0xf365, 0x46ad, { 0x86, 0x21, 0x34, 0x56, 0x71, 0x56, 0x7b, 0xaa } };
+
+// {FEBD85B5-C12D-45b5-B55D-0D3F432B0C6B}
+FOOGUIDDECL const GUID library_manager::class_guid=
+{ 0xfebd85b5, 0xc12d, 0x45b5, { 0xb5, 0x5d, 0xd, 0x3f, 0x43, 0x2b, 0xc, 0x6b } };
+
+// {9A08B50F-E8C6-40c0-88C3-7530CF2C3115}
+FOOGUIDDECL const GUID library_callback::class_guid=
+{ 0x9a08b50f, 0xe8c6, 0x40c0, { 0x88, 0xc3, 0x75, 0x30, 0xcf, 0x2c, 0x31, 0x15 } };
+
+// {D5CAC75A-3023-4dce-8B0D-B502BD056A7C}
+FOOGUIDDECL const GUID popup_message::class_guid=
+{ 0xd5cac75a, 0x3023, 0x4dce, { 0x8b, 0xd, 0xb5, 0x2, 0xbd, 0x5, 0x6a, 0x7c } };
+
+// {13F9CB11-0EAE-4417-AF0C-8894DEB65E8B}
+FOOGUIDDECL const GUID app_close_blocker::class_guid=
+{ 0x13f9cb11, 0xeae, 0x4417, { 0xaf, 0xc, 0x88, 0x94, 0xde, 0xb6, 0x5e, 0x8b } };
+
+// {5570A2D2-8F9E-48a7-AFAC-DAC00A3C1636}
+FOOGUIDDECL const GUID file_operation_callback::class_guid=
+{ 0x5570a2d2, 0x8f9e, 0x48a7, { 0xaf, 0xac, 0xda, 0xc0, 0xa, 0x3c, 0x16, 0x36 } };
+
+// {942F5EFE-D68B-4bde-BA17-C442A8B2A445}
+FOOGUIDDECL const GUID titleformat_config::class_guid=
+{ 0x942f5efe, 0xd68b, 0x4bde, { 0xba, 0x17, 0xc4, 0x42, 0xa8, 0xb2, 0xa4, 0x45 } };
+
+// {9F33EDF0-B8F0-4d11-B27B-4FC1D3B3489F}
+FOOGUIDDECL const GUID titleformat_config_callback::class_guid=
+{ 0x9f33edf0, 0xb8f0, 0x4d11, { 0xb2, 0x7b, 0x4f, 0xc1, 0xd3, 0xb3, 0x48, 0x9f } };
+
+// {B905715B-4B26-4e0e-B3B8-FF4A232A4258}
+FOOGUIDDECL const GUID titleformat_config::config_playlist=
+{ 0xb905715b, 0x4b26, 0x4e0e, { 0xb3, 0xb8, 0xff, 0x4a, 0x23, 0x2a, 0x42, 0x58 } };
+
+// {A2051E09-A1EA-471b-B146-7375413105D2}
+FOOGUIDDECL const GUID titleformat_config::config_copy=
+{ 0xa2051e09, 0xa1ea, 0x471b, { 0xb1, 0x46, 0x73, 0x75, 0x41, 0x31, 0x5, 0xd2 } };
+
+// {70B56942-3C37-427b-8D58-3A2DF3D835BD}
+FOOGUIDDECL const GUID titleformat_config::config_statusbar=
+{ 0x70b56942, 0x3c37, 0x427b, { 0x8d, 0x58, 0x3a, 0x2d, 0xf3, 0xd8, 0x35, 0xbd } };
+
+// {8E728600-7BBD-4a5c-A001-40A450427EB6}
+FOOGUIDDECL const GUID titleformat_config::config_systray=
+{ 0x8e728600, 0x7bbd, 0x4a5c, { 0xa0, 0x1, 0x40, 0xa4, 0x50, 0x42, 0x7e, 0xb6 } };
+
+// {D02F2D01-BED3-46e8-B664-8B1F07E78F69}
+FOOGUIDDECL const GUID titleformat_config::config_windowtitle=
+{ 0xd02f2d01, 0xbed3, 0x46e8, { 0xb6, 0x64, 0x8b, 0x1f, 0x7, 0xe7, 0x8f, 0x69 } };
+
+// {340099D1-7BEC-4ac6-92A4-77FF01507891}
+FOOGUIDDECL const GUID config_object::class_guid=
+{ 0x340099d1, 0x7bec, 0x4ac6, { 0x92, 0xa4, 0x77, 0xff, 0x1, 0x50, 0x78, 0x91 } };
+
+// {1BA04122-DE9A-4a90-9FC3-A6A7EC8F9626}
+FOOGUIDDECL const GUID config_object_notify_manager::class_guid=
+{ 0x1ba04122, 0xde9a, 0x4a90, { 0x9f, 0xc3, 0xa6, 0xa7, 0xec, 0x8f, 0x96, 0x26 } };
+
+// {AD5138E6-CF8F-4482-89B2-B2EAAEDF3B4C}
+FOOGUIDDECL const GUID standard_config_objects::bool_show_keyboard_shortcuts_in_menus=
+{ 0xad5138e6, 0xcf8f, 0x4482, { 0x89, 0xb2, 0xb2, 0xea, 0xae, 0xdf, 0x3b, 0x4c } };
+
+// {E91F618C-5741-470f-A178-21272C3ECA90}
+FOOGUIDDECL const GUID standard_config_objects::bool_remember_window_positions=
+{ 0xe91f618c, 0x5741, 0x470f, { 0xa1, 0x78, 0x21, 0x27, 0x2c, 0x3e, 0xca, 0x90 } };
+
+// {5497FAA9-690C-4fb4-8BC0-678CEBCBBDC4}
+FOOGUIDDECL const GUID standard_config_objects::bool_playback_follows_cursor=
+{ 0x5497faa9, 0x690c, 0x4fb4, { 0x8b, 0xc0, 0x67, 0x8c, 0xeb, 0xcb, 0xbd, 0xc4 } };
+
+// {58D3E2D6-DD6D-48dd-98EB-4EABF0ACFEB8}
+FOOGUIDDECL const GUID standard_config_objects::bool_cursor_follows_playback=
+{ 0x58d3e2d6, 0xdd6d, 0x48dd, { 0x98, 0xeb, 0x4e, 0xab, 0xf0, 0xac, 0xfe, 0xb8 } };
+
+// {2DF7194D-86FC-4312-98DA-E820DA3E710D}
+FOOGUIDDECL const GUID standard_config_objects::bool_ui_always_on_top=
+{ 0x2df7194d, 0x86fc, 0x4312, { 0x98, 0xda, 0xe8, 0x20, 0xda, 0x3e, 0x71, 0xd } };
+
+// {B572C86F-4206-40a0-8476-C7B27E74DB2D}
+FOOGUIDDECL const GUID standard_config_objects::bool_playlist_stop_after_current=
+{ 0xb572c86f, 0x4206, 0x40a0, { 0x84, 0x76, 0xc7, 0xb2, 0x7e, 0x74, 0xdb, 0x2d } };
+
+// {FFDFDA96-699C-4617-A977-22DC2F039B00}
+FOOGUIDDECL const GUID standard_config_objects::string_gui_last_directory_media=
+{ 0xffdfda96, 0x699c, 0x4617, { 0xa9, 0x77, 0x22, 0xdc, 0x2f, 0x3, 0x9b, 0x0 } };
+
+// {915D3B21-81CB-4b96-9762-1C90FBF371DF}
+FOOGUIDDECL const GUID standard_config_objects::string_gui_last_directory_playlists=
+{ 0x915d3b21, 0x81cb, 0x4b96, { 0x97, 0x62, 0x1c, 0x90, 0xfb, 0xf3, 0x71, 0xdf } };
+
+// {338B6871-EB1F-4384-BF83-6BFACE5B66BC}
+FOOGUIDDECL const GUID standard_config_objects::int32_dynamic_bitrate_display_rate=
+{ 0x338b6871, 0xeb1f, 0x4384, { 0xbf, 0x83, 0x6b, 0xfa, 0xce, 0x5b, 0x66, 0xbc } };
+
+// {3E35D949-DCDB-44e1-8013-9D1633C09756}
+FOOGUIDDECL const GUID config_object_notify::class_guid=
+{ 0x3e35d949, 0xdcdb, 0x44e1, { 0x80, 0x13, 0x9d, 0x16, 0x33, 0xc0, 0x97, 0x56 } };
+
+// {4AC9408E-4D9C-4135-ACB5-2CAB35376FC9}
+FOOGUIDDECL const GUID titleformat_object::class_guid=
+{ 0x4ac9408e, 0x4d9c, 0x4135, { 0xac, 0xb5, 0x2c, 0xab, 0x35, 0x37, 0x6f, 0xc9 } };
+
+// {25B0D20D-9BA3-4a7b-8D0E-89FAF75F916F}
+FOOGUIDDECL const GUID tag_processor_id3v2::class_guid=
+{ 0x25b0d20d, 0x9ba3, 0x4a7b, { 0x8d, 0xe, 0x89, 0xfa, 0xf7, 0x5f, 0x91, 0x6f } };
+
+// {AD537D40-499D-4c29-81D4-C0FA496DD58C}
+FOOGUIDDECL const GUID tag_processor_trailing::class_guid=
+{ 0xad537d40, 0x499d, 0x4c29, { 0x81, 0xd4, 0xc0, 0xfa, 0x49, 0x6d, 0xd5, 0x8c } };
+
+// {160885C6-3AA3-4f60-8718-1240615E6414}
+FOOGUIDDECL const GUID metadb_handle::class_guid=
+{ 0x160885c6, 0x3aa3, 0x4f60, { 0x87, 0x18, 0x12, 0x40, 0x61, 0x5e, 0x64, 0x14 } };
+
+// {9DBC262F-4795-4292-824B-23A655011A3E}
+FOOGUIDDECL const GUID threaded_process::class_guid=
+{ 0x9dbc262f, 0x4795, 0x4292, { 0x82, 0x4b, 0x23, 0xa6, 0x55, 0x1, 0x1a, 0x3e } };
+
+// {7B69141B-4271-4070-8998-10CD39249C12}
+FOOGUIDDECL const GUID threaded_process_callback::class_guid=
+{ 0x7b69141b, 0x4271, 0x4070, { 0x89, 0x98, 0x10, 0xcd, 0x39, 0x24, 0x9c, 0x12 } };
+
+
+// {64D18B80-5E97-40e4-A30C-A4640C60BCE5}
+FOOGUIDDECL const GUID metadb_io::class_guid=
+{ 0x64d18b80, 0x5e97, 0x40e4, { 0xa3, 0xc, 0xa4, 0x64, 0xc, 0x60, 0xbc, 0xe5 } };
+
+// {B9218D23-F73D-4b61-A1D9-BFD420CDAC77}
+FOOGUIDDECL const GUID preferences_page::guid_root=
+{ 0xb9218d23, 0xf73d, 0x4b61, { 0xa1, 0xd9, 0xbf, 0xd4, 0x20, 0xcd, 0xac, 0x77 } };
+
+// {2F0E2232-A5FD-43e4-B6AB-3839B8D1A707}
+FOOGUIDDECL const GUID preferences_page::guid_hidden=
+{ 0x2f0e2232, 0xa5fd, 0x43e4, { 0xb6, 0xab, 0x38, 0x39, 0xb8, 0xd1, 0xa7, 0x7 } };
+
+// {627C0767-0793-44f8-8087-BE4934311282}
+FOOGUIDDECL const GUID preferences_page::guid_tools=
+{ 0x627c0767, 0x793, 0x44f8, { 0x80, 0x87, 0xbe, 0x49, 0x34, 0x31, 0x12, 0x82 } };
+
+// {6AAA67B6-732F-4967-899A-18C5F8C70017}
+FOOGUIDDECL const GUID preferences_page::guid_display=
+{ 0x6aaa67b6, 0x732f, 0x4967, { 0x89, 0x9a, 0x18, 0xc5, 0xf8, 0xc7, 0x0, 0x17 } };
+
+// {67508677-CFCC-4a1c-921C-49B39CC5B986}
+FOOGUIDDECL const GUID preferences_page::guid_playback=
+{ 0x67508677, 0xcfcc, 0x4a1c, { 0x92, 0x1c, 0x49, 0xb3, 0x9c, 0xc5, 0xb9, 0x86 } };
+
+// {494326C8-88FF-4265-B2B2-E6470BEE13B3}
+FOOGUIDDECL const GUID preferences_page::guid_visualisations=
+{ 0x494326c8, 0x88ff, 0x4265, { 0xb2, 0xb2, 0xe6, 0x47, 0xb, 0xee, 0x13, 0xb3 } };
+
+// {FC01B529-4BD7-47cd-BAF7-2FB632F0DBB6}
+FOOGUIDDECL const GUID preferences_page::guid_input=
+{ 0xfc01b529, 0x4bd7, 0x47cd, { 0xba, 0xf7, 0x2f, 0xb6, 0x32, 0xf0, 0xdb, 0xb6 } };
+
+// {2E8E9647-4174-41b2-9EC4-910BE128082E}
+FOOGUIDDECL const GUID preferences_page::guid_core=
+{ 0x2e8e9647, 0x4174, 0x41b2, { 0x9e, 0xc4, 0x91, 0xb, 0xe1, 0x28, 0x8, 0x2e } };
+
+// {7D0334E5-ADD7-4ff5-9DB8-A618B4824028}
+FOOGUIDDECL const GUID preferences_page::guid_tag_writing=
+{ 0x7d0334e5, 0xadd7, 0x4ff5, { 0x9d, 0xb8, 0xa6, 0x18, 0xb4, 0x82, 0x40, 0x28 } };
+
+// {2D269FA9-6F78-4cec-9F1F-0A176EFCE77A}
+FOOGUIDDECL const GUID preferences_page::guid_media_library=
+{ 0x2d269fa9, 0x6f78, 0x4cec, { 0x9f, 0x1f, 0xa, 0x17, 0x6e, 0xfc, 0xe7, 0x7a } };
+
+// {B8C5CEEA-A5F4-4278-AA2D-798E4403001F}
+FOOGUIDDECL const GUID library_viewer::class_guid=
+{ 0xb8c5ceea, 0xa5f4, 0x4278, { 0xaa, 0x2d, 0x79, 0x8e, 0x44, 0x3, 0x0, 0x1f } };
+
+// {5CD49B5D-D604-4c07-A8FA-FFD8512AFD2B}
+FOOGUIDDECL const GUID message_loop::class_guid=
+{ 0x5cd49b5d, 0xd604, 0x4c07, { 0xa8, 0xfa, 0xff, 0xd8, 0x51, 0x2a, 0xfd, 0x2b } };
+
+// {932EC96D-4DFD-4ed7-A07C-2A22BE770185}
+FOOGUIDDECL const GUID chapterizer::class_guid=
+{ 0x932ec96d, 0x4dfd, 0x4ed7, { 0xa0, 0x7c, 0x2a, 0x22, 0xbe, 0x77, 0x1, 0x85 } };
+
+// {7EB442CD-FAD7-4a26-AD7E-16F6FC89207B}
+FOOGUIDDECL const GUID input_decoder::class_guid =
+{ 0x7eb442cd, 0xfad7, 0x4a26, { 0xad, 0x7e, 0x16, 0xf6, 0xfc, 0x89, 0x20, 0x7b } };
+
+// {8E9BB1D4-A52B-4df6-A929-1AAE4075388A}
+FOOGUIDDECL const GUID input_info_reader::class_guid =
+{ 0x8e9bb1d4, 0xa52b, 0x4df6, { 0xa9, 0x29, 0x1a, 0xae, 0x40, 0x75, 0x38, 0x8a } };
+
+// {FE40FF66-64C9-4234-B639-028DC8060CF7}
+FOOGUIDDECL const GUID input_info_writer::class_guid =
+{ 0xfe40ff66, 0x64c9, 0x4234, { 0xb6, 0x39, 0x2, 0x8d, 0xc8, 0x6, 0xc, 0xf7 } };
+
+// {436547FC-C4EF-4322-B59E-E696A25FAB2C}
+FOOGUIDDECL const GUID input_entry::class_guid =
+{ 0x436547fc, 0xc4ef, 0x4322, { 0xb5, 0x9e, 0xe6, 0x96, 0xa2, 0x5f, 0xab, 0x2c } };
+
+// {3296219B-EBA5-4c32-A193-C9BB174801DA}
+FOOGUIDDECL const GUID link_resolver::class_guid =
+{ 0x3296219b, 0xeba5, 0x4c32, { 0xa1, 0x93, 0xc9, 0xbb, 0x17, 0x48, 0x1, 0xda } };
+
+// {A49E087E-D064-4b2e-A08D-11264F691FFE}
+FOOGUIDDECL const GUID playback_queue_callback::class_guid =
+{ 0xa49e087e, 0xd064, 0x4b2e, { 0xa0, 0x8d, 0x11, 0x26, 0x4f, 0x69, 0x1f, 0xfe } };
+
+// {1131D64B-04CB-43ee-95EB-24D18B753248}
+FOOGUIDDECL const GUID main_thread_callback_manager::class_guid =
+{ 0x1131d64b, 0x4cb, 0x43ee, { 0x95, 0xeb, 0x24, 0xd1, 0x8b, 0x75, 0x32, 0x48 } };
+
+// {87D2C583-7AFB-4e58-B21E-FBD3E6E8F5E7}
+FOOGUIDDECL const GUID main_thread_callback::class_guid =
+{ 0x87d2c583, 0x7afb, 0x4e58, { 0xb2, 0x1e, 0xfb, 0xd3, 0xe6, 0xe8, 0xf5, 0xe7 } };
+
+
+
+// {21656AB9-0255-4f8c-8FB9-1A7748BCE93A}
+FOOGUIDDECL const GUID mainmenu_group::class_guid =
+{ 0x21656ab9, 0x255, 0x4f8c, { 0x8f, 0xb9, 0x1a, 0x77, 0x48, 0xbc, 0xe9, 0x3a } };
+
+// {2E673A2E-A4EE-419c-94C8-9C838660414C}
+FOOGUIDDECL const GUID mainmenu_group_popup::class_guid =
+{ 0x2e673a2e, 0xa4ee, 0x419c, { 0x94, 0xc8, 0x9c, 0x83, 0x86, 0x60, 0x41, 0x4c } };
+
+// {35077B8C-6E70-47ba-B9DD-D51500E12F2E}
+FOOGUIDDECL const GUID mainmenu_commands::class_guid =
+{ 0x35077b8c, 0x6e70, 0x47ba, { 0xb9, 0xdd, 0xd5, 0x15, 0x0, 0xe1, 0x2f, 0x2e } };
+
+// {350B3EA8-6B3E-4346-B6D2-799E98EFC920}
+FOOGUIDDECL const GUID mainmenu_manager::class_guid =
+{ 0x350b3ea8, 0x6b3e, 0x4346, { 0xb6, 0xd2, 0x79, 0x9e, 0x98, 0xef, 0xc9, 0x20 } };
+
+
+// {8F487F1F-419F-47a7-8ECF-EC44AF4449A3}
+FOOGUIDDECL const GUID mainmenu_groups::file =
+{ 0x8f487f1f, 0x419f, 0x47a7, { 0x8e, 0xcf, 0xec, 0x44, 0xaf, 0x44, 0x49, 0xa3 } };
+
+// {F8BE5604-165F-4bb9-B6A9-15E55E0E0D3A}
+FOOGUIDDECL const GUID mainmenu_groups::view =
+{ 0xf8be5604, 0x165f, 0x4bb9, { 0xb6, 0xa9, 0x15, 0xe5, 0x5e, 0xe, 0xd, 0x3a } };
+
+// {8CDA6B10-0613-4cfd-8730-3B9CBF4C6A39}
+FOOGUIDDECL const GUID mainmenu_groups::edit =
+{ 0x8cda6b10, 0x613, 0x4cfd, { 0x87, 0x30, 0x3b, 0x9c, 0xbf, 0x4c, 0x6a, 0x39 } };
+
+// {D8A4FC46-5E3D-47aa-97B7-947988228246}
+FOOGUIDDECL const GUID mainmenu_groups::edit_part1 =
+{ 0xd8a4fc46, 0x5e3d, 0x47aa, { 0x97, 0xb7, 0x94, 0x79, 0x88, 0x22, 0x82, 0x46 } };
+
+// {007682CE-2A99-4b70-8F63-DE765D1C5555}
+FOOGUIDDECL const GUID mainmenu_groups::edit_part2 =
+{ 0x7682ce, 0x2a99, 0x4b70, { 0x8f, 0x63, 0xde, 0x76, 0x5d, 0x1c, 0x55, 0x55 } };
+
+// {1F572090-D620-4940-85EC-0EFE499FAC03}
+FOOGUIDDECL const GUID mainmenu_groups::edit_part3 =
+{ 0x1f572090, 0xd620, 0x4940, { 0x85, 0xec, 0xe, 0xfe, 0x49, 0x9f, 0xac, 0x3 } };
+
+// {65FA047A-1599-4b9c-B53D-C3FEB716339D}
+FOOGUIDDECL const GUID mainmenu_groups::edit_part2_selection =
+{ 0x65fa047a, 0x1599, 0x4b9c, { 0xb5, 0x3d, 0xc3, 0xfe, 0xb7, 0x16, 0x33, 0x9d } };
+
+// {5B8AEF2C-6E1A-420d-B488-3E3A00E39E28}
+FOOGUIDDECL const GUID mainmenu_groups::edit_part2_sort =
+{ 0x5b8aef2c, 0x6e1a, 0x420d, { 0xb4, 0x88, 0x3e, 0x3a, 0x0, 0xe3, 0x9e, 0x28 } };
+
+// {EE9D6F72-7BC7-4a60-8C28-B96DED252BD3}
+FOOGUIDDECL const GUID mainmenu_groups::edit_part2_selection_sort =
+{ 0xee9d6f72, 0x7bc7, 0x4a60, { 0x8c, 0x28, 0xb9, 0x6d, 0xed, 0x25, 0x2b, 0xd3 } };
+
+// {53FA5B8A-FCBC-4296-B968-45BAE6888845}
+FOOGUIDDECL const GUID mainmenu_groups::playback =
+{ 0x53fa5b8a, 0xfcbc, 0x4296, { 0xb9, 0x68, 0x45, 0xba, 0xe6, 0x88, 0x88, 0x45 } };
+
+// {15D22753-9D30-4929-AA14-5124016F7E68}
+FOOGUIDDECL const GUID mainmenu_groups::library =
+{ 0x15d22753, 0x9d30, 0x4929, { 0xaa, 0x14, 0x51, 0x24, 0x1, 0x6f, 0x7e, 0x68 } };
+
+// {25DC3DB7-996A-4f48-AF53-712032EFA04F}
+FOOGUIDDECL const GUID mainmenu_groups::help =
+{ 0x25dc3db7, 0x996a, 0x4f48, { 0xaf, 0x53, 0x71, 0x20, 0x32, 0xef, 0xa0, 0x4f } };
+
+// {8EED252D-0A0F-4fc9-9D81-8CF7209A8BF2}
+FOOGUIDDECL const GUID mainmenu_groups::file_open =
+{ 0x8eed252d, 0xa0f, 0x4fc9, { 0x9d, 0x81, 0x8c, 0xf7, 0x20, 0x9a, 0x8b, 0xf2 } };
+
+// {9E650B8E-C3F3-4495-AF15-6B656060C3B9}
+FOOGUIDDECL const GUID mainmenu_groups::file_add =
+{ 0x9e650b8e, 0xc3f3, 0x4495, { 0xaf, 0x15, 0x6b, 0x65, 0x60, 0x60, 0xc3, 0xb9 } };
+
+// {9995FAE6-B1C4-457f-A747-5BD120930210}
+FOOGUIDDECL const GUID mainmenu_groups::file_playlist =
+{ 0x9995fae6, 0xb1c4, 0x457f, { 0xa7, 0x47, 0x5b, 0xd1, 0x20, 0x93, 0x2, 0x10 } };
+
+// {8A324F18-6173-42ec-A640-5E296AD446B3}
+FOOGUIDDECL const GUID mainmenu_groups::file_etc =
+{ 0x8a324f18, 0x6173, 0x42ec, { 0xa6, 0x40, 0x5e, 0x29, 0x6a, 0xd4, 0x46, 0xb3 } };
+
+// {12F5E247-5A81-4734-8119-8F9BC114FE74}
+FOOGUIDDECL const GUID mainmenu_groups::playback_controls =
+{ 0x12f5e247, 0x5a81, 0x4734, { 0x81, 0x19, 0x8f, 0x9b, 0xc1, 0x14, 0xfe, 0x74 } };
+
+// {1169B3EB-81B5-4199-8929-7D3EAFD4809F}
+FOOGUIDDECL const GUID mainmenu_groups::playback_etc =
+{ 0x1169b3eb, 0x81b5, 0x4199, { 0x89, 0x29, 0x7d, 0x3e, 0xaf, 0xd4, 0x80, 0x9f } };
+
+// {29272FEC-21C7-4b00-A9A7-01A8CE675EBF}
+FOOGUIDDECL const GUID mainmenu_groups::view_visualisations =
+{ 0x29272fec, 0x21c7, 0x4b00, { 0xa9, 0xa7, 0x1, 0xa8, 0xce, 0x67, 0x5e, 0xbf } };
+
+// {2DA055D4-0257-40b2-8281-7967866B485C}
+FOOGUIDDECL const GUID mainmenu_groups::file_etc_preferences =
+{ 0x2da055d4, 0x257, 0x40b2, { 0x82, 0x81, 0x79, 0x67, 0x86, 0x6b, 0x48, 0x5c } };
+
+// {517BFAE8-A148-4cb2-8CCE-1AD2179FB910}
+FOOGUIDDECL const GUID mainmenu_groups::file_etc_exit =
+{ 0x517bfae8, 0xa148, 0x4cb2, { 0x8c, 0xce, 0x1a, 0xd2, 0x17, 0x9f, 0xb9, 0x10 } };
+
+// {61190F78-3B3A-4fda-A431-2CF7DA1C96CE}
+FOOGUIDDECL const GUID mainmenu_groups::view_alwaysontop =
+{ 0x61190f78, 0x3b3a, 0x4fda, { 0xa4, 0x31, 0x2c, 0xf7, 0xda, 0x1c, 0x96, 0xce } };
+
+// {E55F8D65-AE51-47bf-99F9-BB113421CB19}
+FOOGUIDDECL const GUID mainmenu_groups::help_about =
+{ 0xe55f8d65, 0xae51, 0x47bf, { 0x99, 0xf9, 0xbb, 0x11, 0x34, 0x21, 0xcb, 0x19 } };
+
+// {696DF823-B7AE-4b73-95C8-C1E9A9410726}
+FOOGUIDDECL const GUID mainmenu_groups::library_refresh=
+{ 0x696df823, 0xb7ae, 0x4b73, { 0x95, 0xc8, 0xc1, 0xe9, 0xa9, 0x41, 0x7, 0x26 } };
+
+// {004BF6ED-2F88-464f-BDC1-278F6E610C2F}
+FOOGUIDDECL const GUID standard_commands::guid_seek_ahead_1s =
+{ 0x4bf6ed, 0x2f88, 0x464f, { 0xbd, 0xc1, 0x27, 0x8f, 0x6e, 0x61, 0xc, 0x2f } };
+
+// {5B56D124-2ECA-4b0f-9895-2A533B31D29E}
+FOOGUIDDECL const GUID standard_commands::guid_seek_ahead_5s =
+{ 0x5b56d124, 0x2eca, 0x4b0f, { 0x98, 0x95, 0x2a, 0x53, 0x3b, 0x31, 0xd2, 0x9e } };
+
+// {B582E3CA-D86D-4568-8380-68BC9C93ED0E}
+FOOGUIDDECL const GUID standard_commands::guid_seek_ahead_10s =
+{ 0xb582e3ca, 0xd86d, 0x4568, { 0x83, 0x80, 0x68, 0xbc, 0x9c, 0x93, 0xed, 0xe } };
+
+// {DE6B96B7-3074-4da9-A260-988E31CEE0F9}
+FOOGUIDDECL const GUID standard_commands::guid_seek_ahead_30s =
+{ 0xde6b96b7, 0x3074, 0x4da9, { 0xa2, 0x60, 0x98, 0x8e, 0x31, 0xce, 0xe0, 0xf9 } };
+
+// {FEED4AD7-13D2-4846-8833-D91B5F8B4E94}
+FOOGUIDDECL const GUID standard_commands::guid_seek_ahead_1min =
+{ 0xfeed4ad7, 0x13d2, 0x4846, { 0x88, 0x33, 0xd9, 0x1b, 0x5f, 0x8b, 0x4e, 0x94 } };
+
+// {ECCF4904-03CF-429a-9D99-7A87FA62FD10}
+FOOGUIDDECL const GUID standard_commands::guid_seek_ahead_2min =
+{ 0xeccf4904, 0x3cf, 0x429a, { 0x9d, 0x99, 0x7a, 0x87, 0xfa, 0x62, 0xfd, 0x10 } };
+
+// {5F0F0AF7-F519-41e6-A8DB-04DF1390E69D}
+FOOGUIDDECL const GUID standard_commands::guid_seek_ahead_5min =
+{ 0x5f0f0af7, 0xf519, 0x41e6, { 0xa8, 0xdb, 0x4, 0xdf, 0x13, 0x90, 0xe6, 0x9d } };
+
+// {9ABA4292-1B8F-42ac-93AC-34B2A74C6320}
+FOOGUIDDECL const GUID standard_commands::guid_seek_ahead_10min =
+{ 0x9aba4292, 0x1b8f, 0x42ac, { 0x93, 0xac, 0x34, 0xb2, 0xa7, 0x4c, 0x63, 0x20 } };
+
+// {2F89AB1C-5646-4997-8E3F-92BEE0322A41}
+FOOGUIDDECL const GUID standard_commands::guid_seek_back_1s =
+{ 0x2f89ab1c, 0x5646, 0x4997, { 0x8e, 0x3f, 0x92, 0xbe, 0xe0, 0x32, 0x2a, 0x41 } };
+
+// {0CE84538-2E21-4482-BFE1-BCEC471467CC}
+FOOGUIDDECL const GUID standard_commands::guid_seek_back_5s =
+{ 0xce84538, 0x2e21, 0x4482, { 0xbf, 0xe1, 0xbc, 0xec, 0x47, 0x14, 0x67, 0xcc } };
+
+// {9F504218-AF5D-41a8-BCE3-26313FAE65EE}
+FOOGUIDDECL const GUID standard_commands::guid_seek_back_10s =
+{ 0x9f504218, 0xaf5d, 0x41a8, { 0xbc, 0xe3, 0x26, 0x31, 0x3f, 0xae, 0x65, 0xee } };
+
+// {98239B89-F66E-4160-B650-D9B068C59E63}
+FOOGUIDDECL const GUID standard_commands::guid_seek_back_30s =
+{ 0x98239b89, 0xf66e, 0x4160, { 0xb6, 0x50, 0xd9, 0xb0, 0x68, 0xc5, 0x9e, 0x63 } };
+
+// {6633226B-9AA9-4810-AFDA-185A281D9FE2}
+FOOGUIDDECL const GUID standard_commands::guid_seek_back_1min =
+{ 0x6633226b, 0x9aa9, 0x4810, { 0xaf, 0xda, 0x18, 0x5a, 0x28, 0x1d, 0x9f, 0xe2 } };
+
+// {E2F8B8BB-C539-44f3-A300-13185DE52227}
+FOOGUIDDECL const GUID standard_commands::guid_seek_back_2min =
+{ 0xe2f8b8bb, 0xc539, 0x44f3, { 0xa3, 0x0, 0x13, 0x18, 0x5d, 0xe5, 0x22, 0x27 } };
+
+// {7B41A130-01D2-4a1b-9CAD-6314633C61C4}
+FOOGUIDDECL const GUID standard_commands::guid_seek_back_5min =
+{ 0x7b41a130, 0x1d2, 0x4a1b, { 0x9c, 0xad, 0x63, 0x14, 0x63, 0x3c, 0x61, 0xc4 } };
+
+// {0B012852-BAF9-4f6b-B947-FAB89AE76B79}
+FOOGUIDDECL const GUID standard_commands::guid_seek_back_10min =
+{ 0xb012852, 0xbaf9, 0x4f6b, { 0xb9, 0x47, 0xfa, 0xb8, 0x9a, 0xe7, 0x6b, 0x79 } };
+
+// {97215C5E-7228-4237-B52C-A2B5504EF726}
+FOOGUIDDECL const GUID playback_statistics_collector::class_guid =
+{ 0x97215c5e, 0x7228, 0x4237, { 0xb5, 0x2c, 0xa2, 0xb5, 0x50, 0x4e, 0xf7, 0x26 } };
+
+// {9FB1DA49-AF6F-4fd2-9C73-48A8A109003B}
+FOOGUIDDECL const GUID dsp_v2::class_guid =
+{ 0x9fb1da49, 0xaf6f, 0x4fd2, { 0x9c, 0x73, 0x48, 0xa8, 0xa1, 0x9, 0x0, 0x3b } };
+
+// {9EC5D45E-10F5-46a7-9546-F3ACEC68B149}
+FOOGUIDDECL const GUID dsp_entry_v2::class_guid =
+{ 0x9ec5d45e, 0x10f5, 0x46a7, { 0x95, 0x46, 0xf3, 0xac, 0xec, 0x68, 0xb1, 0x49 } };
+
+
+FOOGUIDDECL const GUID advconfig_entry::guid_root = { 0x34949f34, 0xe655, 0x4f09, { 0xba, 0x50, 0xfa, 0xeb, 0x4d, 0x9b, 0x77, 0x69 } };
+FOOGUIDDECL const GUID advconfig_entry::class_guid = { 0x7e84602e, 0xdc49, 0x4047, { 0xaa, 0xee, 0x63, 0x71, 0x8b, 0xbc, 0x5a, 0x1f } };
+FOOGUIDDECL const GUID advconfig_branch::class_guid = { 0x6a60b472, 0x91ac, 0x4681, { 0x9d, 0xc2, 0x76, 0xc9, 0x94, 0x0, 0x5b, 0x63 } };
+FOOGUIDDECL const GUID advconfig_entry_checkbox::class_guid = { 0x5243aba4, 0x2a3d, 0x4627, { 0x88, 0xef, 0xce, 0xe3, 0x76, 0x1c, 0x7, 0x9c } };
+FOOGUIDDECL const GUID advconfig_entry::guid_branch_tagging = { 0xe8fe273f, 0xdd00, 0x476e, { 0xa7, 0x90, 0xe5, 0x9d, 0xf6, 0xb8, 0xf8, 0xd4 } };
+FOOGUIDDECL const GUID advconfig_entry::guid_branch_decoding = { 0x904c272b, 0x2317, 0x4c3c, { 0xb2, 0xff, 0xc5, 0xa0, 0x12, 0x5e, 0x2c, 0xc2 } };
+FOOGUIDDECL const GUID advconfig_entry_string::class_guid = { 0x185d582d, 0xfbd8, 0x4db3, { 0xbe, 0x23, 0x47, 0xaa, 0xc6, 0x75, 0xfc, 0x11 } };
+FOOGUIDDECL const GUID advconfig_entry::guid_branch_tools = { 0x35365484, 0xcc58, 0x4926, { 0x97, 0xe1, 0x5e, 0x63, 0xf3, 0xab, 0xb9, 0xe2 } };
+FOOGUIDDECL const GUID advconfig_entry::guid_branch_playback = { 0xc48d430d, 0x112, 0x4922, { 0x97, 0x23, 0x28, 0x38, 0xc7, 0xd9, 0x7d, 0xd7 } };
+FOOGUIDDECL const GUID advconfig_entry::guid_branch_display = { 0x6c4bc1c8, 0xbaf4, 0x40c3, { 0x9d, 0xb1, 0x9, 0x50, 0x7f, 0xc, 0xc, 0xb9 } };
+
+
+
+FOOGUIDDECL const GUID playback_control_v2::class_guid = { 0x1eb67bda, 0x1345, 0x49ae, { 0x8e, 0x89, 0x50, 0x5, 0xd9, 0x1, 0x62, 0x89 } };
+
+FOOGUIDDECL const GUID preferences_page_v2::class_guid = { 0xce4ebc9e, 0xab20, 0x46f9, { 0x92, 0x5f, 0x88, 0x3b, 0x8, 0x4f, 0x5, 0x69 } };
+FOOGUIDDECL const GUID preferences_branch_v2::class_guid = { 0x167ebeb9, 0x8334, 0x4b21, { 0xaf, 0x58, 0xa7, 0x40, 0xa5, 0xd5, 0xb6, 0x66 } };
+
+
+
+FOOGUIDDECL const GUID advconfig_entry_enum::class_guid = { 0xb1451540, 0x98ec, 0x4d36, { 0x9f, 0x19, 0xe3, 0x10, 0xfb, 0xa7, 0xab, 0x5a } };
+
+FOOGUIDDECL const GUID info_lookup_handler::class_guid = { 0x4fcfdab7, 0x55b5, 0x47d6, { 0xb1, 0x9d, 0xa4, 0xdc, 0x9f, 0xd7, 0x69, 0x4c } };
+
+FOOGUIDDECL const GUID completion_notify::class_guid = { 0xdf26d586, 0xf7ec, 0x40c3, { 0x9f, 0xe8, 0x2e, 0xa0, 0x72, 0x5d, 0x76, 0xc0 } };
+
+FOOGUIDDECL const GUID metadb_io_v2::class_guid = { 0x265c4ece, 0xffb2, 0x4299, { 0x91, 0xb5, 0x6c, 0xa6, 0x60, 0x3d, 0xa1, 0x53 } };
+
+FOOGUIDDECL const GUID file_info_filter::class_guid = { 0x45d0b800, 0xde83, 0x4a77, { 0xad, 0x34, 0x3f, 0x84, 0x2d, 0x40, 0xe7, 0x95 } };
+
+FOOGUIDDECL const GUID metadb_hint_list::class_guid = { 0x719dc072, 0x8d4d, 0x4aa6, { 0xa6, 0xf3, 0x90, 0x73, 0x7, 0xe5, 0xbc, 0xee } };
+
+FOOGUIDDECL const GUID playlist_incoming_item_filter_v2::class_guid = { 0xf335802b, 0xa522, 0x434d, { 0xbe, 0x89, 0xe8, 0x6d, 0x59, 0x56, 0x16, 0x48 } };
+
+FOOGUIDDECL const GUID process_locations_notify::class_guid = { 0x7d7eddac, 0xf93e, 0x4707, { 0x96, 0x9b, 0xcf, 0x44, 0xa9, 0xe1, 0xfb, 0x78 } };
+
+FOOGUIDDECL const GUID library_manager_v2::class_guid = { 0x900eae79, 0x68d0, 0x4900, { 0xa4, 0xd8, 0x18, 0x20, 0x5, 0xae, 0x33, 0x7e } };
+
+FOOGUIDDECL const GUID packet_decoder::owner_Ogg = { 0x8fa27457, 0xa021, 0x43b9, { 0xad, 0x20, 0xa7, 0x96, 0xdb, 0x94, 0x7c, 0xd1 } };
+
+FOOGUIDDECL const GUID packet_decoder::property_ogg_header = { 0xbeb22c78, 0xeb49, 0x4f9e, { 0x9e, 0x37, 0x57, 0xd8, 0x87, 0x40, 0xfb, 0x4c } };
+
+FOOGUIDDECL const GUID packet_decoder::property_ogg_query_sample_rate = { 0x6226bf73, 0x1c37, 0x4aa1, { 0xae, 0xb1, 0x18, 0x8b, 0x4a, 0xf3, 0xae, 0xf7 } };
+
+FOOGUIDDECL const GUID packet_decoder::property_ogg_packet = { 0xade740be, 0x8e2e, 0x4d0b, { 0xa4, 0x0, 0x3f, 0x6e, 0x8a, 0xf7, 0x71, 0xe4 } };
+
+FOOGUIDDECL const GUID track_property_provider::class_guid = { 0xefcdd365, 0x81fc, 0x4c82, { 0x96, 0x1c, 0xa2, 0xb5, 0x76, 0x1a, 0xf8, 0xb7 } };
+
+FOOGUIDDECL const GUID library_manager_v3::class_guid = { 0x65e34e4d, 0xa9ab, 0x4c02, { 0x9e, 0x8a, 0xe5, 0xf3, 0xb9, 0x55, 0x8c, 0xbe } };
+
+FOOGUIDDECL const GUID core_version_info_v2::class_guid = { 0x273704d7, 0x99ba, 0x4b58, { 0xa0, 0x60, 0x82, 0xab, 0x1, 0xb4, 0x92, 0x25 } }; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/hasher_md5.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/hasher_md5.cpp
new file mode 100644
index 0000000..dc73831
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/hasher_md5.cpp
@@ -0,0 +1,22 @@
+#include "foobar2000.h"
+
+GUID hasher_md5::guid_from_result(const hasher_md5_result & param)
+{
+ assert(sizeof(GUID) == sizeof(hasher_md5_result));
+ GUID temp = * reinterpret_cast<const GUID*>(&param);
+ byte_order::order_le_to_native_t(temp);
+ return temp;
+}
+
+hasher_md5_result hasher_md5::process_single(const void * p_buffer,t_size p_bytes)
+{
+ hasher_md5_state state;
+ initialize(state);
+ process(state,p_buffer,p_bytes);
+ return get_result(state);
+}
+
+GUID hasher_md5::process_single_guid(const void * p_buffer,t_size p_bytes)
+{
+ return guid_from_result(process_single(p_buffer,p_bytes));
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/hasher_md5.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/hasher_md5.h
new file mode 100644
index 0000000..b81a72d
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/hasher_md5.h
@@ -0,0 +1,37 @@
+struct hasher_md5_state {
+ char m_data[128];
+};
+
+struct hasher_md5_result {
+ char m_data[16];
+};
+
+inline bool operator==(const hasher_md5_result & p_item1,const hasher_md5_result & p_item2) {return memcmp(&p_item1,&p_item2,sizeof(hasher_md5_result)) == 0;}
+inline bool operator!=(const hasher_md5_result & p_item1,const hasher_md5_result & p_item2) {return memcmp(&p_item1,&p_item2,sizeof(hasher_md5_result)) != 0;}
+
+namespace pfc {
+ template<> class traits_t<hasher_md5_state> : public traits_rawobject {};
+ template<> class traits_t<hasher_md5_result> : public traits_rawobject {};
+}
+
+class NOVTABLE hasher_md5 : public service_base
+{
+public:
+
+ virtual void initialize(hasher_md5_state & p_state) = 0;
+ virtual void process(hasher_md5_state & p_state,const void * p_buffer,t_size p_bytes) = 0;
+ virtual hasher_md5_result get_result(const hasher_md5_state & p_state) = 0;
+
+
+ static GUID guid_from_result(const hasher_md5_result & param);
+
+ hasher_md5_result process_single(const void * p_buffer,t_size p_bytes);
+ GUID process_single_guid(const void * p_buffer,t_size p_bytes);
+ GUID get_result_guid(const hasher_md5_state & p_state) {return guid_from_result(get_result(p_state));}
+
+
+ //! Helper
+ void process_string(hasher_md5_state & p_state,const char * p_string,t_size p_length = infinite) {return process(p_state,p_string,pfc::strlen_max(p_string,p_length));}
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(hasher_md5);
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/info_lookup_handler.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/info_lookup_handler.h
new file mode 100644
index 0000000..fc68591
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/info_lookup_handler.h
@@ -0,0 +1,24 @@
+//! Service used to access various external (online) track info lookup services, such as freedb, to update file tags with info retrieved from those services.
+class NOVTABLE info_lookup_handler : public service_base {
+public:
+ enum {
+ flag_album_lookup = 1 << 0,
+ flag_track_lookup = 1 << 1,
+ };
+
+ //! Retrieves human-readable name of the lookup handler to display in user interface.
+ virtual void get_name(pfc::string_base & p_out) = 0;
+
+ //! Returns one or more of flag_track_lookup, and flag_album_lookup.
+ virtual t_uint32 get_flags() = 0;
+
+ virtual HICON get_icon(int p_width, int p_height) = 0;
+
+ //! Performs a lookup. Creates a modeless dialog and returns immediately.
+ //! @param p_items Items to look up.
+ //! @param p_notify Callback to notify caller when the operation has completed. Call on_completion with status code 0 to signal failure/abort, or with code 1 to signal success / new infos in metadb.
+ //! @param p_parent Parent window for the lookup dialog. Caller will typically disable the window while lookup is in progress and enable it back when completion is signaled.
+ virtual void lookup(const pfc::list_base_const_t<metadb_handle_ptr> & p_items,completion_notify_ptr p_notify,HWND p_parent) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(info_lookup_handler);
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/initquit.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/initquit.h
new file mode 100644
index 0000000..9984447
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/initquit.h
@@ -0,0 +1,19 @@
+#ifndef _INITQUIT_H_
+#define _INITQUIT_H_
+
+#include "service.h"
+
+//init/quit callback, on_init is called after main window has been created, on_quit is called before main window is destroyed
+class NOVTABLE initquit : public service_base
+{
+public:
+ virtual void on_init() {}
+ virtual void on_quit() {}
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(initquit);
+};
+
+template<typename T>
+class initquit_factory_t : public service_factory_single_t<T> {};
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input.cpp
new file mode 100644
index 0000000..caefae6
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input.cpp
@@ -0,0 +1,245 @@
+#include "foobar2000.h"
+
+
+bool input_entry::g_find_service_by_path(service_ptr_t<input_entry> & p_out,const char * p_path)
+{
+ service_ptr_t<input_entry> ptr;
+ service_enum_t<input_entry> e;
+ pfc::string_extension ext(p_path);
+ while(e.next(ptr))
+ {
+ if (ptr->is_our_path(p_path,ext))
+ {
+ p_out = ptr;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool input_entry::g_find_service_by_content_type(service_ptr_t<input_entry> & p_out,const char * p_content_type)
+{
+ service_ptr_t<input_entry> ptr;
+ service_enum_t<input_entry> e;
+ while(e.next(ptr))
+ {
+ if (ptr->is_our_content_type(p_content_type))
+ {
+ p_out = ptr;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+static void prepare_for_open(service_ptr_t<input_entry> & p_service,service_ptr_t<file> & p_file,const char * p_path,filesystem::t_open_mode p_open_mode,abort_callback & p_abort,bool p_from_redirect)
+{
+ if (p_file.is_empty())
+ {
+ service_ptr_t<filesystem> fs;
+ if (filesystem::g_get_interface(fs,p_path)) {
+ if (fs->supports_content_types()) {
+ fs->open(p_file,p_path,p_open_mode,p_abort);
+ }
+ }
+ }
+
+ if (p_file.is_valid())
+ {
+ pfc::string8 content_type;
+ if (p_file->get_content_type(content_type))
+ {
+ if (input_entry::g_find_service_by_content_type(p_service,content_type))
+ return;
+ }
+ }
+
+ if (input_entry::g_find_service_by_path(p_service,p_path))
+ {
+ if (p_from_redirect && p_service->is_redirect()) throw exception_io_unsupported_format();
+ return;
+ }
+
+ throw exception_io_unsupported_format();
+}
+
+namespace {
+
+ bool g_find_inputs_by_content_type(pfc::list_base_t<service_ptr_t<input_entry> > & p_out,const char * p_content_type,bool p_from_redirect) {
+ service_enum_t<input_entry> e;
+ service_ptr_t<input_entry> ptr;
+ bool ret = false;
+ while(e.next(ptr)) {
+ if (!(p_from_redirect && ptr->is_redirect())) {
+ if (ptr->is_our_content_type(p_content_type)) {p_out.add_item(ptr); ret = true;}
+ }
+ }
+ return ret;
+ }
+
+ bool g_find_inputs_by_path(pfc::list_base_t<service_ptr_t<input_entry> > & p_out,const char * p_path,bool p_from_redirect) {
+ service_enum_t<input_entry> e;
+ service_ptr_t<input_entry> ptr;
+ pfc::string_extension extension(p_path);
+ bool ret = false;
+ while(e.next(ptr)) {
+ if (!(p_from_redirect && ptr->is_redirect())) {
+ if (ptr->is_our_path(p_path,extension)) {p_out.add_item(ptr); ret = true;}
+ }
+ }
+ return ret;
+ }
+
+ template<typename t_service> void g_open_from_list(service_ptr_t<t_service> & p_instance,pfc::list_base_const_t<service_ptr_t<input_entry> > const & p_list,service_ptr_t<file> const & p_filehint,const char * p_path,abort_callback & p_abort) {
+ const t_size count = p_list.get_count();
+ if (count == 1) {
+ p_list[0]->open(p_instance,p_filehint,p_path,p_abort);
+ } else {
+ bool got_bad_data = false, got_bad_data_multi = false;
+ bool done = false;
+ pfc::string8 bad_data_message;
+ for(t_size n=0;n<count && !done;n++) {
+ try {
+ p_list[n]->open(p_instance,p_filehint,p_path,p_abort);
+ done = true;
+ } catch(exception_io_unsupported_format) {
+ //do nothing, skip over
+ } catch(exception_io_data const & e) {
+ if (!got_bad_data) bad_data_message = e.what();
+ else got_bad_data_multi = true;
+ got_bad_data = true;
+ }
+ }
+ if (!done) {
+ if (got_bad_data_multi) throw exception_io_data();
+ else if (got_bad_data) throw exception_io_data(bad_data_message);
+ else throw exception_io_unsupported_format();
+ }
+ }
+ }
+
+ template<typename t_service> bool needs_write_access() {return false;}
+ template<> bool needs_write_access<input_info_writer>() {return true;}
+
+ template<typename t_service> void g_open_t(service_ptr_t<t_service> & p_instance,service_ptr_t<file> const & p_filehint,const char * p_path,abort_callback & p_abort,bool p_from_redirect) {
+ service_ptr_t<file> l_file = p_filehint;
+ if (l_file.is_empty()) {
+ service_ptr_t<filesystem> fs;
+ if (filesystem::g_get_interface(fs,p_path)) {
+ if (fs->supports_content_types()) {
+ fs->open(l_file,p_path,needs_write_access<t_service>() ? filesystem::open_mode_write_existing : filesystem::open_mode_read,p_abort);
+ }
+ }
+ }
+
+ if (l_file.is_valid()) {
+ pfc::string8 content_type;
+ if (l_file->get_content_type(content_type)) {
+ pfc::list_hybrid_t<service_ptr_t<input_entry>,4> list;
+ if (g_find_inputs_by_content_type(list,content_type,p_from_redirect)) {
+ g_open_from_list(p_instance,list,l_file,p_path,p_abort);
+ return;
+ }
+ }
+ }
+
+ {
+ pfc::list_hybrid_t<service_ptr_t<input_entry>,4> list;
+ if (g_find_inputs_by_path(list,p_path,p_from_redirect)) {
+ g_open_from_list(p_instance,list,l_file,p_path,p_abort);
+ return;
+ }
+ }
+
+ throw exception_io_unsupported_format();
+ }
+};
+
+void input_entry::g_open_for_decoding(service_ptr_t<input_decoder> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort,bool p_from_redirect) {
+#if 1
+ g_open_t(p_instance,p_filehint,p_path,p_abort,p_from_redirect);
+#else
+ service_ptr_t<file> filehint = p_filehint;
+ service_ptr_t<input_entry> entry;
+
+ prepare_for_open(entry,filehint,p_path,filesystem::open_mode_read,p_abort,p_from_redirect);
+
+ entry->open_for_decoding(p_instance,filehint,p_path,p_abort);
+#endif
+
+}
+
+void input_entry::g_open_for_info_read(service_ptr_t<input_info_reader> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort,bool p_from_redirect) {
+#if 1
+ g_open_t(p_instance,p_filehint,p_path,p_abort,p_from_redirect);
+#else
+ service_ptr_t<file> filehint = p_filehint;
+ service_ptr_t<input_entry> entry;
+
+ prepare_for_open(entry,filehint,p_path,filesystem::open_mode_read,p_abort,p_from_redirect);
+
+ entry->open_for_info_read(p_instance,filehint,p_path,p_abort);
+#endif
+}
+
+void input_entry::g_open_for_info_write(service_ptr_t<input_info_writer> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort,bool p_from_redirect) {
+#if 1
+ g_open_t(p_instance,p_filehint,p_path,p_abort,p_from_redirect);
+#else
+ service_ptr_t<file> filehint = p_filehint;
+ service_ptr_t<input_entry> entry;
+
+ prepare_for_open(entry,filehint,p_path,filesystem::open_mode_write_existing,p_abort,p_from_redirect);
+
+ entry->open_for_info_write(p_instance,filehint,p_path,p_abort);
+#endif
+}
+
+void input_entry::g_open_for_info_write_timeout(service_ptr_t<input_info_writer> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort,double p_timeout,bool p_from_redirect) {
+ pfc::lores_timer timer;
+ timer.start();
+ for(;;) {
+ try {
+ g_open_for_info_write(p_instance,p_filehint,p_path,p_abort,p_from_redirect);
+ break;
+ } catch(exception_io_sharing_violation) {
+ if (timer.query() > p_timeout) throw;
+ p_abort.sleep(0.01);
+ }
+ }
+}
+
+bool input_entry::g_is_supported_path(const char * p_path)
+{
+ service_ptr_t<input_entry> ptr;
+ service_enum_t<input_entry> e;
+ pfc::string_extension ext(p_path);
+ while(e.next(ptr))
+ {
+ if (ptr->is_our_path(p_path,ext)) return true;
+ }
+ return false;
+}
+
+
+
+void input_open_file_helper(service_ptr_t<file> & p_file,const char * p_path,t_input_open_reason p_reason,abort_callback & p_abort)
+{
+ if (p_file.is_empty()) {
+ switch(p_reason) {
+ default:
+ throw pfc::exception_bug_check();
+ case input_open_info_read:
+ case input_open_decode:
+ filesystem::g_open(p_file,p_path,filesystem::open_mode_read,p_abort);
+ break;
+ case input_open_info_write:
+ filesystem::g_open(p_file,p_path,filesystem::open_mode_write_existing,p_abort);
+ break;
+ }
+ } else {
+ p_file->reopen(p_abort);
+ }
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input.h
new file mode 100644
index 0000000..a0d6f07
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input.h
@@ -0,0 +1,174 @@
+enum {
+ input_flag_no_seeking = 1 << 0,
+ input_flag_no_looping = 1 << 1,
+ input_flag_playback = 1 << 2,
+ input_flag_testing_integrity = 1 << 3,
+ input_flag_allow_inaccurate_seeking = 1 << 4,
+
+ input_flag_simpledecode = input_flag_no_seeking|input_flag_no_looping,
+};
+
+//! Class providing interface for retrieval of information (metadata, duration, replaygain, other tech infos) from files. Also see: file_info. \n
+//! Instantiating: see input_entry.\n
+//! Implementing: see input_impl.
+
+class input_info_reader : public service_base
+{
+public:
+ //! Retrieves count of subsongs in the file. 1 for non-multisubsong-enabled inputs.
+ //! Note: multi-subsong handling is disabled for remote files (see: filesystem::is_remote) for performance reasons. Remote files are always assumed to be single-subsong, with null index.
+ virtual t_uint32 get_subsong_count() = 0;
+
+ //! Retrieves identifier of specified subsong; this identifier is meant to be used in playable_location as well as a parameter for input_info_reader::get_info().
+ //! @param p_index Index of subsong to query. Must be >=0 and < get_subsong_count().
+ virtual t_uint32 get_subsong(t_uint32 p_index) = 0;
+
+ //! Retrieves information about specified subsong.
+ //! @param p_subsong Identifier of the subsong to query. See: input_info_reader::get_subsong(), playable_location.
+ //! @param p_info file_info object to fill. Must be empty on entry.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void get_info(t_uint32 p_subsong,file_info & p_info,abort_callback & p_abort) = 0;
+
+ //! Retrieves file stats. Equivalent to calling get_stats() on file object.
+ virtual t_filestats get_file_stats(abort_callback & p_abort) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(input_info_reader,service_base);
+};
+
+//! Class providing interface for retrieval of PCM audio data from files.\n
+//! Instantiating: see input_entry.\n
+//! Implementing: see input_impl.
+
+class input_decoder : public input_info_reader
+{
+public:
+ //! Prepares to decode specified subsong; resets playback position to the beginning of specified subsong. This must be called first, before any other input_decoder methods (other than those inherited from input_info_reader). \n
+ //! It is legal to set initialize() more than once, with same or different subsong, to play either the same subsong again or another subsong from same file without full reopen.\n
+ //! Warning: this interface inherits from input_info_reader, it is legal to call any input_info_reader methods even during decoding! Call order is not defined, other than initialize() requirement before calling other input_decoder methods.\n
+ //! @param p_subsong Subsong to decode. Should always be 0 for non-multi-subsong-enabled inputs.
+ //! @param p_flags Specifies additional hints for decoding process. It can be null, or a combination of one or more following constants: \n
+ //! input_flag_no_seeking - Indicates that seek() will never be called. Can be used to avoid building potentially expensive seektables when only sequential reading is needed.\n
+ //! input_flag_no_looping - Certain input implementations can be configured to utilize looping info from file formats they process and keep playing single file forever, or keep repeating it specified number of times. This flag indicates that such features should be disabled, for e.g. ReplayGain scan or conversion.\n
+ //! input_flag_playback - Indicates that decoding process will be used for realtime playback rather than conversion. This can be used to reconfigure features that are relevant only for conversion and take a lot of resources, such as very slow secure CDDA reading. \n
+ //! input_flag_testing_integrity - Indicates that we're testing integrity of the file. Any recoverable problems where decoding would normally continue should cause decoder to fail with exception_io_data.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void initialize(t_uint32 p_subsong,unsigned p_flags,abort_callback & p_abort) = 0;
+
+ //! Reads/decodes one chunk of audio data. Use false return value to signal end of file (no more data to return). Before calling run(), decoding must be initialized by initialize() call.
+ //! @param p_chunk audio_chunk object receiving decoded data. Contents are valid only the method returns true.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ //! @returns true on success (new data decoded), false on EOF.
+ virtual bool run(audio_chunk & p_chunk,abort_callback & p_abort) = 0;
+
+ //! Seeks to specified time offset. Before seeking or other decoding calls, decoding must be initialized with initialize() call.
+ //! @param p_seconds Time to seek to, in seconds. If p_seconds exceeds length of the object being decoded, succeed, and then return false from next run() call.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void seek(double p_seconds,abort_callback & p_abort) = 0;
+
+ //! Queries whether resource being read/decoded is seekable. If p_value is set to false, all seek() calls will fail. Before calling can_seek() or other decoding calls, decoding must be initialized with initialize() call.
+ virtual bool can_seek() = 0;
+
+ //! This function is used to signal dynamic VBR bitrate, etc. Called after each run() (or not called at all if caller doesn't care about dynamic info).
+ //! @param p_out Initially contains currently displayed info (either last get_dynamic_info result or current cached info), use this object to return changed info.
+ //! @param p_timestamp_delta Indicates when returned info should be displayed (in seconds, relative to first sample of last decoded chunk), initially set to 0.
+ //! @returns false to keep old info, or true to indicate that changes have been made to p_info and those should be displayed.
+ virtual bool get_dynamic_info(file_info & p_out, double & p_timestamp_delta) = 0;
+
+ //! This function is used to signal dynamic live stream song titles etc. Called after each run() (or not called at all if caller doesn't care about dynamic info). The difference between this and get_dynamic_info() is frequency and relevance of dynamic info changes - get_dynamic_info_track() returns new info only on track change in the stream, returning new titles etc.
+ //! @param p_out Initially contains currently displayed info (either last get_dynamic_info_track result or current cached info), use this object to return changed info.
+ //! @param p_timestamp_delta Indicates when returned info should be displayed (in seconds, relative to first sample of last decoded chunk), initially set to 0.
+ //! @returns false to keep old info, or true to indicate that changes have been made to p_info and those should be displayed.
+ virtual bool get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta) = 0;
+
+ //! Called from playback thread before sleeping.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void on_idle(abort_callback & p_abort) = 0;
+
+
+ FB2K_MAKE_SERVICE_INTERFACE(input_decoder,input_info_reader);
+};
+
+//! Class providing interface for writing metadata and replaygain info to files. Also see: file_info. \n
+//! Instantiating: see input_entry.\n
+//! Implementing: see input_impl.
+
+class input_info_writer : public input_info_reader
+{
+public:
+ //! Tells the service to update file tags with new info for specified subsong.
+ //! @param p_subsong Subsong to update. Should be always 0 for non-multisubsong-enabled inputs.
+ //! @param p_info New info to write. Sometimes not all contents of p_info can be written. Caller will typically read info back after successful write, so e.g. tech infos that change with retag are properly maintained.
+ //! @param p_abort abort_callback object signaling user aborting the operation. WARNING: abort_callback object is provided for consistency; if writing tags actually gets aborted, user will be likely left with corrupted file. Anything calling this should make sure that aborting is either impossible, or gives appropriate warning to the user first.
+ virtual void set_info(t_uint32 p_subsong,const file_info & p_info,abort_callback & p_abort) = 0;
+
+ //! Commits pending updates. In case of multisubsong inputs, set_info should queue the update and perform actual file access in commit(). Otherwise, actual writing can be done in set_info() and then Commit() can just do nothing and always succeed.
+ //! @param p_abort abort_callback object signaling user aborting the operation. WARNING: abort_callback object is provided for consistency; if writing tags actually gets aborted, user will be likely left with corrupted file. Anything calling this should make sure that aborting is either impossible, or gives appropriate warning to the user first.
+ virtual void commit(abort_callback & p_abort) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(input_info_writer,input_info_reader);
+};
+
+class input_entry : public service_base
+{
+public:
+ //! Determines whether specified content type can be handled by this input.
+ //! @param p_type Content type string to test.
+ virtual bool is_our_content_type(const char * p_type)=0;
+
+ //! Determines whether specified file type can be handled by this input. This must not use any kind of file access; the result should be only based on file path / extension.
+ //! @param p_full_path Full URL of file being tested.
+ //! @param p_extension Extension of file being tested, provided by caller for performance reasons.
+ virtual bool is_our_path(const char * p_full_path,const char * p_extension)=0;
+
+ //! Opens specified resource for decoding.
+ //! @param p_instance Receives new input_decoder instance if successful.
+ //! @param p_filehint Optional; passes file object to use for the operation; if set to null, the service will handle opening file by itself. Note that not all inputs operate on physical files that can be reached through filesystem API, some of them require this parameter to be set to null (tone and silence generators for an example).
+ //! @param p_path URL of resource being opened.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void open_for_decoding(service_ptr_t<input_decoder> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort) = 0;
+
+ //! Opens specified file for reading info.
+ //! @param p_instance Receives new input_info_reader instance if successful.
+ //! @param p_filehint Optional; passes file object to use for the operation; if set to null, the service will handle opening file by itself. Note that not all inputs operate on physical files that can be reached through filesystem API, some of them require this parameter to be set to null (tone and silence generators for an example).
+ //! @param p_path URL of resource being opened.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void open_for_info_read(service_ptr_t<input_info_reader> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort) = 0;
+
+ //! Opens specified file for writing info.
+ //! @param p_instance Receives new input_info_writer instance if successful.
+ //! @param p_filehint Optional; passes file object to use for the operation; if set to null, the service will handle opening file by itself. Note that not all inputs operate on physical files that can be reached through filesystem API, some of them require this parameter to be set to null (tone and silence generators for an example).
+ //! @param p_path URL of resource being opened.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void open_for_info_write(service_ptr_t<input_info_writer> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort) = 0;
+
+ //! Reserved for future use. Do nothing and return until specifications are finalized.
+ virtual void get_extended_data(service_ptr_t<file> p_filehint,const playable_location & p_location,const GUID & p_guid,mem_block_container & p_out,abort_callback & p_abort) = 0;
+
+ enum {
+ //! Indicates that this service implements some kind of redirector that opens another input for decoding, used to avoid circular call possibility.
+ flag_redirect = 1,
+ //! Indicates that multi-CPU optimizations should not be used.
+ flag_parallel_reads_slow = 2,
+ };
+ //! See flag_* enums.
+ virtual unsigned get_flags() = 0;
+
+ inline bool is_redirect() {return (get_flags() & flag_redirect) != 0;}
+ inline bool are_parallel_reads_slow() {return (get_flags() & flag_parallel_reads_slow) != 0;}
+
+ static bool g_find_service_by_path(service_ptr_t<input_entry> & p_out,const char * p_path);
+ static bool g_find_service_by_content_type(service_ptr_t<input_entry> & p_out,const char * p_content_type);
+ static void g_open_for_decoding(service_ptr_t<input_decoder> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort,bool p_from_redirect = false);
+ static void g_open_for_info_read(service_ptr_t<input_info_reader> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort,bool p_from_redirect = false);
+ static void g_open_for_info_write(service_ptr_t<input_info_writer> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort,bool p_from_redirect = false);
+ static void g_open_for_info_write_timeout(service_ptr_t<input_info_writer> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort,double p_timeout,bool p_from_redirect = false);
+ static bool g_is_supported_path(const char * p_path);
+
+
+ void open(service_ptr_t<input_decoder> & p_instance,service_ptr_t<file> const & p_filehint,const char * p_path,abort_callback & p_abort) {open_for_decoding(p_instance,p_filehint,p_path,p_abort);}
+ void open(service_ptr_t<input_info_reader> & p_instance,service_ptr_t<file> const & p_filehint,const char * p_path,abort_callback & p_abort) {open_for_info_read(p_instance,p_filehint,p_path,p_abort);}
+ void open(service_ptr_t<input_info_writer> & p_instance,service_ptr_t<file> const & p_filehint,const char * p_path,abort_callback & p_abort) {open_for_info_write(p_instance,p_filehint,p_path,p_abort);}
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(input_entry);
+};
+
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input_file_type.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input_file_type.cpp
new file mode 100644
index 0000000..e01239c
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input_file_type.cpp
@@ -0,0 +1,67 @@
+#include "foobar2000.h"
+
+void input_file_type::build_openfile_mask(pfc::string_base & out, bool b_include_playlists)
+{
+ pfc::string8_fastalloc name,mask,mask_alltypes,out_temp;
+
+ if (b_include_playlists)
+ {
+ service_enum_t<playlist_loader> e;
+ service_ptr_t<playlist_loader> ptr;
+ if (e.first(ptr)) do {
+ if (!mask.is_empty()) mask += ";";
+ mask += "*.";
+ mask += ptr->get_extension();
+ } while(e.next(ptr));
+ out_temp += "Playlists";
+ out_temp += "|";
+ out_temp += mask;
+ out_temp += "|";
+
+ if (!mask_alltypes.is_empty())
+ {
+ if (mask_alltypes[mask_alltypes.length()-1]!=';')
+ mask_alltypes += ";";
+ }
+ mask_alltypes += mask;
+ }
+
+ {
+ service_enum_t<input_file_type> e;
+ service_ptr_t<input_file_type> ptr;
+ if (e.first(ptr)) do {
+ unsigned n,m = ptr->get_count();
+ for(n=0;n<m;n++)
+ {
+ name.reset();
+ mask.reset();
+ if (ptr->get_name(n,name) && ptr->get_mask(n,mask))
+ {
+ if (!strchr(name,'|') && !strchr(mask,'|'))
+ {
+ out_temp += name;
+ out_temp += "|";
+ out_temp += mask;
+ out_temp += "|";
+ if (!mask_alltypes.is_empty())
+ {
+ if (mask_alltypes[mask_alltypes.length()-1]!=';')
+ mask_alltypes += ";";
+ }
+ mask_alltypes += mask;
+ }
+ }
+ }
+ } while(e.next(ptr));
+ }
+ out.reset();
+ out += "All files|*.*|";
+ if (!mask_alltypes.is_empty())
+ {
+ out += "All supported types|";
+ out += mask_alltypes;
+ out += "|";
+ }
+ out += out_temp;
+}
+
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input_file_type.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input_file_type.h
new file mode 100644
index 0000000..c2f5d15
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input_file_type.h
@@ -0,0 +1,42 @@
+class input_file_type : public service_base
+{
+public:
+ virtual unsigned get_count()=0;
+ virtual bool get_name(unsigned idx,pfc::string_base & out)=0;//e.g. "MPEG file"
+ virtual bool get_mask(unsigned idx,pfc::string_base & out)=0;//e.g. "*.MP3;*.MP2"; separate with semicolons
+ virtual bool is_associatable(unsigned idx) = 0;
+
+ static void build_openfile_mask(pfc::string_base & out,bool b_include_playlists=true);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(input_file_type);
+};
+
+class input_file_type_impl : public service_impl_single_t<input_file_type>
+{
+ const char * name, * mask;
+ bool m_associatable;
+public:
+ input_file_type_impl(const char * p_name, const char * p_mask,bool p_associatable) : name(p_name), mask(p_mask), m_associatable(p_associatable) {}
+ unsigned get_count() {return 1;}
+ bool get_name(unsigned idx,pfc::string_base & out) {if (idx==0) {out = name; return true;} else return false;}
+ bool get_mask(unsigned idx,pfc::string_base & out) {if (idx==0) {out = mask; return true;} else return false;}
+ bool is_associatable(unsigned idx) {return m_associatable;}
+};
+
+
+#define DECLARE_FILE_TYPE(NAME,MASK) \
+ namespace { static input_file_type_impl g_filetype_instance(NAME,MASK,true); \
+ static service_factory_single_ref_t<input_file_type_impl> g_filetype_service(g_filetype_instance); }
+
+
+//USAGE: DECLARE_FILE_TYPE("Blah file","*.blah;*.bleh");
+
+class input_file_type_factory : private service_factory_single_transparent_t<input_file_type_impl>
+{
+public:
+ input_file_type_factory(const char * p_name,const char * p_mask,bool p_associatable)
+ : service_factory_single_transparent_t<input_file_type_impl>(p_name,p_mask,p_associatable) {}
+};
+
+
+//usage: static input_file_type_factory mytype("blah type","*.bla;*.meh",true) \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input_impl.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input_impl.h
new file mode 100644
index 0000000..830dd56
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/input_impl.h
@@ -0,0 +1,327 @@
+enum t_input_open_reason {
+ input_open_info_read,
+ input_open_decode,
+ input_open_info_write
+};
+
+//! Helper function for input implementation use; ensures that file is open with relevant access mode. This is typically called from input_impl::open() and such.
+//! @param p_file File object pointer to process. If passed pointer is non-null, the function does nothing and always succeeds; otherwise it attempts to open the file using filesystem API methods.
+//! @param p_path Path to the file.
+//! @param p_reason Type of input operation requested. See: input_impl::open() parameters.
+//! @param p_abort abort_callback object signaling user aborting the operation.
+void input_open_file_helper(service_ptr_t<file> & p_file,const char * p_path,t_input_open_reason p_reason,abort_callback & p_abort);
+
+
+//! This is a class that just declares prototypes of functions that each input needs to implement. See input_decoder / input_info_reader / input_info_writer interfaces for full descriptions of member functions. Since input implementation class is instantiated using a template, you don't need to derive from input_impl as virtual functions are not used on implementation class level. Use input_factory_t template to register input class based on input_impl.
+class input_impl
+{
+public:
+ //! Opens specified file for info read / decoding / info write. This is called only once, immediately after object creation, before any other methods, and no other methods are called if open() fails.
+ //! @param p_filehint Optional; passes file object to use for the operation; if set to null, the implementation should handle opening file by itself. Note that not all inputs operate on physical files that can be reached through filesystem API, some of them require this parameter to be set to null (tone and silence generators for an example). Typically, an input implementation that requires file access calls input_open_file_helper() function to ensure that file is open with relevant access mode (read or read/write).
+ //! @param p_path URL of resource being opened.
+ //! @param p_reason Type of operation requested. Possible values are: \n
+ //! - input_open_info_read - info retrieval methods are valid; \n
+ //! - input_open_decode - info retrieval and decoding methods are valid; \n
+ //! - input_open_info_write - info retrieval and retagging methods are valid; \n
+ //! Note that info retrieval methods are valid in all cases, and they may be called at any point of decoding/retagging process. Results of info retrieval methods (other than get_subsong_count() / get_subsong()) between retag_set_info() and retag_commit() are undefined however; those should not be called during that period.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ void open(service_ptr_t<file> p_filehint,const char * p_path,t_input_open_reason p_reason,abort_callback & p_abort);
+
+ //! See: input_info_reader::get_subsong_count(). Valid after open() with any reason.
+ unsigned get_subsong_count();
+ //! See: input_info_reader::get_subsong(). Valid after open() with any reason.
+ t_uint32 get_subsong(unsigned p_index);
+ //! See: input_info_reader::get_info(). Valid after open() with any reason.
+ void get_info(t_uint32 p_subsong,file_info & p_info,abort_callback & p_abort);
+ //! See: input_info_reader::get_file_stats(). Valid after open() with any reason.
+ t_filestats get_file_stats(abort_callback & p_abort);
+
+ //! See: input_decoder::initialize(). Valid after open() with input_open_decode reason.
+ void decode_initialize(t_uint32 p_subsong,unsigned p_flags,abort_callback & p_abort);
+ //! See: input_decoder::run(). Valid after decode_initialize().
+ bool decode_run(audio_chunk & p_chunk,abort_callback & p_abort);
+ //! See: input_decoder::seek(). Valid after decode_initialize().
+ void decode_seek(double p_seconds,abort_callback & p_abort);
+ //! See: input_decoder::can_seek(). Valid after decode_initialize().
+ bool decode_can_seek();
+ //! See: input_decoder::get_dynamic_info(). Valid after decode_initialize().
+ bool decode_get_dynamic_info(file_info & p_out, double & p_timestamp_delta);
+ //! See: input_decoder::get_dynamic_info_track(). Valid after decode_initialize().
+ bool decode_get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta);
+ //! See: input_decoder::on_idle(). Valid after decode_initialize().
+ void decode_on_idle(abort_callback & p_abort);
+
+ //! See: input_info_writer::set_info(). Valid after open() with input_open_info_write reason.
+ void retag_set_info(t_uint32 p_subsong,const file_info & p_info,abort_callback & p_abort);
+ //! See: input_info_writer::commit(). Valid after open() with input_open_info_write reason.
+ void retag_commit(abort_callback & p_abort);
+
+ //! See: input_entry::is_our_content_type().
+ static bool g_is_our_content_type(const char * p_content_type);
+ //! See: input_entry::is_our_path().
+ static bool g_is_our_path(const char * p_path,const char * p_extension);
+
+protected:
+ input_impl() {}
+ ~input_impl() {}
+};
+
+//! This is a class that just declares prototypes of functions that each non-multitrack-enabled input needs to implement. See input_decoder / input_info_reader / input_info_writer interfaces for full descriptions of member functions. Since input implementation class is instantiated using a template, you don't need to derive from input_singletrack_impl as virtual functions are not used on implementation class level. Use input_singletrack_factory_t template to register input class based on input_singletrack_impl.
+class input_singletrack_impl
+{
+public:
+ //! Opens specified file for info read / decoding / info write. This is called only once, immediately after object creation, before any other methods, and no other methods are called if open() fails.
+ //! @param p_filehint Optional; passes file object to use for the operation; if set to null, the implementation should handle opening file by itself. Note that not all inputs operate on physical files that can be reached through filesystem API, some of them require this parameter to be set to null (tone and silence generators for an example). Typically, an input implementation that requires file access calls input_open_file_helper() function to ensure that file is open with relevant access mode (read or read/write).
+ //! @param p_path URL of resource being opened.
+ //! @param p_reason Type of operation requested. Possible values are: \n
+ //! - input_open_info_read - info retrieval methods are valid; \n
+ //! - input_open_decode - info retrieval and decoding methods are valid; \n
+ //! - input_open_info_write - info retrieval and retagging methods are valid; \n
+ //! Note that info retrieval methods are valid in all cases, and they may be called at any point of decoding/retagging process. Results of info retrieval methods (other than get_subsong_count() / get_subsong()) between retag_set_info() and retag_commit() are undefined however; those should not be called during that period.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ void open(service_ptr_t<file> p_filehint,const char * p_path,t_input_open_reason p_reason,abort_callback & p_abort);
+
+ //! See: input_info_reader::get_info(). Valid after open() with any reason. \n
+ //! Implementation warning: this is typically also called immediately after tag update and should return newly written content then.
+ void get_info(file_info & p_info,abort_callback & p_abort);
+ //! See: input_info_reader::get_file_stats(). Valid after open() with any reason. \n
+ //! Implementation warning: this is typically also called immediately after tag update and should return new values then.
+ t_filestats get_file_stats(abort_callback & p_abort);
+
+ //! See: input_decoder::initialize(). Valid after open() with input_open_decode reason.
+ void decode_initialize(unsigned p_flags,abort_callback & p_abort);
+ //! See: input_decoder::run(). Valid after decode_initialize().
+ bool decode_run(audio_chunk & p_chunk,abort_callback & p_abort);
+ //! See: input_decoder::seek(). Valid after decode_initialize().
+ void decode_seek(double p_seconds,abort_callback & p_abort);
+ //! See: input_decoder::can_seek(). Valid after decode_initialize().
+ bool decode_can_seek();
+ //! See: input_decoder::get_dynamic_info(). Valid after decode_initialize().
+ bool decode_get_dynamic_info(file_info & p_out, double & p_timestamp_delta);
+ //! See: input_decoder::get_dynamic_info_track(). Valid after decode_initialize().
+ bool decode_get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta);
+ //! See: input_decoder::on_idle(). Valid after decode_initialize().
+ void decode_on_idle(abort_callback & p_abort);
+
+ //! See: input_info_writer::set_info(). Note that input_info_writer::commit() call isn't forwarded because it's useless in case of non-multitrack-enabled inputs. Valid after open() with input_open_info_write reason.
+ void retag(const file_info & p_info,abort_callback & p_abort);
+
+ //! See: input_entry::is_our_content_type().
+ static bool g_is_our_content_type(const char * p_content_type);
+ //! See: input_entry::is_our_path().
+ static bool g_is_our_path(const char * p_path,const char * p_extension);
+
+protected:
+ input_singletrack_impl() {}
+ ~input_singletrack_impl() {}
+};
+
+
+//! Misc helper, documentme.
+class input_singletrack_file_impl
+{
+public:
+ void open(service_ptr_t<file> p_file,t_input_open_reason p_reason,abort_callback & p_abort);
+
+ void get_info(file_info & p_info,abort_callback & p_abort);
+ t_filestats get_file_stats(abort_callback & p_abort);
+
+ void decode_initialize(unsigned p_flags,abort_callback & p_abort);
+ bool decode_run(audio_chunk & p_chunk,abort_callback & p_abort);
+ void decode_seek(double p_seconds,abort_callback & p_abort);
+ bool decode_can_seek();
+ bool decode_get_dynamic_info(file_info & p_out, double & p_timestamp_delta);
+ bool decode_get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta);
+ void decode_on_idle(abort_callback & p_abort);
+
+ void retag(file_info & p_info,abort_callback & p_abort);
+
+ static bool g_is_our_content_type(const char * p_content_type);
+ static bool g_is_our_path(const char * p_path,const char * p_extension);
+
+protected:
+ input_singletrack_file_impl() {}
+ ~input_singletrack_file_impl() {}
+};
+
+//! Used internally by standard input_entry implementation; do not use directly. Translates input_decoder / input_info_reader / input_info_writer calls to input_impl calls.
+template<class I, class t_base>
+class input_impl_interface_wrapper_t : public t_base
+{
+public:
+ void open(service_ptr_t<file> p_filehint,const char * p_path,t_input_open_reason p_reason,abort_callback & p_abort) {
+ m_instance.open(p_filehint,p_path,p_reason,p_abort);
+ }
+
+ // input_info_reader methods
+
+ t_uint32 get_subsong_count() {
+ return m_instance.get_subsong_count();
+ }
+
+ t_uint32 get_subsong(t_uint32 p_index) {
+ return m_instance.get_subsong(p_index);
+ }
+
+
+ void get_info(t_uint32 p_subsong,file_info & p_info,abort_callback & p_abort) {
+ m_instance.get_info(p_subsong,p_info,p_abort);
+ }
+
+ t_filestats get_file_stats(abort_callback & p_abort) {
+ return m_instance.get_file_stats(p_abort);
+ }
+
+ // input_decoder methods
+
+ void initialize(t_uint32 p_subsong,unsigned p_flags,abort_callback & p_abort) {
+ m_instance.decode_initialize(p_subsong,p_flags,p_abort);
+ }
+
+ bool run(audio_chunk & p_chunk,abort_callback & p_abort) {
+ return m_instance.decode_run(p_chunk,p_abort);
+ }
+
+ void seek(double p_seconds,abort_callback & p_abort) {
+ m_instance.decode_seek(p_seconds,p_abort);
+ }
+
+ bool can_seek() {
+ return m_instance.decode_can_seek();
+ }
+
+ bool get_dynamic_info(file_info & p_out, double & p_timestamp_delta) {
+ return m_instance.decode_get_dynamic_info(p_out,p_timestamp_delta);
+ }
+
+ bool get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta) {
+ return m_instance.decode_get_dynamic_info_track(p_out,p_timestamp_delta);
+ }
+
+ void on_idle(abort_callback & p_abort) {
+ m_instance.decode_on_idle(p_abort);
+ }
+
+ // input_info_writer methods
+
+ void set_info(t_uint32 p_subsong,const file_info & p_info,abort_callback & p_abort) {
+ m_instance.retag_set_info(p_subsong,p_info,p_abort);
+ }
+
+ void commit(abort_callback & p_abort) {
+ m_instance.retag_commit(p_abort);
+ }
+
+private:
+ I m_instance;
+};
+
+//! Helper used by input_singletrack_factory_t, do not use directly. Translates input_impl calls to input_singletrack_impl calls.
+template<class I>
+class input_wrapper_singletrack_t
+{
+public:
+ input_wrapper_singletrack_t() {}
+
+ void open(service_ptr_t<file> p_filehint,const char * p_path,t_input_open_reason p_reason,abort_callback & p_abort) {
+ m_instance.open(p_filehint,p_path,p_reason,p_abort);
+ }
+
+ void get_info(t_uint32 p_subsong,file_info & p_info,abort_callback & p_abort) {
+ if (p_subsong != 0) throw exception_io_data();
+ m_instance.get_info(p_info,p_abort);
+ }
+
+ t_uint32 get_subsong_count() {
+ return 1;
+ }
+
+ t_uint32 get_subsong(t_uint32 p_index) {
+ assert(p_index == 0);
+ return 0;
+ }
+
+ t_filestats get_file_stats(abort_callback & p_abort) {
+ return m_instance.get_file_stats(p_abort);
+ }
+
+ void decode_initialize(t_uint32 p_subsong,unsigned p_flags,abort_callback & p_abort) {
+ if (p_subsong != 0) throw exception_io_data();
+ m_instance.decode_initialize(p_flags,p_abort);
+ }
+
+ bool decode_run(audio_chunk & p_chunk,abort_callback & p_abort) {return m_instance.decode_run(p_chunk,p_abort);}
+ void decode_seek(double p_seconds,abort_callback & p_abort) {m_instance.decode_seek(p_seconds,p_abort);}
+ bool decode_can_seek() {return m_instance.decode_can_seek();}
+ bool decode_get_dynamic_info(file_info & p_out, double & p_timestamp_delta) {return m_instance.decode_get_dynamic_info(p_out,p_timestamp_delta);}
+ bool decode_get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta) {return m_instance.decode_get_dynamic_info_track(p_out,p_timestamp_delta);}
+ void decode_on_idle(abort_callback & p_abort) {m_instance.decode_on_idle(p_abort);}
+
+ void retag_set_info(t_uint32 p_subsong,const file_info & p_info,abort_callback & p_abort) {
+ if (p_subsong != 0) throw exception_io_data();
+ m_instance.retag(p_info,p_abort);
+ }
+
+ void retag_commit(abort_callback & p_abort) {}
+
+ static bool g_is_our_content_type(const char * p_content_type) {return I::g_is_our_content_type(p_content_type);}
+ static bool g_is_our_path(const char * p_path,const char * p_extension) {return I::g_is_our_path(p_path,p_extension);}
+
+
+private:
+ I m_instance;
+};
+
+//! Helper; standard input_entry implementation. Do not instantiate this directly, use input_factory_t or one of other input_*_factory_t helpers instead.
+template<class I,unsigned t_flags>
+class input_entry_impl_t : public input_entry
+{
+private:
+
+ template<class T>
+ void instantiate_t(service_ptr_t<T> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,t_input_open_reason p_reason,abort_callback & p_abort)
+ {
+ service_ptr_t< service_impl_t<input_impl_interface_wrapper_t<I,T> > > temp;
+ temp = new service_impl_t<input_impl_interface_wrapper_t<I,T> >();
+ temp->open(p_filehint,p_path,p_reason,p_abort);
+ p_instance = temp.get_ptr();
+ }
+public:
+ bool is_our_content_type(const char * p_type) {return I::g_is_our_content_type(p_type);}
+ bool is_our_path(const char * p_full_path,const char * p_extension) {return I::g_is_our_path(p_full_path,p_extension);}
+
+ void open_for_decoding(service_ptr_t<input_decoder> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort) {
+ instantiate_t(p_instance,p_filehint,p_path,input_open_decode,p_abort);
+ }
+
+ void open_for_info_read(service_ptr_t<input_info_reader> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort) {
+ instantiate_t(p_instance,p_filehint,p_path,input_open_info_read,p_abort);
+ }
+
+ void open_for_info_write(service_ptr_t<input_info_writer> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort) {
+ instantiate_t(p_instance,p_filehint,p_path,input_open_info_write,p_abort);
+ }
+
+ void get_extended_data(service_ptr_t<file> p_filehint,const playable_location & p_location,const GUID & p_guid,mem_block_container & p_out,abort_callback & p_abort) {
+ p_out.reset();
+ }
+
+ unsigned get_flags() {return t_flags;}
+};
+
+
+//! Stardard input factory. For reference of functions that must be supported by registered class, see input_impl.\n Usage: static input_factory_t<myinputclass> g_myinputclass_factory;\n Note that input classes can't be registered through service_factory_t template directly.
+template<class T>
+class input_factory_t : public service_factory_single_t<input_entry_impl_t<T,0> > {};
+
+//! Non-multitrack-enabled input factory (helper) - hides multitrack management functions from input implementation; use this for inputs that handle file types where each physical file can contain only one user-visible playable track. For reference of functions that must be supported by registered class, see input_singletrack_impl.\n Usage: static input_singletrack_factory_t<myinputclass> g_myinputclass_factory;\n Note that input classes can't be registered through service_factory_t template directly.template<class T>
+template<class T>
+class input_singletrack_factory_t : public service_factory_single_t<input_entry_impl_t<input_wrapper_singletrack_t<T>,0> > {};
+
+//! Extended version of input_factory_t, with non-default flags. See: input_factory_t, input_entry::get_flags().
+template<class T,unsigned t_flags>
+class input_factory_ex_t : public service_factory_single_t<input_entry_impl_t<T,t_flags> > {};
+
+//! Extended version of input_singletrack_factory_t, with non-default flags. See: input_singletrack_factory_t, input_entry::get_flags().
+template<class T,unsigned t_flags>
+class input_singletrack_factory_ex_t : public service_factory_single_t<input_entry_impl_t<input_wrapper_singletrack_t<T>,t_flags> > {};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/library_manager.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/library_manager.h
new file mode 100644
index 0000000..4dc0529
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/library_manager.h
@@ -0,0 +1,133 @@
+#ifndef _foobar2000_sdk_library_manager_h_
+#define _foobar2000_sdk_library_manager_h_
+
+/*!
+This service implements methods allowing you to interact with the Media Library.\n
+All methods are valid from main thread only.\n
+To avoid race conditions, methods that alter library contents should not be called from inside global callbacks.\n
+Usage: Use static_api_ptr_t<library_manager> to instantiate.
+*/
+
+class NOVTABLE library_manager : public service_base {
+public:
+ //! Interface for use with library_manager::enum_items().
+ class NOVTABLE enum_callback {
+ public:
+ //! Return true to continue enumeration, false to abort.
+ virtual bool on_item(const metadb_handle_ptr & p_item) = 0;
+ };
+
+ //! Returns whether specified item is in the Media Library or not.
+ virtual bool is_item_in_library(const metadb_handle_ptr & p_item) = 0;
+ //! Returns whether current user settings allow specified item to be added to the Media Library or not.
+ virtual bool is_item_addable(const metadb_handle_ptr & p_item) = 0;
+ //! Returns whether current user settings allow specified item path to be added to the Media Library or not.
+ virtual bool is_path_addable(const char * p_path) = 0;
+ //! Retrieves path of specified item relative to Media Library directory it is in. Returns true on success, false when the item is not in the Media Library.
+ virtual bool get_relative_path(const metadb_handle_ptr & p_item,pfc::string_base & p_out) = 0;
+ //! Calls callback method for every item in the Media Library. Note that order of items in Media Library is undefined.
+ virtual void enum_items(enum_callback & p_callback) = 0;
+ //! Adds specified items to the Media Library (items actually added will be filtered according to user settings).
+ virtual void add_items(const pfc::list_base_const_t<metadb_handle_ptr> & p_data) = 0;
+ //! Removes specified items from the Media Library (does nothing if specific item is not in the Media Library).
+ virtual void remove_items(const pfc::list_base_const_t<metadb_handle_ptr> & p_data) = 0;
+ //! Adds specified items to the Media Library (items actually added will be filtered according to user settings). The difference between this and add_items() is that items are not added immediately; the operation is queued and executed later, so it is safe to call from e.g. global callbacks.
+ virtual void add_items_async(const pfc::list_base_const_t<metadb_handle_ptr> & p_data) = 0;
+
+ //! For internal use only; p_data must be sorted by metadb::path_compare; use file_operation_callback static methods instead of calling this directly.
+ virtual void on_files_deleted_sorted(const pfc::list_base_const_t<const char *> & p_data) = 0;
+
+ //! Retrieves entire Media Library content.
+ virtual void get_all_items(pfc::list_base_t<metadb_handle_ptr> & p_out) = 0;
+
+ //! Returns whether Media Library functionality is enabled or not, for e.g. notifying user to change settings when trying to use a Media Library viewer without having configured Media Library first.
+ virtual bool is_library_enabled() = 0;
+ //! Pops up Media Library preferences page.
+ virtual void show_preferences() = 0;
+
+ //! Deprecated; use library_manager_v2::rescan_async() when possible.\n
+ //! Rescans user-specified Media Library directories for new files and removes references to files that no longer exist from the Media Library.\n
+ //! Note that this function creates modal dialog and does not return until the operation has completed.\n
+ virtual void rescan() = 0;
+
+ //! Deprecated; use library_manager_v2::check_dead_entries_async() when possible.\n
+ //! Hints Media Library about possible dead items, typically used for "remove dead entries" context action in ML viewers. The implementation will verify whether the items are actually dead before ML contents are altered.\n
+ //! Note that this function creates modal dialog and does not return until the operation has completed.\n
+ virtual void check_dead_entries(const pfc::list_base_t<metadb_handle_ptr> & p_list) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(library_manager);
+};
+
+//! New in 0.9.3
+class NOVTABLE library_manager_v2 : public library_manager {
+public:
+ //! Returns whether a rescan process is currently running.
+ virtual bool is_rescan_running() = 0;
+
+ //! Starts an async rescan process. Note that if another process is already running, the process is silently aborted.
+ //! @param p_parent Parent window for displayed progress dialog.
+ //! @param p_notify Allows caller to receive notifications about the process finishing. Status code: 1 on success, 0 on user abort. Pass NULL if caller doesn't care.
+ virtual void rescan_async(HWND p_parent,completion_notify_ptr p_notify) = 0;
+
+ //! Hints Media Library about possible dead items, typically used for "remove dead entries" context action in ML viewers. The implementation will verify whether the items are actually dead before ML contents are altered.\n
+ //! @param p_list List of items to process.
+ //! @param p_parent Parent window for displayed progress dialog.
+ //! @param p_notify Allows caller to receive notifications about the process finishing. Status code: 1 on success, 0 on user abort. Pass NULL if caller doesn't care.
+ virtual void check_dead_entries_async(const pfc::list_base_t<metadb_handle_ptr> & p_list,HWND p_parent,completion_notify_ptr p_notify) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(library_manager_v2,library_manager);
+};
+
+//! New in 0.9.4
+class NOVTABLE library_manager_v3 : public library_manager_v2 {
+public:
+ //! Retrieves directory path and subdirectory/filename formatting scheme for newly encoded/copied/moved tracks.
+ //! @returns True on success, false when the feature has not been configured.
+ virtual bool get_new_file_pattern_tracks(pfc::string_base & p_directory,pfc::string_base & p_format) = 0;
+ //! Retrieves directory path and subdirectory/filename formatting scheme for newly encoded/copied/moved full album images.
+ //! @returns True on success, false when the feature has not been configured.
+ virtual bool get_new_file_pattern_images(pfc::string_base & p_directory,pfc::string_base & p_format) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(library_manager_v3,library_manager_v2);
+};
+
+//! Callback service receiving notifications about Media Library content changes. Methods called only from main thread.\n
+//! Use library_callback_factory_t template to register.
+class NOVTABLE library_callback : public service_base {
+public:
+ //! Called when new items are added to the Media Library.
+ virtual void on_items_added(const pfc::list_base_const_t<metadb_handle_ptr> & p_data) = 0;
+ //! Called when some items have been removed from the Media Library.
+ virtual void on_items_removed(const pfc::list_base_const_t<metadb_handle_ptr> & p_data) = 0;
+ //! Called when some items in the Media Library have been modified.
+ virtual void on_items_modified(const pfc::list_base_const_t<metadb_handle_ptr> & p_data) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(library_callback);
+};
+
+template<typename T>
+class library_callback_factory_t : public service_factory_single_t<T> {};
+
+//! Implement this service to appear on "library viewers" list in Media Library preferences page.\n
+//! Use library_viewer_factory_t to register.
+class NOVTABLE library_viewer : public service_base {
+public:
+ //! Retrieves GUID of your preferences page (pfc::guid_null if you don't have one).
+ virtual GUID get_preferences_page() = 0;
+ //! Queries whether "activate" action is supported (relevant button will be disabled if it's not).
+ virtual bool have_activate() = 0;
+ //! Activates your Media Library viewer component (e.g. shows its window).
+ virtual void activate() = 0;
+ //! Retrieves GUID of your library_viewer implementation, for internal identification. Note that this not the same as preferences page GUID.
+ virtual GUID get_guid() = 0;
+ //! Retrieves name of your Media Library viewer, a null-terminated UTF-8 encoded string.
+ virtual const char * get_name() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(library_viewer);
+};
+
+template<typename T>
+class library_viewer_factory_t : public service_factory_single_t<T> {};
+
+
+#endif _foobar2000_sdk_library_manager_h_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/link_resolver.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/link_resolver.cpp
new file mode 100644
index 0000000..26c6c3e
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/link_resolver.cpp
@@ -0,0 +1,17 @@
+#include "foobar2000.h"
+
+bool link_resolver::g_find(service_ptr_t<link_resolver> & p_out,const char * p_path)
+{
+ service_enum_t<link_resolver> e;
+ service_ptr_t<link_resolver> ptr;
+ pfc::string_extension ext(p_path);
+ while(e.next(ptr))
+ {
+ if (ptr->is_our_path(p_path,ext))
+ {
+ p_out = ptr;
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/link_resolver.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/link_resolver.h
new file mode 100644
index 0000000..ca92aaa
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/link_resolver.h
@@ -0,0 +1,33 @@
+#ifndef _foobar2000_sdk_link_resolver_h_
+#define _foobar2000_sdk_link_resolver_h_
+
+//! Interface for resolving different sorts of link files.
+//! Utilized by mechanisms that convert filesystem path into list of playable locations.
+//! For security reasons, link may only point to playable object path, not to a playlist or another link.
+
+class NOVTABLE link_resolver : public service_base
+{
+public:
+
+ //! Tests whether specified file is supported by this link_resolver service.
+ //! @param p_path Path of file being queried.
+ //! @param p_extension Extension of file being queried. This is provided for performance reasons, path already includes it.
+ virtual bool is_our_path(const char * p_path,const char * p_extension) = 0;
+
+ //! Resolves a link file. Before this is called, path must be accepted by is_our_path().
+ //! @param p_filehint Optional file interface to use. If null/empty, implementation should open file by itself.
+ //! @param p_path Path of link file to resolve.
+ //! @param p_out Receives path the link is pointing to.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void resolve(service_ptr_t<file> p_filehint,const char * p_path,pfc::string_base & p_out,abort_callback & p_abort) = 0;
+
+ //! Helper function; finds link_resolver interface that supports specified link file.
+ //! @param p_out Receives link_resolver interface on success.
+ //! @param p_path Path of file to query.
+ //! @returns True on success, false on failure (no interface that supports specified path could be found).
+ static bool g_find(service_ptr_t<link_resolver> & p_out,const char * p_path);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(link_resolver);
+};
+
+#endif //_foobar2000_sdk_link_resolver_h_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/main_thread_callback.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/main_thread_callback.h
new file mode 100644
index 0000000..467efdd
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/main_thread_callback.h
@@ -0,0 +1,20 @@
+//! Callback object class for main_thread_callback_manager service.
+class NOVTABLE main_thread_callback : public service_base {
+public:
+ //! Gets called from main app thread. See main_thread_callback_manager description for more info.
+ virtual void callback_run() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(main_thread_callback,service_base);
+};
+
+/*!
+Allows you to queue a callback object to be called from main app thread. This is commonly used to trigger main-thread-only API calls from worker threads.\n
+This can be also used from main app thread, to avoid race conditions when trying to use APIs that dispatch global callbacks from inside some other global callback, or using message loops / modal dialogs inside global callbacks.
+*/
+class NOVTABLE main_thread_callback_manager : public service_base {
+public:
+ //! Queues a callback object. This can be called from any thread, implementation ensures multithread safety. Implementation will call p_callback->callback_run() once later. To get it called repeatedly, you would need to add your callback again.
+ virtual void add_callback(service_ptr_t<main_thread_callback> p_callback) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(main_thread_callback_manager);
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/mainmenu.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/mainmenu.cpp
new file mode 100644
index 0000000..454b292
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/mainmenu.cpp
@@ -0,0 +1,34 @@
+#include "foobar2000.h"
+
+bool mainmenu_commands::g_execute(const GUID & p_guid,service_ptr_t<service_base> p_callback) {
+ service_enum_t<mainmenu_commands> e;
+ service_ptr_t<mainmenu_commands> ptr;
+ while(e.next(ptr)) {
+ const t_uint32 count = ptr->get_command_count();
+ for(t_uint32 n=0;n<count;n++) {
+ if (ptr->get_command(n) == p_guid) {
+ ptr->execute(n,p_callback);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool mainmenu_commands::g_find_by_name(const char * p_name,GUID & p_guid) {
+ service_enum_t<mainmenu_commands> e;
+ service_ptr_t<mainmenu_commands> ptr;
+ pfc::string8_fastalloc temp;
+ while(e.next(ptr)) {
+ const t_uint32 count = ptr->get_command_count();
+ for(t_uint32 n=0;n<count;n++) {
+ ptr->get_name(n,temp);
+ if (stricmp_utf8(temp,p_name) == 0) {
+ p_guid = ptr->get_command(n);
+ return true;
+ }
+ }
+ }
+ return false;
+
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/masstagger_action.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/masstagger_action.h
new file mode 100644
index 0000000..ed774aa
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/masstagger_action.h
@@ -0,0 +1,71 @@
+#ifndef _FOOBAR2000_MASSTAG_ACTION_H_
+#define _FOOBAR2000_MASSTAG_ACTION_H_
+
+class NOVTABLE masstagger_action : public service_base
+{
+public:
+ /**
+ * Get name to display on list of available actions.
+ * \param p_out store name in here
+ */
+ virtual void get_name(pfc::string_base & p_out)=0;
+
+ /**
+ * Initialize and show configuration with default values, if appropriate.
+ * \param p_parent handle to parent window
+ * \returns true iff succesful
+ */
+ virtual bool initialize(HWND p_parent) = 0;
+
+ /**
+ * Initialize and get configuration from parameter.
+ * \param p_data a zero-terminated string containing previously stored configuration data.
+ * \returns true iff succesful
+ */
+ virtual bool initialize_fromconfig(const char * p_data)=0;
+
+ /**
+ * Show configuration with current values.
+ * \param parent handle to parent window
+ * \returns true if display string needs to be updated.
+ */
+ virtual bool configure(HWND p_parent) = 0;
+
+ /**
+ * Get name to display on list of configured actions.
+ * You should include value of settings, if possible.
+ * \param p_name store name in here
+ */
+ virtual void get_display_string(pfc::string_base & p_name) = 0;
+
+ /**
+ * Get current settings as zero-terminated string.
+ * \param p_data store settings in here
+ */
+ virtual void get_config(pfc::string_base & p_data) = 0;
+
+ /**
+ * Apply action on file info.
+ * \param p_location location of current item
+ * \param p_info file info of current item, contains modifications from previous actions
+ * \param p_index zero-based index of current item in list of processed items
+ * \param p_count number of processed items
+ */
+ virtual void run(const playable_location & p_location, file_info * p_info, t_size p_index, t_size p_count) = 0;
+
+ /**
+ * Get GUID.
+ * Used for identification when storing scripts.
+ * \returns your GUID
+ */
+ virtual const GUID & get_guid()=0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(masstagger_action);
+};
+
+DECLARE_CLASS_GUID(masstagger_action,0x49da1f6c, 0x6744, 0x47f3, 0xbf, 0x93, 0x67, 0x1c, 0x37, 0x79, 0xff, 0xcd);
+
+template<typename T>
+class masstagger_action_factory_t : public service_factory_t<T> {};
+
+#endif //_FOOBAR2000_MASSTAG_ACTION_H_
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/mem_block_container.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/mem_block_container.cpp
new file mode 100644
index 0000000..a1961b9
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/mem_block_container.cpp
@@ -0,0 +1,12 @@
+#include "foobar2000.h"
+
+void mem_block_container::from_stream(stream_reader * p_stream,t_size p_bytes,abort_callback & p_abort) {
+ if (p_bytes == 0) {set_size(0);}
+ set_size(p_bytes);
+ p_stream->read_object(get_ptr(),p_bytes,p_abort);
+}
+
+void mem_block_container::set(const void * p_buffer,t_size p_size) {
+ set_size(p_size);
+ memcpy(get_ptr(),p_buffer,p_size);
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/mem_block_container.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/mem_block_container.h
new file mode 100644
index 0000000..8960ed1
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/mem_block_container.h
@@ -0,0 +1,49 @@
+//! Generic interface for a memory block; used by various other interfaces to return memory blocks while allowing caller to allocate.
+class NOVTABLE mem_block_container {
+public:
+ virtual const void * get_ptr() const = 0;
+ virtual void * get_ptr() = 0;
+ virtual t_size get_size() const = 0;
+ virtual void set_size(t_size p_size) = 0;
+
+ void from_stream(stream_reader * p_stream,t_size p_bytes,abort_callback & p_abort);
+
+ void set(const void * p_buffer,t_size p_size);
+
+ inline void copy(const mem_block_container & p_source) {set(p_source.get_ptr(),p_source.get_size());}
+ inline void reset() {set_size(0);}
+
+ const mem_block_container & operator=(const mem_block_container & p_source) {copy(p_source);return *this;}
+
+protected:
+ mem_block_container() {}
+ ~mem_block_container() {}
+};
+
+//! mem_block_container implementation.
+template<template<typename> class t_alloc = pfc::alloc_standard>
+class mem_block_container_impl_t : public mem_block_container {
+public:
+ const void * get_ptr() const {return m_data.get_ptr();}
+ void * get_ptr() {return m_data.get_ptr();}
+ t_size get_size() const {return m_data.get_size();}
+ void set_size(t_size p_size) {
+ m_data.set_size(p_size);
+ }
+private:
+ pfc::array_t<t_uint8,t_alloc> m_data;
+};
+
+typedef mem_block_container_impl_t<> mem_block_container_impl;
+
+class mem_block_container_temp_impl : public mem_block_container {
+public:
+ mem_block_container_temp_impl(void * p_buffer,t_size p_size) : m_buffer(p_buffer), m_buffer_size(p_size), m_size(0) {}
+ const void * get_ptr() const {return m_buffer;}
+ void * get_ptr() {return m_buffer;}
+ t_size get_size() const {return m_size;}
+ void set_size(t_size p_size) {if (p_size > m_buffer_size) throw pfc::exception_overflow(); m_size = p_size;}
+private:
+ t_size m_size,m_buffer_size;
+ void * m_buffer;
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu.h
new file mode 100644
index 0000000..61190ee
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu.h
@@ -0,0 +1,127 @@
+class NOVTABLE mainmenu_group : public service_base {
+public:
+ virtual GUID get_guid() = 0;
+ virtual GUID get_parent() = 0;
+ virtual t_uint32 get_sort_priority() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(mainmenu_group);
+};
+
+class NOVTABLE mainmenu_group_popup : public mainmenu_group {
+public:
+ virtual void get_display_string(pfc::string_base & p_out) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(mainmenu_group_popup,mainmenu_group);
+};
+
+class NOVTABLE mainmenu_commands : public service_base {
+public:
+ enum {
+ flag_disabled = 1<<0,
+ flag_checked = 1<<1,
+ sort_priority_base = 0x10000,
+ sort_priority_dontcare = 0x80000000,
+ sort_priority_last = infinite,
+ };
+
+ //! Retrieves number of implemented commands. Index parameter of other methods must be in 0....command_count-1 range.
+ virtual t_uint32 get_command_count() = 0;
+ //! Retrieves GUID of specified command.
+ virtual GUID get_command(t_uint32 p_index) = 0;
+ //! Retrieves name of item, for list of commands to assign keyboard shortcuts to etc.
+ virtual void get_name(t_uint32 p_index,pfc::string_base & p_out) = 0;
+ //! Retrieves item's description for statusbar etc.
+ virtual bool get_description(t_uint32 p_index,pfc::string_base & p_out) = 0;
+ //! Retrieves GUID of owning menu group.
+ virtual GUID get_parent() = 0;
+ //! Retrieves sorting priority of the command; the lower the number, the upper in the menu your commands will appear. Third party components should use sorting_priority_base and up (values below are reserved for internal use). In case of equal priority, order is undefined.
+ virtual t_uint32 get_sort_priority() {return sort_priority_dontcare;}
+ //! Retrieves display string and display flags to use when menu is about to be displayed. If returns false, menu item won't be displayed. You can create keyboard-shortcut-only commands by always returning false from get_display().
+ virtual bool get_display(t_uint32 p_index,pfc::string_base & p_text,t_uint32 & p_flags) {p_flags = 0;get_name(p_index,p_text);return true;}
+ //! Executes the command. p_callback parameter is reserved for future use and should be ignored / set to null pointer.
+ virtual void execute(t_uint32 p_index,service_ptr_t<service_base> p_callback) = 0;
+
+ static bool g_execute(const GUID & p_guid,service_ptr_t<service_base> p_callback = service_ptr_t<service_base>());
+ static bool g_find_by_name(const char * p_name,GUID & p_guid);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(mainmenu_commands);
+};
+
+class NOVTABLE mainmenu_manager : public service_base {
+public:
+ enum {
+ flag_show_shortcuts = 1 << 0,
+ flag_show_shortcuts_global = 1 << 1,
+ };
+
+ virtual void instantiate(const GUID & p_root) = 0;
+
+#ifdef _WIN32
+ virtual void generate_menu_win32(HMENU p_menu,t_uint32 p_id_base,t_uint32 p_id_count,t_uint32 p_flags) = 0;
+#else
+#error portme
+#endif
+ //@param p_id Identifier of command to execute, relative to p_id_base of generate_menu_*()
+ //@returns true if command was executed successfully, false if not (e.g. command with given identifier not found).
+ virtual bool execute_command(t_uint32 p_id,service_ptr_t<service_base> p_callback = service_ptr_t<service_base>()) = 0;
+
+ virtual bool get_description(t_uint32 p_id,pfc::string_base & p_out) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(mainmenu_manager);
+};
+
+class mainmenu_groups {
+public:
+ static const GUID file,view,edit,playback,library,help;
+ static const GUID file_open,file_add,file_playlist,file_etc;
+ static const GUID playback_controls,playback_etc;
+ static const GUID view_visualisations, view_alwaysontop;
+ static const GUID edit_part1,edit_part2,edit_part3;
+ static const GUID edit_part2_selection,edit_part2_sort,edit_part2_selection_sort;
+ static const GUID file_etc_preferences, file_etc_exit;
+ static const GUID help_about;
+ static const GUID library_refresh;
+
+ enum {priority_edit_part1,priority_edit_part2,priority_edit_part3};
+ enum {priority_edit_part2_commands,priority_edit_part2_selection,priority_edit_part2_sort};
+ enum {priority_edit_part2_selection_commands,priority_edit_part2_selection_sort};
+ enum {priority_file_open,priority_file_add,priority_file_playlist,priority_file_etc = mainmenu_commands::sort_priority_last};
+};
+
+
+class mainmenu_group_impl : public mainmenu_group {
+public:
+ mainmenu_group_impl(const GUID & p_guid,const GUID & p_parent,t_uint32 p_priority) : m_guid(p_guid), m_parent(p_parent), m_priority(p_priority) {}
+ GUID get_guid() {return m_guid;}
+ GUID get_parent() {return m_parent;}
+ t_uint32 get_sort_priority() {return m_priority;}
+private:
+ GUID m_guid,m_parent; t_uint32 m_priority;
+};
+
+class mainmenu_group_popup_impl : public mainmenu_group_popup {
+public:
+ mainmenu_group_popup_impl(const GUID & p_guid,const GUID & p_parent,t_uint32 p_priority,const char * p_name) : m_guid(p_guid), m_parent(p_parent), m_priority(p_priority), m_name(p_name) {}
+ GUID get_guid() {return m_guid;}
+ GUID get_parent() {return m_parent;}
+ t_uint32 get_sort_priority() {return m_priority;}
+ void get_display_string(pfc::string_base & p_out) {p_out = m_name;}
+private:
+ GUID m_guid,m_parent; t_uint32 m_priority; pfc::string8 m_name;
+};
+
+typedef service_factory_single_t<mainmenu_group_impl> __mainmenu_group_factory;
+typedef service_factory_single_t<mainmenu_group_popup_impl> __mainmenu_group_popup_factory;
+
+class mainmenu_group_factory : public __mainmenu_group_factory {
+public:
+ inline mainmenu_group_factory(const GUID & p_guid,const GUID & p_parent,t_uint32 p_priority) : __mainmenu_group_factory(p_guid,p_parent,p_priority) {}
+};
+
+class mainmenu_group_popup_factory : public __mainmenu_group_popup_factory {
+public:
+ inline mainmenu_group_popup_factory(const GUID & p_guid,const GUID & p_parent,t_uint32 p_priority,const char * p_name) : __mainmenu_group_popup_factory(p_guid,p_parent,p_priority,p_name) {}
+};
+
+template<typename T>
+class mainmenu_commands_factory_t : public service_factory_single_t<T> {}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_helpers.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_helpers.cpp
new file mode 100644
index 0000000..ad81e02
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_helpers.cpp
@@ -0,0 +1,360 @@
+#include "foobar2000.h"
+
+
+bool menu_helpers::context_get_description(const GUID& p_guid,pfc::string_base & out)
+{
+ service_enum_t<contextmenu_item> e;
+ service_ptr_t<contextmenu_item> ptr;
+ if (e.first(ptr)) do {
+ unsigned action,num_actions = ptr->get_num_items();
+ for(action=0;action<num_actions;action++)
+ {
+ if (p_guid == ptr->get_item_guid(action))
+ {
+ bool rv = ptr->get_item_description(action,out);
+ if (!rv) out.reset();
+ return rv;
+ }
+ }
+ } while(e.next(ptr));
+ return false;
+}
+
+static bool run_context_command_internal(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data,const GUID & caller)
+{
+ bool done = false;
+ if (data.get_count() > 0) {
+ service_enum_t<contextmenu_item> e;
+ service_ptr_t<contextmenu_item> ptr;
+ if (e.first(ptr)) do {
+ unsigned action,num_actions = ptr->get_num_items();
+ for(action=0;action<num_actions;action++)
+ {
+ if (p_command == ptr->get_item_guid(action))
+ {
+ TRACK_CALL_TEXT("menu_helpers::run_command(), by GUID");
+ ptr->item_execute_simple(action,p_subcommand,data,caller);
+ done = true;
+ break;
+ }
+ }
+ if (done) break;
+ } while(e.next(ptr));
+ }
+ return done;
+}
+
+bool menu_helpers::run_command_context(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data)
+{
+ return run_context_command_internal(p_command,p_subcommand,data,contextmenu_item::caller_undefined);
+}
+
+bool menu_helpers::run_command_context_ex(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data,const GUID & caller)
+{
+ return run_context_command_internal(p_command,p_subcommand,data,caller);
+}
+
+bool menu_helpers::test_command_context(const GUID & p_guid)
+{
+ service_enum_t<contextmenu_item> e;
+ service_ptr_t<contextmenu_item> ptr;
+ bool done = false;
+ if (e.first(ptr)) do {
+ unsigned action,num_actions = ptr->get_num_items();
+ for(action=0;action<num_actions;action++)
+ {
+ if (ptr->get_item_guid(action) == p_guid)
+ {
+ done = true;
+ break;
+ }
+ }
+ if (done) break;
+ } while(e.next(ptr));
+ return done;
+}
+
+static bool g_is_checked(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data,const GUID & caller)
+{
+ service_enum_t<contextmenu_item> e;
+ service_ptr_t<contextmenu_item> ptr;
+ bool done = false, rv = false;
+ pfc::string8_fastalloc dummystring;
+ if (e.first(ptr)) do {
+ unsigned action,num_actions = ptr->get_num_items();
+ for(action=0;action<num_actions;action++)
+ {
+ if (p_command == ptr->get_item_guid(action))
+ {
+ unsigned displayflags = 0;
+ if (ptr->item_get_display_data(dummystring,displayflags,action,p_subcommand,data,caller))
+ {
+ rv = !!(displayflags & contextmenu_item_node::FLAG_CHECKED);
+ done = true;
+ break;
+ }
+ }
+ }
+ if (done) break;
+ } while(e.next(ptr));
+ return rv;
+}
+
+bool menu_helpers::is_command_checked_context(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data)
+{
+ return g_is_checked(p_command,p_subcommand,data,contextmenu_item::caller_undefined);
+}
+
+bool menu_helpers::is_command_checked_context_playlist(const GUID & p_command,const GUID & p_subcommand)
+{
+ metadb_handle_list temp;
+ static_api_ptr_t<playlist_manager> api;
+ api->activeplaylist_get_selected_items(temp);
+ return g_is_checked(p_command,p_subcommand,temp,contextmenu_item::caller_playlist);
+}
+
+
+
+
+
+
+
+bool menu_helpers::run_command_context_playlist(const GUID & p_command,const GUID & p_subcommand)
+{
+ metadb_handle_list temp;
+ static_api_ptr_t<playlist_manager> api;
+ api->activeplaylist_get_selected_items(temp);
+ return run_command_context_ex(p_command,p_subcommand,temp,contextmenu_item::caller_playlist);
+}
+
+bool menu_helpers::run_command_context_now_playing(const GUID & p_command,const GUID & p_subcommand)
+{
+ metadb_handle_ptr item;
+ if (!static_api_ptr_t<playback_control>()->get_now_playing(item)) return false;//not playing
+ return run_command_context_ex(p_command,p_subcommand,pfc::list_single_ref_t<metadb_handle_ptr>(item),contextmenu_item::caller_now_playing);
+}
+
+
+bool menu_helpers::guid_from_name(const char * p_name,unsigned p_name_len,GUID & p_out)
+{
+ service_enum_t<contextmenu_item> e;
+ service_ptr_t<contextmenu_item> ptr;
+ pfc::string8_fastalloc nametemp;
+ while(e.next(ptr))
+ {
+ unsigned n, m = ptr->get_num_items();
+ for(n=0;n<m;n++)
+ {
+ ptr->get_item_name(n,nametemp);
+ if (!strcmp_ex(nametemp,infinite,p_name,p_name_len))
+ {
+ p_out = ptr->get_item_guid(n);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool menu_helpers::name_from_guid(const GUID & p_guid,pfc::string_base & p_out)
+{
+ service_enum_t<contextmenu_item> e;
+ service_ptr_t<contextmenu_item> ptr;
+ pfc::string8_fastalloc nametemp;
+ while(e.next(ptr))
+ {
+ unsigned n, m = ptr->get_num_items();
+ for(n=0;n<m;n++)
+ {
+ if (p_guid == ptr->get_item_guid(n))
+ {
+ ptr->get_item_name(n,p_out);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+static unsigned calc_total_action_count()
+{
+ service_enum_t<contextmenu_item> e;
+ service_ptr_t<contextmenu_item> ptr;
+ unsigned ret = 0;
+ while(e.next(ptr))
+ ret += ptr->get_num_items();
+ return ret;
+}
+
+
+const char * menu_helpers::guid_to_name_table::search(const GUID & p_guid)
+{
+ if (!m_inited)
+ {
+ m_data.set_size(calc_total_action_count());
+ t_size dataptr = 0;
+ pfc::string8_fastalloc nametemp;
+
+ service_enum_t<contextmenu_item> e;
+ service_ptr_t<contextmenu_item> ptr;
+ while(e.next(ptr))
+ {
+ unsigned n, m = ptr->get_num_items();
+ for(n=0;n<m;n++)
+ {
+ assert(dataptr < m_data.get_size());
+
+ ptr->get_item_name(n,nametemp);
+ m_data[dataptr].m_name = strdup(nametemp);
+ m_data[dataptr].m_guid = ptr->get_item_guid(n);
+ dataptr++;
+ }
+ }
+ assert(dataptr == m_data.get_size());
+
+ pfc::sort_t(m_data,entry_compare,m_data.get_size());
+ m_inited = true;
+ }
+ t_size index;
+ if (pfc::bsearch_t(m_data.get_size(),m_data,entry_compare_search,p_guid,index))
+ return m_data[index].m_name;
+ else
+ return 0;
+}
+
+int menu_helpers::guid_to_name_table::entry_compare_search(const entry & entry1,const GUID & entry2)
+{
+ return pfc::guid_compare(entry1.m_guid,entry2);
+}
+
+int menu_helpers::guid_to_name_table::entry_compare(const entry & entry1,const entry & entry2)
+{
+ return pfc::guid_compare(entry1.m_guid,entry2.m_guid);
+}
+
+menu_helpers::guid_to_name_table::guid_to_name_table()
+{
+ m_inited = false;
+}
+
+menu_helpers::guid_to_name_table::~guid_to_name_table()
+{
+ t_size n, m = m_data.get_size();
+ for(n=0;n<m;n++) free(m_data[n].m_name);
+
+}
+
+
+int menu_helpers::name_to_guid_table::entry_compare_search(const entry & entry1,const search_entry & entry2)
+{
+ return stricmp_utf8_ex(entry1.m_name,infinite,entry2.m_name,entry2.m_name_len);
+}
+
+int menu_helpers::name_to_guid_table::entry_compare(const entry & entry1,const entry & entry2)
+{
+ return stricmp_utf8(entry1.m_name,entry2.m_name);
+}
+
+bool menu_helpers::name_to_guid_table::search(const char * p_name,unsigned p_name_len,GUID & p_out)
+{
+ if (!m_inited)
+ {
+ m_data.set_size(calc_total_action_count());
+ t_size dataptr = 0;
+ pfc::string8_fastalloc nametemp;
+
+ service_enum_t<contextmenu_item> e;
+ service_ptr_t<contextmenu_item> ptr;
+ while(e.next(ptr))
+ {
+ unsigned n, m = ptr->get_num_items();
+ for(n=0;n<m;n++)
+ {
+ assert(dataptr < m_data.get_size());
+
+ ptr->get_item_name(n,nametemp);
+ m_data[dataptr].m_name = strdup(nametemp);
+ m_data[dataptr].m_guid = ptr->get_item_guid(n);
+ dataptr++;
+ }
+ }
+ assert(dataptr == m_data.get_size());
+
+ pfc::sort_t(m_data,entry_compare,m_data.get_size());
+ m_inited = true;
+ }
+ t_size index;
+ search_entry temp = {p_name,p_name_len};
+ if (pfc::bsearch_t(m_data.get_size(),m_data,entry_compare_search,temp,index))
+ {
+ p_out = m_data[index].m_guid;
+ return true;
+ }
+ else
+ return false;
+}
+
+menu_helpers::name_to_guid_table::name_to_guid_table()
+{
+ m_inited = false;
+}
+
+menu_helpers::name_to_guid_table::~name_to_guid_table()
+{
+ t_size n, m = m_data.get_size();
+ for(n=0;n<m;n++) free(m_data[n].m_name);
+
+}
+
+bool menu_helpers::find_command_by_name(const char * p_name,service_ptr_t<contextmenu_item> & p_item,unsigned & p_index)
+{
+ pfc::string8_fastalloc path,name;
+ service_enum_t<contextmenu_item> e;
+ service_ptr_t<contextmenu_item> ptr;
+ if (e.first(ptr)) do {
+// if (ptr->get_type()==type)
+ {
+ unsigned action,num_actions = ptr->get_num_items();
+ for(action=0;action<num_actions;action++)
+ {
+ ptr->get_item_default_path(action,path); ptr->get_item_name(action,name);
+ if (!path.is_empty()) path += "/";
+ path += name;
+ if (!stricmp_utf8(p_name,path))
+ {
+ p_item = ptr;
+ p_index = action;
+ return true;
+ }
+ }
+ }
+ } while(e.next(ptr));
+ return false;
+
+}
+
+bool menu_helpers::find_command_by_name(const char * p_name,GUID & p_command)
+{
+ service_ptr_t<contextmenu_item> item;
+ unsigned index;
+ bool ret = find_command_by_name(p_name,item,index);
+ if (ret) p_command = item->get_item_guid(index);
+ return ret;
+}
+
+
+bool standard_commands::run_main(const GUID & p_guid) {
+ service_enum_t<mainmenu_commands> e;
+ service_ptr_t<mainmenu_commands> ptr;
+ while(e.next(ptr)) {
+ const t_size count = ptr->get_command_count();
+ for(t_size n=0;n<count;n++) {
+ if (ptr->get_command(n) == p_guid) {
+ ptr->execute(n,service_ptr_t<service_base>());
+ return true;
+ }
+ }
+ }
+ return false;
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_helpers.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_helpers.h
new file mode 100644
index 0000000..60b6922
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_helpers.h
@@ -0,0 +1,183 @@
+namespace menu_helpers {
+#ifdef _WIN32
+ void win32_auto_mnemonics(HMENU menu);
+#endif
+
+ bool run_command_context(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data);
+ bool run_command_context_ex(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data,const GUID & caller);
+ bool run_command_context_playlist(const GUID & p_command,const GUID & p_subcommand);
+ bool run_command_context_now_playing(const GUID & p_command,const GUID & p_subcommand);
+
+ bool test_command_context(const GUID & p_guid);
+
+ bool is_command_checked_context(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data);
+ bool is_command_checked_context_playlist(const GUID & p_command,const GUID & p_subcommand);
+
+ bool find_command_by_name(const char * p_name,service_ptr_t<contextmenu_item> & p_item,unsigned & p_index);
+ bool find_command_by_name(const char * p_name,GUID & p_command);
+
+ bool context_get_description(const GUID& p_guid,pfc::string_base & out);
+
+ bool guid_from_name(const char * p_name,unsigned p_name_len,GUID & p_out);
+ bool name_from_guid(const GUID & p_guid,pfc::string_base & p_out);
+
+ class guid_to_name_table
+ {
+ public:
+ guid_to_name_table();
+ ~guid_to_name_table();
+ const char * search(const GUID & p_guid);
+ private:
+ struct entry {
+ char* m_name;
+ GUID m_guid;
+ };
+ pfc::array_t<entry> m_data;
+ bool m_inited;
+
+ static int entry_compare_search(const entry & entry1,const GUID & entry2);
+ static int entry_compare(const entry & entry1,const entry & entry2);
+ };
+
+ class name_to_guid_table
+ {
+ public:
+ name_to_guid_table();
+ ~name_to_guid_table();
+ bool search(const char * p_name,unsigned p_name_len,GUID & p_out);
+ private:
+ struct entry {
+ char* m_name;
+ GUID m_guid;
+ };
+ pfc::array_t<entry> m_data;
+ bool m_inited;
+ struct search_entry {
+ const char * m_name; unsigned m_name_len;
+ };
+
+ static int entry_compare_search(const entry & entry1,const search_entry & entry2);
+ static int entry_compare(const entry & entry1,const entry & entry2);
+ };
+
+};
+
+
+
+class standard_commands
+{
+public:
+ static const GUID
+ guid_context_file_properties, guid_context_file_open_directory, guid_context_copy_names,
+ guid_context_send_to_playlist, guid_context_reload_info, guid_context_reload_info_if_changed,
+ guid_context_rewrite_info, guid_context_remove_tags, guid_context_remove_from_database,
+ guid_context_convert_run, guid_context_convert_run_singlefile,guid_context_convert_run_withcue,
+ guid_context_write_cd,
+ guid_context_rg_scan_track, guid_context_rg_scan_album, guid_context_rg_scan_album_multi,
+ guid_context_rg_remove, guid_context_save_playlist, guid_context_masstag_edit,
+ guid_context_masstag_rename,
+ guid_main_always_on_top, guid_main_preferences, guid_main_about,
+ guid_main_exit, guid_main_restart, guid_main_activate,
+ guid_main_hide, guid_main_activate_or_hide, guid_main_titleformat_help,
+ guid_main_next, guid_main_previous,
+ guid_main_next_or_random, guid_main_random, guid_main_pause,
+ guid_main_play, guid_main_play_or_pause, guid_main_rg_set_album,
+ guid_main_rg_set_track, guid_main_rg_disable, guid_main_stop,
+ guid_main_stop_after_current, guid_main_volume_down, guid_main_volume_up,
+ guid_main_volume_mute, guid_main_add_directory, guid_main_add_files,
+ guid_main_add_location, guid_main_add_playlist, guid_main_clear_playlist,
+ guid_main_create_playlist, guid_main_highlight_playing, guid_main_load_playlist,
+ guid_main_next_playlist, guid_main_previous_playlist, guid_main_open,
+ guid_main_remove_playlist, guid_main_remove_dead_entries, guid_main_remove_duplicates,
+ guid_main_rename_playlist, guid_main_save_all_playlists, guid_main_save_playlist,
+ guid_main_playlist_search, guid_main_playlist_sel_crop, guid_main_playlist_sel_remove,
+ guid_main_playlist_sel_invert, guid_main_playlist_undo, guid_main_show_console,
+ guid_main_play_cd, guid_main_restart_resetconfig, guid_main_record,
+ guid_main_playlist_moveback, guid_main_playlist_moveforward, guid_main_playlist_redo,
+ guid_main_playback_follows_cursor, guid_main_cursor_follows_playback, guid_main_saveconfig,
+ guid_main_playlist_select_all, guid_main_show_now_playing,
+
+ guid_seek_ahead_1s, guid_seek_ahead_5s, guid_seek_ahead_10s, guid_seek_ahead_30s,
+ guid_seek_ahead_1min, guid_seek_ahead_2min, guid_seek_ahead_5min, guid_seek_ahead_10min,
+
+ guid_seek_back_1s, guid_seek_back_5s, guid_seek_back_10s, guid_seek_back_30s,
+ guid_seek_back_1min, guid_seek_back_2min, guid_seek_back_5min, guid_seek_back_10min
+ ;
+
+ static bool run_main(const GUID & guid);
+ static inline bool run_context(const GUID & guid,const pfc::list_base_const_t<metadb_handle_ptr> &data) {return menu_helpers::run_command_context(guid,pfc::guid_null,data);}
+ static inline bool run_context(const GUID & guid,const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller) {return menu_helpers::run_command_context_ex(guid,pfc::guid_null,data,caller);}
+
+ static inline bool context_file_properties(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_file_properties,data,caller);}
+ static inline bool context_file_open_directory(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_file_open_directory,data,caller);}
+ static inline bool context_copy_names(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_copy_names,data,caller);}
+ static inline bool context_send_to_playlist(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_send_to_playlist,data,caller);}
+ static inline bool context_reload_info(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_reload_info,data,caller);}
+ static inline bool context_reload_info_if_changed(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_reload_info_if_changed,data,caller);}
+ static inline bool context_rewrite_info(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_rewrite_info,data,caller);}
+ static inline bool context_remove_tags(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_remove_tags,data,caller);}
+ static inline bool context_remove_from_database(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_remove_from_database,data,caller);}
+ static inline bool context_convert_run(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_convert_run,data,caller);}
+ static inline bool context_convert_run_singlefile(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_convert_run_singlefile,data,caller);}
+ static inline bool context_write_cd(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_write_cd,data,caller);}
+ static inline bool context_rg_scan_track(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_rg_scan_track,data,caller);}
+ static inline bool context_rg_scan_album(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_rg_scan_album,data,caller);}
+ static inline bool context_rg_scan_album_multi(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_rg_scan_album_multi,data,caller);}
+ static inline bool context_rg_remove(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_rg_remove,data,caller);}
+ static inline bool context_save_playlist(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_save_playlist,data,caller);}
+ static inline bool context_masstag_edit(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_masstag_edit,data,caller);}
+ static inline bool context_masstag_rename(const pfc::list_base_const_t<metadb_handle_ptr> &data,const GUID& caller = contextmenu_item::caller_undefined) {return run_context(guid_context_masstag_rename,data,caller);}
+ static inline bool main_always_on_top() {return run_main(guid_main_always_on_top);}
+ static inline bool main_preferences() {return run_main(guid_main_preferences);}
+ static inline bool main_about() {return run_main(guid_main_about);}
+ static inline bool main_exit() {return run_main(guid_main_exit);}
+ static inline bool main_restart() {return run_main(guid_main_restart);}
+ static inline bool main_activate() {return run_main(guid_main_activate);}
+ static inline bool main_hide() {return run_main(guid_main_hide);}
+ static inline bool main_activate_or_hide() {return run_main(guid_main_activate_or_hide);}
+ static inline bool main_titleformat_help() {return run_main(guid_main_titleformat_help);}
+ static inline bool main_playback_follows_cursor() {return run_main(guid_main_playback_follows_cursor);}
+ static inline bool main_next() {return run_main(guid_main_next);}
+ static inline bool main_previous() {return run_main(guid_main_previous);}
+ static inline bool main_next_or_random() {return run_main(guid_main_next_or_random);}
+ static inline bool main_random() {return run_main(guid_main_random);}
+ static inline bool main_pause() {return run_main(guid_main_pause);}
+ static inline bool main_play() {return run_main(guid_main_play);}
+ static inline bool main_play_or_pause() {return run_main(guid_main_play_or_pause);}
+ static inline bool main_rg_set_album() {return run_main(guid_main_rg_set_album);}
+ static inline bool main_rg_set_track() {return run_main(guid_main_rg_set_track);}
+ static inline bool main_rg_disable() {return run_main(guid_main_rg_disable);}
+ static inline bool main_stop() {return run_main(guid_main_stop);}
+ static inline bool main_stop_after_current() {return run_main(guid_main_stop_after_current);}
+ static inline bool main_volume_down() {return run_main(guid_main_volume_down);}
+ static inline bool main_volume_up() {return run_main(guid_main_volume_up);}
+ static inline bool main_volume_mute() {return run_main(guid_main_volume_mute);}
+ static inline bool main_add_directory() {return run_main(guid_main_add_directory);}
+ static inline bool main_add_files() {return run_main(guid_main_add_files);}
+ static inline bool main_add_location() {return run_main(guid_main_add_location);}
+ static inline bool main_add_playlist() {return run_main(guid_main_add_playlist);}
+ static inline bool main_clear_playlist() {return run_main(guid_main_clear_playlist);}
+ static inline bool main_create_playlist() {return run_main(guid_main_create_playlist);}
+ static inline bool main_highlight_playing() {return run_main(guid_main_highlight_playing);}
+ static inline bool main_load_playlist() {return run_main(guid_main_load_playlist);}
+ static inline bool main_next_playlist() {return run_main(guid_main_next_playlist);}
+ static inline bool main_previous_playlist() {return run_main(guid_main_previous_playlist);}
+ static inline bool main_open() {return run_main(guid_main_open);}
+ static inline bool main_remove_playlist() {return run_main(guid_main_remove_playlist);}
+ static inline bool main_remove_dead_entries() {return run_main(guid_main_remove_dead_entries);}
+ static inline bool main_remove_duplicates() {return run_main(guid_main_remove_duplicates);}
+ static inline bool main_rename_playlist() {return run_main(guid_main_rename_playlist);}
+ static inline bool main_save_all_playlists() {return run_main(guid_main_save_all_playlists);}
+ static inline bool main_save_playlist() {return run_main(guid_main_save_playlist);}
+ static inline bool main_playlist_search() {return run_main(guid_main_playlist_search);}
+ static inline bool main_playlist_sel_crop() {return run_main(guid_main_playlist_sel_crop);}
+ static inline bool main_playlist_sel_remove() {return run_main(guid_main_playlist_sel_remove);}
+ static inline bool main_playlist_sel_invert() {return run_main(guid_main_playlist_sel_invert);}
+ static inline bool main_playlist_undo() {return run_main(guid_main_playlist_undo);}
+ static inline bool main_show_console() {return run_main(guid_main_show_console);}
+ static inline bool main_play_cd() {return run_main(guid_main_play_cd);}
+ static inline bool main_restart_resetconfig() {return run_main(guid_main_restart_resetconfig);}
+ static inline bool main_playlist_moveback() {return run_main(guid_main_playlist_moveback);}
+ static inline bool main_playlist_moveforward() {return run_main(guid_main_playlist_moveforward);}
+ static inline bool main_saveconfig() {return run_main(guid_main_saveconfig);}
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_item.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_item.cpp
new file mode 100644
index 0000000..b4e5cbf
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_item.cpp
@@ -0,0 +1,40 @@
+#include "foobar2000.h"
+
+
+
+bool contextmenu_item::item_get_display_data_root(pfc::string_base & p_out,unsigned & p_displayflags,unsigned p_index,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller)
+{
+ bool status = false;
+ pfc::ptrholder_t<contextmenu_item_node_root> root ( instantiate_item(p_index,p_data,p_caller) );
+ if (root.is_valid()) status = root->get_display_data(p_out,p_displayflags,p_data,p_caller);
+ return status;
+}
+
+
+static contextmenu_item_node * g_find_node(const GUID & p_guid,contextmenu_item_node * p_parent)
+{
+ if (p_parent->get_guid() == p_guid) return p_parent;
+ else if (p_parent->get_type() == contextmenu_item_node::TYPE_POPUP)
+ {
+ t_size n, m = p_parent->get_children_count();
+ for(n=0;n<m;n++)
+ {
+ contextmenu_item_node * temp = g_find_node(p_guid,p_parent->get_child(n));
+ if (temp) return temp;
+ }
+ return 0;
+ }
+ else return 0;
+}
+
+bool contextmenu_item::item_get_display_data(pfc::string_base & p_out,unsigned & p_displayflags,unsigned p_index,const GUID & p_node,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const GUID & p_caller)
+{
+ bool status = false;
+ pfc::ptrholder_t<contextmenu_item_node_root> root ( instantiate_item(p_index,p_data,p_caller) );
+ if (root.is_valid())
+ {
+ contextmenu_item_node * node = g_find_node(p_node,root.get_ptr());
+ if (node) status = node->get_display_data(p_out,p_displayflags,p_data,p_caller);
+ }
+ return status;
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_manager.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_manager.cpp
new file mode 100644
index 0000000..ebb8f67
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/menu_manager.cpp
@@ -0,0 +1,307 @@
+#include "foobar2000.h"
+
+#ifdef WIN32
+
+static void fix_ampersand(const char * src,pfc::string_base & out)
+{
+ unsigned ptr = 0;
+ while(src[ptr])
+ {
+ if (src[ptr]=='&')
+ {
+ out.add_string("&&");
+ ptr++;
+ while(src[ptr]=='&')
+ {
+ out.add_string("&&");
+ ptr++;
+ }
+ }
+ else out.add_byte(src[ptr++]);
+ }
+}
+
+static unsigned flags_to_win32(unsigned flags)
+{
+ unsigned ret = 0;
+ if (flags & contextmenu_item_node::FLAG_CHECKED) ret |= MF_CHECKED;
+ if (flags & contextmenu_item_node::FLAG_DISABLED) ret |= MF_DISABLED;
+ if (flags & contextmenu_item_node::FLAG_GRAYED) ret |= MF_GRAYED;
+ return ret;
+}
+
+void contextmenu_manager::win32_build_menu(HMENU menu,contextmenu_node * parent,int base_id,int max_id)//menu item identifiers are base_id<=N<base_id+max_id (if theres too many items, they will be clipped)
+{
+ if (parent!=0 && parent->get_type()==contextmenu_item_node::TYPE_POPUP)
+ {
+ pfc::string8_fastalloc temp;
+ t_size child_idx,child_num = parent->get_num_children();
+ for(child_idx=0;child_idx<child_num;child_idx++)
+ {
+ contextmenu_node * child = parent->get_child(child_idx);
+ if (child)
+ {
+ const char * name = child->get_name();
+ if (strchr(name,'&')) {fix_ampersand(name,temp);name=temp;}
+ contextmenu_item_node::t_type type = child->get_type();
+ if (type==contextmenu_item_node::TYPE_POPUP)
+ {
+ HMENU new_menu = CreatePopupMenu();
+ uAppendMenu(menu,MF_STRING|MF_POPUP | flags_to_win32(child->get_display_flags()),(UINT_PTR)new_menu,name);
+ win32_build_menu(new_menu,child,base_id,max_id);
+ }
+ else if (type==contextmenu_item_node::TYPE_SEPARATOR)
+ {
+ uAppendMenu(menu,MF_SEPARATOR,0,0);
+ }
+ else if (type==contextmenu_item_node::TYPE_COMMAND)
+ {
+ int id = child->get_id();
+ if (id>=0 && (max_id<0 || id<max_id))
+ {
+ uAppendMenu(menu,MF_STRING | flags_to_win32(child->get_display_flags()),base_id+id,name);
+ }
+ }
+ }
+ }
+ }
+}
+
+#endif
+
+bool contextmenu_manager::execute_by_id(unsigned id)
+{
+ bool rv = false;
+ contextmenu_node * ptr = find_by_id(id);
+ if (ptr) {rv=true;ptr->execute();}
+ return rv;
+}
+
+#ifdef WIN32
+
+void contextmenu_manager::win32_run_menu_popup(HWND parent,const POINT * pt)
+{
+ enum {ID_CUSTOM_BASE = 1};
+
+ int cmd;
+
+ {
+ POINT p;
+ if (pt) p = *pt;
+ else GetCursorPos(&p);
+
+ HMENU hmenu = CreatePopupMenu();
+ try {
+
+ win32_build_menu(hmenu,ID_CUSTOM_BASE,-1);
+ menu_helpers::win32_auto_mnemonics(hmenu);
+
+ cmd = TrackPopupMenu(hmenu,TPM_RIGHTBUTTON|TPM_NONOTIFY|TPM_RETURNCMD,p.x,p.y,0,parent,0);
+ } catch(...) {DestroyMenu(hmenu); throw;}
+
+ DestroyMenu(hmenu);
+ }
+
+ if (cmd>0)
+ {
+ if (cmd>=ID_CUSTOM_BASE)
+ {
+ execute_by_id(cmd - ID_CUSTOM_BASE);
+ }
+ }
+}
+
+void contextmenu_manager::win32_run_menu_context(HWND parent,const pfc::list_base_const_t<metadb_handle_ptr> & data,const POINT * pt,unsigned flags)
+{
+ service_ptr_t<contextmenu_manager> manager;
+ contextmenu_manager::g_create(manager);
+ manager->init_context(data,flags);
+ manager->win32_run_menu_popup(parent,pt);
+}
+
+void contextmenu_manager::win32_run_menu_context_playlist(HWND parent,const POINT * pt,unsigned flags)
+{
+ service_ptr_t<contextmenu_manager> manager;
+ contextmenu_manager::g_create(manager);
+ manager->init_context_playlist(flags);
+ manager->win32_run_menu_popup(parent,pt);
+}
+
+
+namespace {
+ class mnemonic_manager
+ {
+ pfc::string8_fastalloc used;
+ bool is_used(unsigned c)
+ {
+ char temp[8];
+ temp[pfc::utf8_encode_char(char_lower(c),temp)]=0;
+ return !!strstr(used,temp);
+ }
+
+ static bool is_alphanumeric(char c)
+ {
+ return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9');
+ }
+
+
+
+
+ void insert(const char * src,unsigned idx,pfc::string_base & out)
+ {
+ out.reset();
+ out.add_string(src,idx);
+ out.add_string("&");
+ out.add_string(src+idx);
+ used.add_char(char_lower(src[idx]));
+ }
+ public:
+ bool check_string(const char * src)
+ {//check for existing mnemonics
+ const char * ptr = src;
+ while(ptr = strchr(ptr,'&'))
+ {
+ if (ptr[1]=='&') ptr+=2;
+ else
+ {
+ unsigned c = 0;
+ if (pfc::utf8_decode_char(ptr+1,&c)>0)
+ {
+ if (!is_used(c)) used.add_char(char_lower(c));
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+ bool process_string(const char * src,pfc::string_base & out)//returns if changed
+ {
+ if (check_string(src)) {out=src;return false;}
+ unsigned idx=0;
+ while(src[idx]==' ') idx++;
+ while(src[idx])
+ {
+ if (is_alphanumeric(src[idx]) && !is_used(src[idx]))
+ {
+ insert(src,idx,out);
+ return true;
+ }
+
+ while(src[idx] && src[idx]!=' ' && src[idx]!='\t') idx++;
+ if (src[idx]=='\t') break;
+ while(src[idx]==' ') idx++;
+ }
+
+ //no success picking first letter of one of words
+ idx=0;
+ while(src[idx])
+ {
+ if (src[idx]=='\t') break;
+ if (is_alphanumeric(src[idx]) && !is_used(src[idx]))
+ {
+ insert(src,idx,out);
+ return true;
+ }
+ idx++;
+ }
+
+ //giving up
+ out = src;
+ return false;
+ }
+ };
+}
+
+void menu_helpers::win32_auto_mnemonics(HMENU menu)
+{
+ mnemonic_manager mgr;
+ unsigned n, m = GetMenuItemCount(menu);
+ pfc::string8_fastalloc temp,temp2;
+ for(n=0;n<m;n++)//first pass, check existing mnemonics
+ {
+ unsigned type = uGetMenuItemType(menu,n);
+ if (type==MFT_STRING)
+ {
+ uGetMenuString(menu,n,temp,MF_BYPOSITION);
+ mgr.check_string(temp);
+ }
+ }
+
+ for(n=0;n<m;n++)
+ {
+ HMENU submenu = GetSubMenu(menu,n);
+ if (submenu) win32_auto_mnemonics(submenu);
+
+ {
+ unsigned type = uGetMenuItemType(menu,n);
+ if (type==MFT_STRING)
+ {
+ unsigned state = submenu ? 0 : GetMenuState(menu,n,MF_BYPOSITION);
+ unsigned id = GetMenuItemID(menu,n);
+ uGetMenuString(menu,n,temp,MF_BYPOSITION);
+ if (mgr.process_string(temp,temp2))
+ {
+ uModifyMenu(menu,n,MF_BYPOSITION|MF_STRING|state,id,temp2);
+ }
+ }
+ }
+ }
+}
+
+#endif
+
+static bool test_key(unsigned k)
+{
+ return (GetKeyState(k) & 0x8000) ? true : false;
+}
+
+#define F_SHIFT (HOTKEYF_SHIFT<<8)
+#define F_CTRL (HOTKEYF_CONTROL<<8)
+#define F_ALT (HOTKEYF_ALT<<8)
+#define F_WIN (HOTKEYF_EXT<<8)
+
+static unsigned get_key_code(WPARAM wp)
+{
+ unsigned code = (unsigned)(wp & 0xFF);
+ if (test_key(VK_CONTROL)) code|=F_CTRL;
+ if (test_key(VK_SHIFT)) code|=F_SHIFT;
+ if (test_key(VK_MENU)) code|=F_ALT;
+ if (test_key(VK_LWIN) || test_key(VK_RWIN)) code|=F_WIN;
+ return code;
+}
+
+bool keyboard_shortcut_manager::on_keydown(shortcut_type type,WPARAM wp)
+{
+ if (type==TYPE_CONTEXT) return false;
+ metadb_handle_list dummy;
+ return process_keydown(type,dummy,get_key_code(wp));
+}
+
+bool keyboard_shortcut_manager::on_keydown_context(const pfc::list_base_const_t<metadb_handle_ptr> & data,WPARAM wp,const GUID & caller)
+{
+ if (data.get_count()==0) return false;
+ return process_keydown_ex(TYPE_CONTEXT,data,get_key_code(wp),caller);
+}
+
+bool keyboard_shortcut_manager::on_keydown_auto(WPARAM wp)
+{
+ if (on_keydown(TYPE_MAIN,wp)) return true;
+ if (on_keydown(TYPE_CONTEXT_PLAYLIST,wp)) return true;
+ if (on_keydown(TYPE_CONTEXT_NOW_PLAYING,wp)) return true;
+ return false;
+}
+
+bool keyboard_shortcut_manager::on_keydown_auto_playlist(WPARAM wp)
+{
+ metadb_handle_list data;
+ static_api_ptr_t<playlist_manager> api;
+ api->activeplaylist_get_selected_items(data);
+ return on_keydown_auto_context(data,wp,contextmenu_item::caller_playlist);
+}
+
+bool keyboard_shortcut_manager::on_keydown_auto_context(const pfc::list_base_const_t<metadb_handle_ptr> & data,WPARAM wp,const GUID & caller)
+{
+ if (on_keydown_context(data,wp,caller)) return true;
+ else return on_keydown_auto(wp);
+}
+
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/message_loop.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/message_loop.h
new file mode 100644
index 0000000..a5ad203
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/message_loop.h
@@ -0,0 +1,56 @@
+class NOVTABLE message_filter
+{
+public:
+ virtual bool pretranslate_message(MSG * p_msg) = 0;
+};
+
+class NOVTABLE idle_handler
+{
+public:
+ virtual bool on_idle() = 0;
+};
+
+class NOVTABLE message_loop : public service_base
+{
+public:
+ virtual void add_message_filter(message_filter * ptr) = 0;
+ virtual void remove_message_filter(message_filter * ptr) = 0;
+
+ virtual void add_idle_handler(idle_handler * ptr) = 0;
+ virtual void remove_idle_handler(idle_handler * ptr) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(message_loop);
+};
+
+class message_filter_impl_base : public message_filter {
+public:
+ message_filter_impl_base() {static_api_ptr_t<message_loop>()->add_message_filter(this);}
+ ~message_filter_impl_base() {static_api_ptr_t<message_loop>()->remove_message_filter(this);}
+ bool pretranslate_message(MSG * p_msg) {return false;}
+
+ PFC_CLASS_NOT_COPYABLE(message_filter_impl_base,message_filter_impl_base);
+};
+
+class message_filter_impl_accel : public message_filter_impl_base {
+protected:
+ bool pretranslate_message(MSG * p_msg) {
+ if (m_wnd != NULL) {
+ if (GetActiveWindow() == m_wnd) {
+ if (TranslateAccelerator(m_wnd,m_accel.get(),p_msg) != 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+public:
+ message_filter_impl_accel(HINSTANCE p_instance,const TCHAR * p_accel) : m_wnd(NULL) {
+ m_accel.load(p_instance,p_accel);
+ }
+ void set_wnd(HWND p_wnd) {m_wnd = p_wnd;}
+private:
+ HWND m_wnd;
+ win32_accelerator m_accel;
+
+ PFC_CLASS_NOT_COPYABLE(message_filter_impl_accel,message_filter_impl_accel);
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb.cpp
new file mode 100644
index 0000000..4628ddb
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb.cpp
@@ -0,0 +1,176 @@
+#include "foobar2000.h"
+
+
+void metadb::handle_create_replace_path_canonical(metadb_handle_ptr & p_out,const metadb_handle_ptr & p_source,const char * p_new_path) {
+ handle_create(p_out,make_playable_location(p_new_path,p_source->get_subsong_index()));
+}
+
+void metadb::handle_create_replace_path(metadb_handle_ptr & p_out,const metadb_handle_ptr & p_source,const char * p_new_path) {
+ pfc::string8 path;
+ filesystem::g_get_canonical_path(p_new_path,path);
+ handle_create_replace_path_canonical(p_out,p_source,path);
+}
+
+void metadb::handle_replace_path_canonical(metadb_handle_ptr & p_out,const char * p_new_path) {
+ metadb_handle_ptr temp;
+ handle_create_replace_path_canonical(temp,p_out,p_new_path);
+ p_out = temp;
+}
+
+
+metadb_io::t_load_info_state metadb_io::load_info(metadb_handle_ptr p_item,t_load_info_type p_type,HWND p_parent_window,bool p_show_errors) {
+ return load_info_multi(pfc::list_single_ref_t<metadb_handle_ptr>(p_item),p_type,p_parent_window,p_show_errors);
+}
+
+metadb_io::t_update_info_state metadb_io::update_info(metadb_handle_ptr p_item,file_info & p_info,HWND p_parent_window,bool p_show_errors)
+{
+ file_info * blah = &p_info;
+ return update_info_multi(pfc::list_single_ref_t<metadb_handle_ptr>(p_item),pfc::list_single_ref_t<file_info*>(blah),p_parent_window,p_show_errors);
+}
+
+file_info_update_helper::file_info_update_helper(metadb_handle_ptr p_item)
+{
+ const t_size count = 1;
+ m_data.add_item(p_item);
+
+ m_infos.set_size(count);
+ m_mask.set_size(count);
+ for(t_size n=0;n<count;n++) m_mask[n] = false;
+}
+
+file_info_update_helper::file_info_update_helper(const pfc::list_base_const_t<metadb_handle_ptr> & p_data)
+{
+ const t_size count = p_data.get_count();
+ m_data.add_items(p_data);
+
+ m_infos.set_size(count);
+ m_mask.set_size(count);
+ for(t_size n=0;n<count;n++) m_mask[n] = false;
+}
+
+bool file_info_update_helper::read_infos(HWND p_parent,bool p_show_errors)
+{
+ static_api_ptr_t<metadb_io> api;
+ if (api->load_info_multi(m_data,metadb_io::load_info_default,p_parent,p_show_errors) != metadb_io::load_info_success) return false;
+ t_size n; const t_size m = m_data.get_count();
+ t_size loaded_count = 0;
+ for(n=0;n<m;n++)
+ {
+ bool val = m_data[n]->get_info(m_infos[n]);
+ if (val) loaded_count++;
+ m_mask[n] = val;
+ }
+ return loaded_count == m;
+}
+
+file_info_update_helper::t_write_result file_info_update_helper::write_infos(HWND p_parent,bool p_show_errors)
+{
+ t_size n, outptr = 0; const t_size count = m_data.get_count();
+ pfc::array_t<metadb_handle_ptr> items_to_update;
+ pfc::array_t<file_info *> infos_to_write;
+ items_to_update.set_size(count);
+ infos_to_write.set_size(count);
+
+ for(n=0;n<count;n++)
+ {
+ if (m_mask[n])
+ {
+ items_to_update[outptr] = m_data[n];
+ infos_to_write[outptr] = &m_infos[n];
+ outptr++;
+ }
+ }
+
+ if (outptr == 0) return write_ok;
+ else
+ {
+ static_api_ptr_t<metadb_io> api;
+ switch(api->update_info_multi(
+ pfc::list_const_array_t<metadb_handle_ptr,const pfc::array_t<metadb_handle_ptr>&>(items_to_update,outptr),
+ pfc::list_const_array_t<file_info*,const pfc::array_t<file_info*>&>(infos_to_write,outptr),
+ p_parent,
+ true
+ ))
+ {
+ case metadb_io::update_info_success:
+ return write_ok;
+ case metadb_io::update_info_aborted:
+ return write_aborted;
+ default:
+ case metadb_io::update_info_errors:
+ return write_error;
+ }
+ }
+}
+
+t_size file_info_update_helper::get_item_count() const
+{
+ return m_data.get_count();
+}
+
+bool file_info_update_helper::is_item_valid(t_size p_index) const
+{
+ return m_mask[p_index];
+}
+
+file_info & file_info_update_helper::get_item(t_size p_index)
+{
+ return m_infos[p_index];
+}
+
+metadb_handle_ptr file_info_update_helper::get_item_handle(t_size p_index) const
+{
+ return m_data[p_index];
+}
+
+void file_info_update_helper::invalidate_item(t_size p_index)
+{
+ m_mask[p_index] = false;
+}
+
+
+void metadb_io::hint_async(metadb_handle_ptr p_item,const file_info & p_info,const t_filestats & p_stats,bool p_fresh)
+{
+ const file_info * blargh = &p_info;
+ hint_multi_async(pfc::list_single_ref_t<metadb_handle_ptr>(p_item),pfc::list_single_ref_t<const file_info *>(blargh),pfc::list_single_ref_t<t_filestats>(p_stats),bit_array_val(p_fresh));
+}
+
+
+bool metadb::g_get_random_handle(metadb_handle_ptr & p_out) {
+ if (static_api_ptr_t<playback_control>()->get_now_playing(p_out)) return true;
+
+ {
+ static_api_ptr_t<playlist_manager> api;
+
+ t_size playlist_count = api->get_playlist_count();
+ t_size active_playlist = api->get_active_playlist();
+ if (active_playlist != infinite) {
+ if (api->playlist_get_focus_item_handle(p_out,active_playlist)) return true;
+ }
+
+ for(t_size n = 0; n < playlist_count; n++) {
+ if (api->playlist_get_focus_item_handle(p_out,n)) return true;
+ }
+
+ if (active_playlist != infinite) {
+ t_size item_count = api->playlist_get_item_count(active_playlist);
+ if (item_count > 0) {
+ if (api->playlist_get_item_handle(p_out,active_playlist,0)) return true;
+ }
+ }
+
+ for(t_size n = 0; n < playlist_count; n++) {
+ t_size item_count = api->playlist_get_item_count(n);
+ if (item_count > 0) {
+ if (api->playlist_get_item_handle(p_out,n,0)) return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+
+void metadb_io_v2::update_info_async_simple(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,const pfc::list_base_const_t<const file_info*> & p_new_info, HWND p_parent_window,t_uint32 p_op_flags,completion_notify_ptr p_notify) {
+ update_info_async(p_list,new service_impl_t<file_info_filter_impl>(p_list,p_new_info),p_parent_window,p_op_flags,p_notify);
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb.h
new file mode 100644
index 0000000..525570c
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb.h
@@ -0,0 +1,301 @@
+#ifndef _METADB_H_
+#define _METADB_H_
+
+//! API for tag read/write operations. Legal to call from main thread only, except for hint_multi_async() / hint_async().\n
+//! Implemented only by core, do not reimplement.\n
+//! Use static_api_ptr_t template to access metadb_io methods.\n
+//! WARNING: Methods that perform file access (tag reads/writes) run a modal message loop. They SHOULD NOT be called from global callbacks and such.
+class NOVTABLE metadb_io : public service_base
+{
+public:
+ enum t_load_info_type {
+ load_info_default,
+ load_info_force,
+ load_info_check_if_changed
+ };
+
+ enum t_update_info_state {
+ update_info_success,
+ update_info_aborted,
+ update_info_errors,
+ };
+
+ enum t_load_info_state {
+ load_info_success,
+ load_info_aborted,
+ load_info_errors,
+ };
+
+ //! Returns whether some tag I/O operation is currently running. Another one can't be started.
+ __declspec(deprecated) virtual bool is_busy() = 0;
+ //! Returns whether - in result of user settings - all update operations will fail.
+ __declspec(deprecated) virtual bool is_updating_disabled() = 0;
+ //! Returns whether - in result of user settings - all update operations will silently succeed but without actually modifying files.
+ __declspec(deprecated) virtual bool is_file_updating_blocked() = 0;
+ //! If another tag I/O operation is running, this call will give focus to its progress window.
+ __declspec(deprecated) virtual void highlight_running_process() = 0;
+ //! Loads tags from multiple items.
+ __declspec(deprecated) virtual t_load_info_state load_info_multi(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,t_load_info_type p_type,HWND p_parent_window,bool p_show_errors) = 0;
+ //! Updates tags on multiple items.
+ __declspec(deprecated) virtual t_update_info_state update_info_multi(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,const pfc::list_base_const_t<file_info*> & p_new_info,HWND p_parent_window,bool p_show_errors) = 0;
+ //! Rewrites tags on multiple items.
+ __declspec(deprecated) virtual t_update_info_state rewrite_info_multi(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,HWND p_parent_window,bool p_show_errors) = 0;
+ //! Removes tags from multiple items.
+ __declspec(deprecated) virtual t_update_info_state remove_info_multi(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,HWND p_parent_window,bool p_show_errors) = 0;
+
+ virtual void hint_multi(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,const pfc::list_base_const_t<const file_info*> & p_infos,const pfc::list_base_const_t<t_filestats> & p_stats,const bit_array & p_fresh_mask) = 0;
+
+ virtual void hint_multi_async(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,const pfc::list_base_const_t<const file_info*> & p_infos,const pfc::list_base_const_t<t_filestats> & p_stats,const bit_array & p_fresh_mask) = 0;
+
+ virtual void hint_reader(service_ptr_t<class input_info_reader> p_reader,const char * p_path,abort_callback & p_abort) = 0;
+
+ //! For internal use only.
+ virtual void path_to_handles_simple(const char * p_path,pfc::list_base_t<metadb_handle_ptr> & p_out) = 0;
+
+ //! Dispatches metadb_io_callback calls with specified items. To be used with metadb_display_hook when your component needs specified items refreshed.
+ virtual void dispatch_refresh(const pfc::list_base_const_t<metadb_handle_ptr> & p_list) = 0;
+
+ void hint_async(metadb_handle_ptr p_item,const file_info & p_info,const t_filestats & p_stats,bool p_fresh);
+
+ __declspec(deprecated) t_load_info_state load_info(metadb_handle_ptr p_item,t_load_info_type p_type,HWND p_parent_window,bool p_show_errors);
+ __declspec(deprecated) t_update_info_state update_info(metadb_handle_ptr p_item,file_info & p_info,HWND p_parent_window,bool p_show_errors);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(metadb_io);
+};
+
+//! Implementing this class gives you direct control over which part of file_info gets altered during a tag update uperation. To be used with metadb_io_v2::update_info_async().
+class NOVTABLE file_info_filter : public service_base {
+public:
+ //! Alters specified file_info entry; called as a part of tag update process. Specified file_info has been read from a file, and will be written back.\n
+ //! WARNING: This will be typically called from another thread than main app thread (precisely, from thread created by tag updater). You should copy all relevant data to members of your file_info_filter instance in constructor and reference only member data in apply_filter() implementation.
+ //! @returns True when you have altered file_info and changes need to be written back to the file; false if no changes have been made.
+ virtual bool apply_filter(metadb_handle_ptr p_location,t_filestats p_stats,file_info & p_info) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(file_info_filter,service_base);
+};
+
+//! Advanced interface for passing infos read from files to metadb backend. Use metadb_io_v2::create_hint_list() to instantiate.
+class NOVTABLE metadb_hint_list : public service_base {
+public:
+ //! Adds a hint to the list.
+ //! @param p_location Location of the item the hint applies to.
+ //! @param p_info file_info object describing the item.
+ //! @param p_stats Information about the file containing item the hint applies to.
+ //! @param p_freshflag Set to true if the info has been directly read from the file, false if it comes from another source such as a playlist file.
+ virtual void add_hint(metadb_handle_ptr const & p_location,const file_info & p_info,const t_filestats & p_stats,bool p_freshflag) = 0;
+ //! Reads info from specified info reader instance and adds hints. May throw an exception in case info read has failed.
+ virtual void add_hint_reader(const char * p_path,service_ptr_t<input_info_reader> const & p_reader,abort_callback & p_abort) = 0;
+ //! Call this when you're done working with this metadb_hint_list instance, to apply hints and dispatch callbacks. If you don't call this, all added hints will be ignored.
+ virtual void on_done() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(metadb_hint_list,service_base);
+};
+
+//! New in 0.9.3. Extends metadb_io functionality with nonblocking versions of tag read/write functions, and some other utility features.
+class NOVTABLE metadb_io_v2 : public metadb_io {
+public:
+ enum {
+ //! By default, when some part of requested operation could not be performed for reasons other than user abort, a popup dialog with description of the problem is spawned.\n
+ //! Set this flag to disable error notification.
+ op_flag_no_errors = 1 << 0,
+ //! Set this flag to make the progress dialog not steal focus on creation.
+ op_flag_background = 1 << 1,
+ //! Set this flag to delay the progress dialog becoming visible, so it does not appear at all during short operations. Also implies op_flag_background effect.
+ op_flag_delay_ui = 1 << 2,
+ };
+
+ //! @param p_list List of items to process.
+ //! @param p_op_flags Can be null, or one or more of op_flag_* enum values combined, altering behaviors of the operation.
+ //! @param p_notify Called when the task is completed. Status code is one of t_load_info_state values. Can be null if caller doesn't care.
+ virtual void load_info_async(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,t_load_info_type p_type,HWND p_parent_window,t_uint32 p_op_flags,completion_notify_ptr p_notify) = 0;
+ //! @param p_list List of items to process.
+ //! @param p_op_flags Can be null, or one or more of op_flag_* enum values combined, altering behaviors of the operation.
+ //! @param p_notify Called when the task is completed. Status code is one of t_update_info values. Can be null if caller doesn't care.
+ //! @param p_filter Callback handling actual file_info alterations. Typically used to replace entire meta part of file_info, or to alter something else such as ReplayGain while leaving meta intact.
+ virtual void update_info_async(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,service_ptr_t<file_info_filter> p_filter,HWND p_parent_window,t_uint32 p_op_flags,completion_notify_ptr p_notify) = 0;
+ //! @param p_list List of items to process.
+ //! @param p_op_flags Can be null, or one or more of op_flag_* enum values combined, altering behaviors of the operation.
+ //! @param p_notify Called when the task is completed. Status code is one of t_update_info values. Can be null if caller doesn't care.
+ virtual void rewrite_info_async(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,HWND p_parent_window,t_uint32 p_op_flags,completion_notify_ptr p_notify) = 0;
+ //! @param p_list List of items to process.
+ //! @param p_op_flags Can be null, or one or more of op_flag_* enum values combined, altering behaviors of the operation.
+ //! @param p_notify Called when the task is completed. Status code is one of t_update_info values. Can be null if caller doesn't care.
+ virtual void remove_info_async(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,HWND p_parent_window,t_uint32 p_op_flags,completion_notify_ptr p_notify) = 0;
+
+ //! Creates a metadb_hint_list object.
+ virtual service_ptr_t<metadb_hint_list> create_hint_list() = 0;
+
+ //! @param p_list List of items to process.
+ //! @param p_op_flags Can be null, or one or more of op_flag_* enum values combined, altering behaviors of the operation.
+ //! @param p_notify Called when the task is completed. Status code is one of t_update_info values. Can be null if caller doesn't care.
+ //! @param p_new_info New infos to write to specified items.
+ void update_info_async_simple(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,const pfc::list_base_const_t<const file_info*> & p_new_info, HWND p_parent_window,t_uint32 p_op_flags,completion_notify_ptr p_notify);
+
+ FB2K_MAKE_SERVICE_INTERFACE(metadb_io_v2,metadb_io);
+};
+
+//! Callback service receiving notifications about metadb contents changes.
+class NOVTABLE metadb_io_callback : public service_base {
+public:
+ //! Called when metadb contents change. (Or, one of display hook component requests display update).
+ //! @param p_items_sorted List of items that have been updated. The list is always sorted by pointer value, to allow fast bsearch to test whether specific item has changed.
+ //! @param p_fromhook Set to true when actual contents haven't changed but one of display hooks requested an update.
+ virtual void on_changed_sorted(const pfc::list_base_const_t<metadb_handle_ptr> & p_items_sorted, bool p_fromhook) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(metadb_io_callback);
+};
+
+//! Entrypoint service for metadb_handle related operations.\n
+//! Implemented only by core, do not reimplement.\n
+//! Use static_api_ptr_t template to access it, e.g. static_api_ptr_t<metadb>()->handle_create(myhandle,mylocation);
+class NOVTABLE metadb : public service_base
+{
+public:
+ //! Locks metadb to prevent other threads from modifying it while you're working with some of its contents. Some functions (metadb_handle::get_info_locked(), metadb_handle::get_info_async_locked()) can be called only from inside metadb lock section.
+ virtual void database_lock()=0;
+ //! Unlocks metadb after database_lock(). Some functions (metadb_handle::get_info_locked(), metadb_handle::get_info_async_locked()) can be called only from inside metadb lock section.
+ virtual void database_unlock()=0;
+
+ //! Returns metadb_handle object referencing specified location (attempts to find existing one, creates new one if doesn't exist).
+ //! @param p_out Receives metadb_handle pointer.
+ //! @param p_location Location to create metadb_handle for.
+ virtual void handle_create(metadb_handle_ptr & p_out,const playable_location & p_location)=0;
+
+ void handle_create_replace_path_canonical(metadb_handle_ptr & p_out,const metadb_handle_ptr & p_source,const char * p_new_path);
+ void handle_replace_path_canonical(metadb_handle_ptr & p_out,const char * p_new_path);
+ void handle_create_replace_path(metadb_handle_ptr & p_out,const metadb_handle_ptr & p_source,const char * p_new_path);
+
+ //! Helper function; attempts to retrieve a handle to any known playable location to be used for e.g. titleformatting script preview.\n
+ //! @returns True on success; false on failure (no known playable locations).
+ static bool g_get_random_handle(metadb_handle_ptr & p_out);
+
+ enum {case_sensitive = true};
+ typedef pfc::comparator_strcmp path_comparator;
+
+ inline static int path_compare_ex(const char * p1,unsigned len1,const char * p2,unsigned len2) {return case_sensitive ? pfc::strcmp_ex(p1,len1,p2,len2) : stricmp_utf8_ex(p1,len1,p2,len2);}
+ inline static int path_compare(const char * p1,const char * p2) {return case_sensitive ? strcmp(p1,p2) : stricmp_utf8(p1,p2);}
+ inline static int path_compare_metadb_handle(const metadb_handle_ptr & p1,const metadb_handle_ptr & p2) {return path_compare(p1->get_path(),p2->get_path());}
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(metadb);
+};
+
+
+class in_metadb_sync {
+public:
+ in_metadb_sync() {
+ m_api->database_lock();
+ }
+ ~in_metadb_sync() {
+ m_api->database_unlock();
+ }
+private:
+ static_api_ptr_t<metadb> m_api;
+};
+
+class in_metadb_sync_fromptr {
+public:
+ in_metadb_sync_fromptr(const service_ptr_t<metadb> & p_api) : m_api(p_api) {m_api->database_lock();}
+ ~in_metadb_sync_fromptr() {m_api->database_unlock();}
+private:
+ service_ptr_t<metadb> m_api;
+};
+
+class in_metadb_sync_fromhandle {
+public:
+ in_metadb_sync_fromhandle(const service_ptr_t<metadb_handle> & p_api) : m_api(p_api) {m_api->metadb_lock();}
+ ~in_metadb_sync_fromhandle() {m_api->metadb_unlock();}
+private:
+ service_ptr_t<metadb_handle> m_api;
+};
+
+
+//! Deprecated - use metadb_io_v2::update_info_async w/ file_info_filter whenever possible.
+class __declspec(deprecated("Use metadb_io_v2::update_info_async instead whenever possible.")) file_info_update_helper
+{
+public:
+ file_info_update_helper(const pfc::list_base_const_t<metadb_handle_ptr> & p_data);
+ file_info_update_helper(metadb_handle_ptr p_item);
+
+ bool read_infos(HWND p_parent,bool p_show_errors);
+
+ enum t_write_result
+ {
+ write_ok,
+ write_aborted,
+ write_error
+ };
+ t_write_result write_infos(HWND p_parent,bool p_show_errors);
+
+ t_size get_item_count() const;
+ bool is_item_valid(t_size p_index) const;//returns false where info reading failed
+
+ file_info & get_item(t_size p_index);
+ metadb_handle_ptr get_item_handle(t_size p_index) const;
+
+ void invalidate_item(t_size p_index);
+
+private:
+ metadb_handle_list m_data;
+ pfc::array_t<file_info_impl> m_infos;
+ pfc::array_t<bool> m_mask;
+};
+
+class titleformat_text_out;
+class titleformat_hook_function_params;
+
+
+/*
+ Implementing this service installs a global hook for metadb_handle::format_title field processing. \n
+ This should be implemented only where absolutely necessary, for safety and performance reasons. \n
+ metadb_display_hook methods should NEVER make any other API calls (other than possibly querying information from passed metadb_handle pointer), only read implementation-specific private data and return as soon as possible. Since those are called from metadb_handle::format_title, no assumptions should be made about calling context (threading etc). \n
+ Both methods are called from inside metadb lock, so no additional locking is required to use *_locked metadb_handle methods.
+ See titleformat_hook for more info about methods/parameters. \n
+ If there are multiple metadb_display_hook implementations registered, call order is undefined.
+*/
+
+class metadb_display_hook : public service_base {
+public:
+ virtual bool process_field(metadb_handle * p_handle,titleformat_text_out * p_out,const char * p_name,t_size p_name_length,bool & p_found_flag) = 0;
+ virtual bool process_function(metadb_handle * p_handle,titleformat_text_out * p_out,const char * p_name,t_size p_name_length,titleformat_hook_function_params * p_params,bool & p_found_flag) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(metadb_display_hook);
+};
+
+
+
+
+
+
+
+//! Helper implementation of file_info_filter_impl.
+class file_info_filter_impl : public file_info_filter {
+public:
+ file_info_filter_impl(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,const pfc::list_base_const_t<const file_info*> & p_new_info) {
+ pfc::dynamic_assert(p_list.get_count() == p_new_info.get_count());
+ pfc::array_t<t_size> order;
+ order.set_size(p_list.get_count());
+ order_helper::g_fill(order.get_ptr(),order.get_size());
+ p_list.sort_get_permutation_t(pfc::compare_t<metadb_handle_ptr,metadb_handle_ptr>,order.get_ptr());
+ m_handles.set_count(order.get_size());
+ m_infos.set_size(order.get_size());
+ for(t_size n = 0; n < order.get_size(); n++) {
+ m_handles[n] = p_list[order[n]];
+ m_infos[n] = *p_new_info[order[n]];
+ }
+ }
+
+ bool apply_filter(metadb_handle_ptr p_location,t_filestats p_stats,file_info & p_info) {
+ t_size index;
+ if (m_handles.bsearch_t(pfc::compare_t<metadb_handle_ptr,metadb_handle_ptr>,p_location,index)) {
+ p_info = m_infos[index];
+ return true;
+ } else {
+ return false;
+ }
+ }
+private:
+ metadb_handle_list m_handles;
+ pfc::array_t<file_info_impl> m_infos;
+};
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb_handle.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb_handle.cpp
new file mode 100644
index 0000000..71fd8ae
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb_handle.cpp
@@ -0,0 +1,48 @@
+#include "foobar2000.h"
+
+
+double metadb_handle::get_length()
+{
+ double rv = 0;
+ in_metadb_sync_fromhandle l_sync(this);
+ const file_info * info;
+ if (get_info_locked(info))
+ rv = info->get_length();
+ return rv;
+}
+
+t_filetimestamp metadb_handle::get_filetimestamp()
+{
+ return get_filestats().m_timestamp;
+}
+
+t_filesize metadb_handle::get_filesize()
+{
+ return get_filestats().m_size;
+}
+
+bool metadb_handle::format_title_legacy(titleformat_hook * p_hook,pfc::string_base & p_out,const char * p_spec,titleformat_text_filter * p_filter)
+{
+ service_ptr_t<titleformat_object> script;
+ if (static_api_ptr_t<titleformat_compiler>()->compile(script,p_spec)) {
+ return format_title(p_hook,p_out,script,p_filter);
+ } else {
+ p_out.reset();
+ return false;
+ }
+}
+
+
+
+bool metadb_handle::g_should_reload(const t_filestats & p_old_stats,const t_filestats & p_new_stats,bool p_fresh)
+{
+ if (p_new_stats.m_timestamp == filetimestamp_invalid) return p_fresh;
+ else if (p_fresh) return p_old_stats!= p_new_stats;
+ else return p_old_stats.m_timestamp < p_new_stats.m_timestamp;
+}
+
+bool metadb_handle::should_reload(const t_filestats & p_new_stats, bool p_fresh) const
+{
+ if (!is_info_loaded_async()) return true;
+ else return g_should_reload(get_filestats(),p_new_stats,p_fresh);
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb_handle.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb_handle.h
new file mode 100644
index 0000000..5ab3c2b
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb_handle.h
@@ -0,0 +1,191 @@
+#ifndef _FOOBAR2000_METADB_HANDLE_H_
+#define _FOOBAR2000_METADB_HANDLE_H_
+
+class titleformat_hook;
+class titleformat_text_filter;
+
+//! metadb_handle object represents interface to reference-counted file_info cache entry for specified location.\n
+//! To obtain a metadb_handle to specific location, use metadb::handle_create(). To obtain a list of metadb_handle objects corresponding to specific path (directory, playlist, multitrack file, etc), use relevant playlist_loader static helper methods.\n
+//! metadb_handle is also the most efficient way of passing playable object locations around because it provides fast access to both location and infos, and is reference counted so duplicating it is as fast as possible.\n
+//! To retrieve a path of a file from a metadb_handle, use metadb_handle::get_path() function. Note that metadb_handle is NOT just file path, some formats support multiple subsongs per physical file, which are signaled using subsong indexes.\n
+
+class NOVTABLE metadb_handle : public service_base
+{
+public:
+ //! Retrieves location represented by this metadb_handle object. Returned reference is valid until calling context releases metadb_handle that returned it (metadb_handle_ptr is deallocated etc).
+ virtual const playable_location & get_location() const = 0;//never fails, returned pointer valid till the object is released
+
+
+ //! Renders information about item referenced by this metadb_handle object.
+ //! @param p_hook Optional callback object overriding fields and functions; set to NULL if not used.
+ //! @param p_out String receiving the output on success.
+ //! @param p_script Titleformat script to use. Use titleformat_compiler service to create one.
+ //! @param p_filter Optional callback object allowing input to be filtered according to context (i.e. removal of linebreak characters present in tags when rendering playlist lines). Set to NULL when not used.
+ //! @returns true on success, false when dummy file_info instance was used because actual info is was not (yet) known.
+ virtual bool format_title(titleformat_hook * p_hook,pfc::string_base & p_out,const service_ptr_t<class titleformat_object> & p_script,titleformat_text_filter * p_filter) = 0;
+
+ //! Locks metadb to prevent other threads from modifying it while you're working with some of its contents. Some functions (metadb_handle::get_info_locked(), metadb_handle::get_info_async_locked()) can be called only from inside metadb lock section.
+ //! Same as metadb::database_lock().
+ virtual void metadb_lock() = 0;
+ //! Unlocks metadb after metadb_lock(). Some functions (metadb_handle::get_info_locked(), metadb_handle::get_info_async_locked()) can be called only from inside metadb lock section.
+ //! Same as metadb::database_unlock().
+ virtual void metadb_unlock() = 0;
+
+ //! Returns last seen file stats, filestats_invalid if unknown.
+ virtual t_filestats get_filestats() const = 0;
+
+ //! Queries whether cached info about item referenced by this metadb_handle object is already available.\n
+ //! Note that state of cached info changes only inside main thread, so you can safely assume that it doesn't change while some block of your code inside main thread is being executed.
+ virtual bool is_info_loaded() const = 0;
+ //! Queries cached info about item referenced by this metadb_handle object. Returns true on success, false when info is not yet known.\n
+ //! Note that state of cached info changes only inside main thread, so you can safely assume that it doesn't change while some block of your code inside main thread is being executed.
+ virtual bool get_info(file_info & p_info) const = 0;
+ //! Queries cached info about item referenced by this metadb_handle object. Returns true on success, false when info is not yet known. This is more efficient than get_info() since no data is copied.\n
+ //! You must lock the metadb before calling this function, and unlock it after you are done working with the returned pointer, to ensure multithread safety.\n
+ //! Note that state of cached info changes only inside main thread, so you can safely assume that it doesn't change while some block of your code inside main thread is being executed.
+ //! @param p_info On success, receives a pointer to metadb's file_info object. The pointer is for temporary use only, and becomes invalid when metadb is unlocked.
+ virtual bool get_info_locked(const file_info * & p_info) const = 0;
+
+ //! Queries whether cached info about item referenced by this metadb_handle object is already available.\n
+ //! This is intended for use in special cases when you need to immediately retrieve info sent by metadb_io hint from another thread; state of returned data can be altered by any thread, as opposed to non-async methods.
+ virtual bool is_info_loaded_async() const = 0;
+ //! Queries cached info about item referenced by this metadb_handle object. Returns true on success, false when info is not yet known.\n
+ //! This is intended for use in special cases when you need to immediately retrieve info sent by metadb_io hint from another thread; state of returned data can be altered by any thread, as opposed to non-async methods.
+ virtual bool get_info_async(file_info & p_info) const = 0;
+ //! Queries cached info about item referenced by this metadb_handle object. Returns true on success, false when info is not yet known. This is more efficient than get_info() since no data is copied.\n
+ //! You must lock the metadb before calling this function, and unlock it after you are done working with the returned pointer, to ensure multithread safety.\n
+ //! This is intended for use in special cases when you need to immediately retrieve info sent by metadb_io hint from another thread; state of returned data can be altered by any thread, as opposed to non-async methods.
+ //! @param p_info On success, receives a pointer to metadb's file_info object. The pointer is for temporary use only, and becomes invalid when metadb is unlocked.
+ virtual bool get_info_async_locked(const file_info * & p_info) const = 0;
+
+
+ //! Renders information about item referenced by this metadb_handle object, using external file_info data.
+ virtual void format_title_from_external_info(const file_info & p_info,titleformat_hook * p_hook,pfc::string_base & p_out,const service_ptr_t<class titleformat_object> & p_script,titleformat_text_filter * p_filter)=0;
+
+ static bool g_should_reload(const t_filestats & p_old_stats,const t_filestats & p_new_stats,bool p_fresh);
+ bool should_reload(const t_filestats & p_new_stats,bool p_fresh) const;
+
+
+ //! Helper provided for backwards compatibility; takes formatting script as text string and calls relevant titleformat_compiler methods; returns false when the script could not be compiled.\n
+ //! See format_title() for descriptions of parameters.\n
+ //! Bottleneck warning: you should consider using precompiled titleformat script object and calling regular format_title() instead when processing large numbers of items.
+ bool format_title_legacy(titleformat_hook * p_hook,pfc::string_base & out,const char * p_spec,titleformat_text_filter * p_filter);
+
+ //! Retrieves path of item described by this metadb_handle instance. Returned string is valid until calling context releases metadb_handle that returned it (metadb_handle_ptr is deallocated etc).
+ inline const char * get_path() const {return get_location().get_path();}
+ //! Retrieves subsong index of item described by this metadb_handle instance (used for multiple playable tracks within single physical file).
+ inline t_uint32 get_subsong_index() const {return get_location().get_subsong_index();}
+
+ double get_length();//helper
+
+ t_filetimestamp get_filetimestamp();
+ t_filesize get_filesize();
+
+ FB2K_MAKE_SERVICE_INTERFACE(metadb_handle,service_base);
+};
+
+typedef service_ptr_t<metadb_handle> metadb_handle_ptr;
+
+namespace metadb_handle_list_helper {
+ void sort_by_format_partial(pfc::list_base_t<metadb_handle_ptr> & p_list,t_size base,t_size count,const char * spec,titleformat_hook * p_hook);
+ void sort_by_format_get_order_partial(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,t_size base,t_size count,t_size* order,const char * spec,titleformat_hook * p_hook);
+ void sort_by_format_partial(pfc::list_base_t<metadb_handle_ptr> & p_list,t_size base,t_size count,const service_ptr_t<titleformat_object> & p_script,titleformat_hook * p_hook);
+ void sort_by_format_get_order_partial(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,t_size base,t_size count,t_size* order,const service_ptr_t<titleformat_object> & p_script,titleformat_hook * p_hook);
+
+ void sort_by_relative_path_partial(pfc::list_base_t<metadb_handle_ptr> & p_list,t_size base,t_size count);
+ void sort_by_relative_path_get_order_partial(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,t_size base,t_size count,t_size* order);
+
+ void remove_duplicates(pfc::list_base_t<metadb_handle_ptr> & p_list);
+ void sort_by_pointer_remove_duplicates(pfc::list_base_t<metadb_handle_ptr> & p_list);
+ void sort_by_path_quick(pfc::list_base_t<metadb_handle_ptr> & p_list);
+
+ void sort_by_pointer(pfc::list_base_t<metadb_handle_ptr> & p_list);
+ t_size bsearch_by_pointer(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,const metadb_handle_ptr & val);
+
+ double calc_total_duration(const pfc::list_base_const_t<metadb_handle_ptr> & p_list);
+
+ void sort_by_path(pfc::list_base_t<metadb_handle_ptr> & p_list);
+};
+
+template<template<typename> class t_alloc = pfc::alloc_fast >
+class metadb_handle_list_t : public service_list_t<metadb_handle,t_alloc> {
+private:
+ typedef metadb_handle_list_t<t_alloc> t_self;
+ typedef list_base_const_t<metadb_handle_ptr> t_interface;
+public:
+ inline void sort_by_format(const char * spec,titleformat_hook * p_hook) {return sort_by_format_partial(0,get_count(),spec,p_hook);}
+ inline void sort_by_format_partial(t_size base,t_size count,const char * spec,titleformat_hook * p_hook) {metadb_handle_list_helper::sort_by_format_partial(*this,base,count,spec,p_hook);}
+ inline void sort_by_format_get_order(t_size* order,const char * spec,titleformat_hook * p_hook) const {sort_by_format_get_order_partial(0,get_count(),order,spec,p_hook);}
+ inline void sort_by_format_get_order_partial(t_size base,t_size count,t_size* order,const char * spec,titleformat_hook * p_hook) const {metadb_handle_list_helper::sort_by_format_get_order_partial(*this,base,count,order,spec,p_hook);}
+
+ inline void sort_by_format(const service_ptr_t<titleformat_object> & p_script,titleformat_hook * p_hook) {return sort_by_format_partial(0,get_count(),p_script,p_hook);}
+ inline void sort_by_format_partial(t_size base,t_size count,const service_ptr_t<titleformat_object> & p_script,titleformat_hook * p_hook) {metadb_handle_list_helper::sort_by_format_partial(*this,base,count,p_script,p_hook);}
+ inline void sort_by_format_get_order(t_size* order,const service_ptr_t<titleformat_object> & p_script,titleformat_hook * p_hook) const {sort_by_format_get_order_partial(0,get_count(),order,p_script,p_hook);}
+ inline void sort_by_format_get_order_partial(t_size base,t_size count,t_size* order,const service_ptr_t<titleformat_object> & p_script,titleformat_hook * p_hook) const {metadb_handle_list_helper::sort_by_format_get_order_partial(*this,base,count,order,p_script,p_hook);}
+
+ inline void sort_by_relative_path() {sort_by_relative_path_partial(0,get_count());}
+ inline void sort_by_relative_path_partial(t_size base,t_size count) {metadb_handle_list_helper::sort_by_relative_path_partial(*this,base,count);}
+ inline void sort_by_relative_path_get_order(t_size* order) const {sort_by_relative_path_get_order_partial(0,get_count(),order);}
+ inline void sort_by_relative_path_get_order_partial(t_size base,t_size count,t_size* order) const {metadb_handle_list_helper::sort_by_relative_path_get_order_partial(*this,base,count,order);}
+
+ inline void remove_duplicates() {metadb_handle_list_helper::remove_duplicates(*this);}
+ inline void sort_by_pointer_remove_duplicates() {metadb_handle_list_helper::sort_by_pointer_remove_duplicates(*this);}
+ inline void sort_by_path_quick() {metadb_handle_list_helper::sort_by_path_quick(*this);}
+
+ inline void sort_by_pointer() {metadb_handle_list_helper::sort_by_pointer(*this);}
+ inline t_size bsearch_by_pointer(const metadb_handle_ptr & val) const {return metadb_handle_list_helper::bsearch_by_pointer(*this,val);}
+
+ inline double calc_total_duration() const {return metadb_handle_list_helper::calc_total_duration(*this);}
+
+ inline void sort_by_path() {metadb_handle_list_helper::sort_by_path(*this);}
+
+ const t_self & operator=(const t_self & p_source) {remove_all(); add_items(p_source);return *this;}
+ const t_self & operator=(const t_interface & p_source) {remove_all(); add_items(p_source);return *this;}
+ metadb_handle_list_t(const t_self & p_source) {add_items(p_source);}
+ metadb_handle_list_t(const t_interface & p_source) {add_items(p_source);}
+ metadb_handle_list_t() {}
+
+};
+
+typedef metadb_handle_list_t<> metadb_handle_list;
+
+namespace metadb_handle_list_helper {
+ void sorted_by_pointer_extract_difference(metadb_handle_list const & p_list_1,metadb_handle_list const & p_list_2,metadb_handle_list & p_list_1_specific,metadb_handle_list & p_list_2_specific);
+};
+
+class metadb_handle_lock
+{
+ metadb_handle_ptr m_ptr;
+public:
+ inline metadb_handle_lock(const metadb_handle_ptr & param)
+ {
+ m_ptr = param;
+ m_ptr->metadb_lock();
+ }
+ inline ~metadb_handle_lock() {m_ptr->metadb_unlock();}
+};
+
+inline pfc::string_base & operator<<(pfc::string_base & p_fmt,const metadb_handle_ptr & p_location) {
+ if (p_location.is_valid())
+ return p_fmt << p_location->get_location();
+ else
+ return p_fmt << "[invalid location]";
+}
+
+
+class string_format_title {
+public:
+ string_format_title(metadb_handle_ptr p_item,const char * p_script) {
+ p_item->format_title_legacy(NULL,m_data,p_script,NULL);
+ }
+ string_format_title(metadb_handle_ptr p_item,service_ptr_t<class titleformat_object> p_script) {
+ p_item->format_title(NULL,m_data,p_script,NULL);
+ }
+
+ const char * get_ptr() const {return m_data.get_ptr();}
+ operator const char * () const {return m_data.get_ptr();}
+private:
+ pfc::string8_fastalloc m_data;
+};
+
+#endif //_FOOBAR2000_METADB_HANDLE_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb_handle_list.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb_handle_list.cpp
new file mode 100644
index 0000000..cd595ff
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/metadb_handle_list.cpp
@@ -0,0 +1,264 @@
+#include "foobar2000.h"
+
+
+
+
+namespace {
+ struct custom_sort_data
+ {
+ HANDLE text;
+ //int subsong;
+ t_size index;
+ };
+}
+static int __cdecl custom_sort_compare(const custom_sort_data & elem1, const custom_sort_data & elem2 )
+{//depends on unicode/ansi, nonportable (win32 lstrcmpi)
+ int ret = uSortStringCompare(elem1.text,elem2.text);//uStringCompare
+// if (ret == 0) ret = elem1.subsong - elem2.subsong;
+ if (ret == 0) ret = pfc::sgn_t((t_ssize)elem1.index - (t_ssize)elem2.index);
+ return ret;
+}
+
+void metadb_handle_list_helper::sort_by_format_partial(pfc::list_base_t<metadb_handle_ptr> & p_list,t_size base,t_size count,const char * spec,titleformat_hook * p_hook)
+{
+ service_ptr_t<titleformat_object> script;
+ if (static_api_ptr_t<titleformat_compiler>()->compile(script,spec))
+ sort_by_format_partial(p_list,base,count,script,p_hook);
+}
+
+void metadb_handle_list_helper::sort_by_format_get_order_partial(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,t_size base,t_size count,t_size* order,const char * spec,titleformat_hook * p_hook)
+{
+ service_ptr_t<titleformat_object> script;
+ if (static_api_ptr_t<titleformat_compiler>()->compile(script,spec))
+ sort_by_format_get_order_partial(p_list,base,count,order,script,p_hook);
+}
+
+void metadb_handle_list_helper::sort_by_format_partial(pfc::list_base_t<metadb_handle_ptr> & p_list,t_size base,t_size count,const service_ptr_t<titleformat_object> & p_script,titleformat_hook * p_hook)
+{
+ pfc::array_t<t_size> order; order.set_size(count);
+ sort_by_format_get_order_partial(p_list,base,count,order.get_ptr(),p_script,p_hook);
+ p_list.reorder_partial(base,order.get_ptr(),count);
+}
+
+void metadb_handle_list_helper::sort_by_format_get_order_partial(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,t_size base,t_size count,t_size* order,const service_ptr_t<titleformat_object> & p_script,titleformat_hook * p_hook)
+{
+ assert(base+count<=p_list.get_count());
+ t_size n;
+ pfc::array_t<custom_sort_data> data;
+ data.set_size(count);
+
+ pfc::string8_fastalloc temp;
+ pfc::string8_fastalloc temp2;
+ temp.prealloc(512);
+ for(n=0;n<count;n++)
+ {
+ metadb_handle_ptr item;
+ p_list.get_item_ex(item,base+n);
+ assert(item.is_valid());
+
+ item->format_title(p_hook,temp,p_script,0);
+ data[n].index = n;
+ data[n].text = uSortStringCreate(temp);
+ //data[n].subsong = item->get_subsong_index();
+ }
+
+ pfc::sort_t(data,custom_sort_compare,count);
+ //qsort(data.get_ptr(),count,sizeof(custom_sort_data),(int (__cdecl *)(const void *elem1, const void *elem2 ))custom_sort_compare);
+
+ for(n=0;n<count;n++)
+ {
+ order[n]=data[n].index;
+ uSortStringFree(data[n].text);
+ }
+}
+
+void metadb_handle_list_helper::sort_by_relative_path_partial(pfc::list_base_t<metadb_handle_ptr> & p_list,t_size base,t_size count)
+{
+ assert(base+count<=p_list.get_count());
+ pfc::array_t<t_size> order; order.set_size(count);
+ sort_by_relative_path_get_order_partial(p_list,base,count,order.get_ptr());
+ p_list.reorder_partial(base,order.get_ptr(),count);
+}
+
+void metadb_handle_list_helper::sort_by_relative_path_get_order_partial(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,t_size base,t_size count,t_size* order)
+{
+ assert(base+count<=p_list.get_count());
+ t_size n;
+ pfc::array_t<custom_sort_data> data;
+ data.set_size(count);
+ static_api_ptr_t<library_manager> api;
+
+ pfc::string8_fastalloc temp;
+ temp.prealloc(512);
+ for(n=0;n<count;n++)
+ {
+ metadb_handle_ptr item;
+ p_list.get_item_ex(item,base+n);
+ if (!api->get_relative_path(item,temp)) temp = "";
+ data[n].index = n;
+ data[n].text = uSortStringCreate(temp);
+ //data[n].subsong = item->get_subsong_index();
+ }
+
+ pfc::sort_t(data,custom_sort_compare,count);
+ //qsort(data.get_ptr(),count,sizeof(custom_sort_data),(int (__cdecl *)(const void *elem1, const void *elem2 ))custom_sort_compare);
+
+ for(n=0;n<count;n++)
+ {
+ order[n]=data[n].index;
+ uSortStringFree(data[n].text);
+ }
+}
+
+void metadb_handle_list_helper::remove_duplicates(pfc::list_base_t<metadb_handle_ptr> & p_list)
+{
+ t_size count = p_list.get_count();
+ if (count>0)
+ {
+ bit_array_bittable mask(count);
+ pfc::array_t<t_size> order; order.set_size(count);
+ order_helper::g_fill(order);
+
+ p_list.sort_get_permutation_t(pfc::compare_t<metadb_handle_ptr,metadb_handle_ptr>,order.get_ptr());
+
+ t_size n;
+ bool found = false;
+ for(n=0;n<count-1;n++)
+ {
+ if (p_list.get_item(order[n])==p_list.get_item(order[n+1]))
+ {
+ found = true;
+ mask.set(order[n+1],true);
+ }
+ }
+
+ if (found) p_list.remove_mask(mask);
+ }
+}
+
+void metadb_handle_list_helper::sort_by_pointer_remove_duplicates(pfc::list_base_t<metadb_handle_ptr> & p_list)
+{
+ t_size count = p_list.get_count();
+ if (count>0)
+ {
+ sort_by_pointer(p_list);
+ bool b_found = false;
+ t_size n;
+ for(n=0;n<count-1;n++)
+ {
+ if (p_list.get_item(n)==p_list.get_item(n+1))
+ {
+ b_found = true;
+ break;
+ }
+ }
+
+ if (b_found)
+ {
+ bit_array_bittable mask(count);
+ t_size n;
+ for(n=0;n<count-1;n++)
+ {
+ if (p_list.get_item(n)==p_list.get_item(n+1))
+ mask.set(n+1,true);
+ }
+ p_list.remove_mask(mask);
+ }
+ }
+}
+
+void metadb_handle_list_helper::sort_by_path_quick(pfc::list_base_t<metadb_handle_ptr> & p_list)
+{
+ p_list.sort_t(metadb::path_compare_metadb_handle);
+}
+
+
+void metadb_handle_list_helper::sort_by_pointer(pfc::list_base_t<metadb_handle_ptr> & p_list)
+{
+ //it seems MSVC71 /GL does something highly retarded here
+ //p_list.sort_t(pfc::compare_t<metadb_handle_ptr,metadb_handle_ptr>);
+ p_list.sort();
+}
+
+t_size metadb_handle_list_helper::bsearch_by_pointer(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,const metadb_handle_ptr & val)
+{
+ t_size blah;
+ if (p_list.bsearch_t(pfc::compare_t<metadb_handle_ptr,metadb_handle_ptr>,val,blah)) return blah;
+ else return ~0;
+}
+
+
+void metadb_handle_list_helper::sorted_by_pointer_extract_difference(metadb_handle_list const & p_list_1,metadb_handle_list const & p_list_2,metadb_handle_list & p_list_1_specific,metadb_handle_list & p_list_2_specific)
+{
+ t_size found_1, found_2;
+ const t_size count_1 = p_list_1.get_count(), count_2 = p_list_2.get_count();
+ t_size ptr_1, ptr_2;
+
+ found_1 = found_2 = 0;
+ ptr_1 = ptr_2 = 0;
+ while(ptr_1 < count_1 || ptr_2 < count_2)
+ {
+ while(ptr_1 < count_1 && (ptr_2 == count_2 || p_list_1[ptr_1] < p_list_2[ptr_2]))
+ {
+ found_1++;
+ t_size ptr_1_new = ptr_1 + 1;
+ while(ptr_1_new < count_1 && p_list_1[ptr_1_new] == p_list_1[ptr_1]) ptr_1_new++;
+ ptr_1 = ptr_1_new;
+ }
+ while(ptr_2 < count_2 && (ptr_1 == count_1 || p_list_2[ptr_2] < p_list_1[ptr_1]))
+ {
+ found_2++;
+ t_size ptr_2_new = ptr_2 + 1;
+ while(ptr_2_new < count_2 && p_list_2[ptr_2_new] == p_list_2[ptr_2]) ptr_2_new++;
+ ptr_2 = ptr_2_new;
+ }
+ while(ptr_1 < count_1 && ptr_2 < count_2 && p_list_1[ptr_1] == p_list_2[ptr_2]) {ptr_1++; ptr_2++;}
+ }
+
+
+
+ p_list_1_specific.set_count(found_1);
+ p_list_2_specific.set_count(found_2);
+ if (found_1 > 0 || found_2 > 0)
+ {
+ found_1 = found_2 = 0;
+ ptr_1 = ptr_2 = 0;
+
+ while(ptr_1 < count_1 || ptr_2 < count_2)
+ {
+ while(ptr_1 < count_1 && (ptr_2 == count_2 || p_list_1[ptr_1] < p_list_2[ptr_2]))
+ {
+ p_list_1_specific[found_1++] = p_list_1[ptr_1];
+ t_size ptr_1_new = ptr_1 + 1;
+ while(ptr_1_new < count_1 && p_list_1[ptr_1_new] == p_list_1[ptr_1]) ptr_1_new++;
+ ptr_1 = ptr_1_new;
+ }
+ while(ptr_2 < count_2 && (ptr_1 == count_1 || p_list_2[ptr_2] < p_list_1[ptr_1]))
+ {
+ p_list_2_specific[found_2++] = p_list_2[ptr_2];
+ t_size ptr_2_new = ptr_2 + 1;
+ while(ptr_2_new < count_2 && p_list_2[ptr_2_new] == p_list_2[ptr_2]) ptr_2_new++;
+ ptr_2 = ptr_2_new;
+ }
+ while(ptr_1 < count_1 && ptr_2 < count_2 && p_list_1[ptr_1] == p_list_2[ptr_2]) {ptr_1++; ptr_2++;}
+ }
+
+ }
+}
+
+double metadb_handle_list_helper::calc_total_duration(const pfc::list_base_const_t<metadb_handle_ptr> & p_list)
+{
+ double ret = 0;
+ t_size n, m = p_list.get_count();
+ for(n=0;n<m;n++)
+ {
+ double temp = p_list.get_item(n)->get_length();
+ if (temp > 0) ret += temp;
+ }
+ return ret;
+}
+
+void metadb_handle_list_helper::sort_by_path(pfc::list_base_t<metadb_handle_ptr> & p_list)
+{
+ sort_by_format_partial(p_list,0,p_list.get_count(),"%path_sort%",0);
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/modeless_dialog.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/modeless_dialog.cpp
new file mode 100644
index 0000000..66edccb
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/modeless_dialog.cpp
@@ -0,0 +1,19 @@
+#include "foobar2000.h"
+
+void modeless_dialog_manager::g_add(HWND p_wnd)
+{
+ service_enum_t<modeless_dialog_manager> e;
+ service_ptr_t<modeless_dialog_manager> ptr;
+ if (e.first(ptr)) do {
+ ptr->add(p_wnd);
+ } while(e.next(ptr));
+}
+
+void modeless_dialog_manager::g_remove(HWND p_wnd)
+{
+ service_enum_t<modeless_dialog_manager> e;
+ service_ptr_t<modeless_dialog_manager> ptr;
+ if (e.first(ptr)) do {
+ ptr->remove(p_wnd);
+ } while(e.next(ptr));
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/modeless_dialog.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/modeless_dialog.h
new file mode 100644
index 0000000..1f6c9ad
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/modeless_dialog.h
@@ -0,0 +1,24 @@
+#ifndef _MODELESS_DIALOG_H_
+#define _MODELESS_DIALOG_H_
+
+
+//! Service for plugging your nonmodal dialog windows into main app loop to receive IsDialogMessage()-translated messages.\n
+//! Note that all methods are valid from main app thread only.\n
+//! Usage: static_api_ptr_t<modeless_dialog_manager> or modeless_dialog_manager::g_add / modeless_dialog_manager::g_remove.
+class NOVTABLE modeless_dialog_manager : public service_base
+{
+public:
+ //! Adds specified window to global list of windows to receive IsDialogMessage().
+ virtual void add(HWND p_wnd) = 0;
+ //! Removes specified window from global list of windows to receive IsDialogMessage().
+ virtual void remove(HWND p_wnd) = 0;
+
+ //! Static helper; see add().
+ static void g_add(HWND p_wnd);
+ //! Static helper; see remove().
+ static void g_remove(HWND p_wnd);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(modeless_dialog_manager);
+};
+
+#endif //_MODELESS_DIALOG_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/packet_decoder.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/packet_decoder.cpp
new file mode 100644
index 0000000..abef1bc
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/packet_decoder.cpp
@@ -0,0 +1,14 @@
+#include "foobar2000.h"
+
+void packet_decoder::g_open(service_ptr_t<packet_decoder> & p_out,bool p_decode,const GUID & p_owner,t_size p_param1,const void * p_param2,t_size p_param2size,abort_callback & p_abort)
+{
+ service_enum_t<packet_decoder_entry> e;
+ service_ptr_t<packet_decoder_entry> ptr;
+ while(e.next(ptr)) {
+ if (ptr->is_our_setup(p_owner,p_param1,p_param2,p_param2size)) {
+ ptr->open(p_out,p_decode,p_owner,p_param1,p_param2,p_param2size,p_abort);
+ return;
+ }
+ }
+ throw exception_io_data();
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/packet_decoder.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/packet_decoder.h
new file mode 100644
index 0000000..7527707
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/packet_decoder.h
@@ -0,0 +1,113 @@
+//! Provides interface to decode various audio data types to PCM. Use packet_decoder_factory_t template to register.
+
+class packet_decoder : public service_base {
+protected:
+ //! Prototype of function that must be implemented by packet_decoder implementation but is not accessible through packet_decoder interface itself.
+ //! Determines whether specific packet_decoder implementation supports specified decoder setup data.
+ static bool g_is_our_setup(const GUID & p_owner,t_size p_param1,const void * p_param2,t_size p_param2size) {return false;}
+
+ //! Prototype of function that must be implemented by packet_decoder implementation but is not accessible through packet_decoder interface itself.
+ //! Initializes packet decoder instance with specified decoder setup data. This is called only once, before any other methods.
+ //! @param p_decode If set to true, decode() and reset_after_seek() calls can be expected later. If set to false, those methods will not be called on this packet_decoder instance - for an example when caller is only retrieving information about the file rather than preparing to decode it.
+ void open(const GUID & p_owner,bool p_decode,t_size p_param1,const void * p_param2,t_size p_param2size,abort_callback & p_abort) {throw exception_io_data();}
+public:
+
+
+ //! Forwards additional information about stream being decoded. \n
+ //! Calling: this must be called immediately after packet_decoder object is created, before any other methods are called.\n
+ //! Implementation: this is called after open() (which is called by implementation framework immediately after creation), and before any other methods are called.
+ virtual t_size set_stream_property(const GUID & p_type,t_size p_param1,const void * p_param2,t_size p_param2size) = 0;
+
+
+ //! Retrieves additional user-readable tech infos that decoder can provide.
+ //! @param p_info Interface receiving information about the stream being decoded. Note that it already contains partial info about the file; existing info should not be erased, decoder-provided info should be merged with it.
+ virtual void get_info(file_info & p_info) = 0;
+
+ //! Returns many frames back to start decoding when seeking.
+ virtual unsigned get_max_frame_dependency()=0;
+ //! Returns much time back to start decoding when seeking (for containers where going back by specified number of frames is not trivial).
+ virtual double get_max_frame_dependency_time()=0;
+
+ //! Flushes decoder after seeking.
+ virtual void reset_after_seek()=0;
+
+ //! Decodes a block of audio data.\n
+ //! It may return empty chunk even when successful (caused by encoder+decoder delay for an example), caller must check for it and handle it appropriately.
+ virtual void decode(const void * p_buffer,t_size p_bytes,audio_chunk & p_chunk,abort_callback & p_abort)=0;
+
+ //! Returns whether this packet decoder supports analyze_first_frame() function.
+ virtual bool analyze_first_frame_supported() = 0;
+ //! Optional. Some codecs need to analyze first frame of the stream to return additional info about the stream, such as encoding setup. This can be only called immediately after instantiation (and set_stream_property() if present), before any actual decoding or get_info(). Caller can determine whether this method is supported or not by calling analyze_first_frame_supported(), to avoid reading first frame when decoder won't utiilize the extra info for an example. If particular decoder can't utilize first frame info in any way (and analyze_first_frame_supported() returns false), this function should do nothing and succeed.
+ virtual void analyze_first_frame(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) = 0;
+
+ //! Static helper, creates a packet_decoder instance and initializes it with specific decoder setup data.
+ static void g_open(service_ptr_t<packet_decoder> & p_out,bool p_decode,const GUID & p_owner,t_size p_param1,const void * p_param2,t_size p_param2size,abort_callback & p_abort);
+
+ static const GUID owner_MP4,owner_matroska,owner_MP3,owner_MP2,owner_MP1,owner_MP4_ALAC,owner_ADTS,owner_ADIF, owner_Ogg, owner_MP4_AMR, owner_MP4_AMR_WB;
+
+ struct matroska_setup
+ {
+ const char * codec_id;
+ unsigned sample_rate,sample_rate_output;
+ unsigned channels;
+ unsigned codec_private_size;
+ const void * codec_private;
+ };
+ //owner_MP4: param1 - codec ID (MP4 audio type), param2 - MP4 codec initialization data
+ //owner_MP3: raw MP3/MP2 file, parameters ignored
+ //owner_matroska: param2 = matroska_setup struct, param2size size must be equal to sizeof(matroska_setup)
+
+
+ //these are used to initialize PCM decoder
+ static const GUID property_samplerate,property_bitspersample,property_channels,property_byteorder,property_signed,property_channelmask;
+ //property_samplerate : param1 == sample rate in hz
+ //property_bitspersample : param1 == bits per sample
+ //property_channels : param1 == channel count
+ //property_byteorder : if (param1) little_endian; else big_endian;
+ //property_signed : if (param1) signed; else unsigned;
+
+
+ //property_ogg_header : p_param1 = unused, p_param2 = ogg_packet structure, retval: 0 when more headers are wanted, 1 when done parsing headers
+ //property_ogg_query_sample_rate : returns sample rate, no parameters
+ //property_ogg_packet : p_param1 = unused, p_param2 = ogg_packet strucute
+ static const GUID property_ogg_header, property_ogg_query_sample_rate, property_ogg_packet;
+
+ FB2K_MAKE_SERVICE_INTERFACE(packet_decoder,service_base);
+};
+
+class packet_decoder_streamparse : public packet_decoder
+{
+public:
+ virtual void decode_ex(const void * p_buffer,t_size p_bytes,t_size & p_bytes_processed,audio_chunk & p_chunk,abort_callback & p_abort) = 0;
+ virtual void analyze_first_frame_ex(const void * p_buffer,t_size p_bytes,t_size & p_bytes_processed,abort_callback & p_abort) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(packet_decoder_streamparse,packet_decoder);
+};
+
+class packet_decoder_entry : public service_base
+{
+public:
+ virtual bool is_our_setup(const GUID & p_owner,t_size p_param1,const void * p_param2,t_size p_param2size) = 0;
+ virtual void open(service_ptr_t<packet_decoder> & p_out,bool p_decode,const GUID & p_owner,t_size p_param1,const void * p_param2,t_size p_param2size,abort_callback & p_abort) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(packet_decoder_entry);
+};
+
+
+template<class T>
+class packet_decoder_entry_impl_t : public packet_decoder_entry
+{
+public:
+ bool is_our_setup(const GUID & p_owner,t_size p_param1,const void * p_param2,t_size p_param2size) {
+ return T::g_is_our_setup(p_owner,p_param1,p_param2,p_param2size);
+ }
+ void open(service_ptr_t<packet_decoder> & p_out,bool p_decode,const GUID & p_owner,t_size p_param1,const void * p_param2,t_size p_param2size,abort_callback & p_abort) {
+ assert(is_our_setup(p_owner,p_param1,p_param2,p_param2size));
+ service_ptr_t<T> instance = new service_impl_t<T>();
+ instance->open(p_owner,p_decode,p_param1,p_param2,p_param2size,p_abort);
+ p_out = instance.get_ptr();
+ }
+};
+
+template<typename T>
+class packet_decoder_factory_t : public service_factory_single_t<packet_decoder_entry_impl_t<T> > {}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/play_callback.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/play_callback.h
new file mode 100644
index 0000000..f98b1d7
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/play_callback.h
@@ -0,0 +1,96 @@
+#ifndef _PLAY_CALLBACK_H_
+#define _PLAY_CALLBACK_H_
+
+/*!
+Class receiving notifications about playback events. Note that all methods are called only from app's main thread.
+Use play_callback_manager to register your dynamically created instances. Statically registered version is available too - see play_callback_static.
+*/
+class NOVTABLE play_callback {
+public:
+ //! Playback process is being initialized. on_playback_new_track() should be called soon after this when first file is successfully opened for decoding.
+ virtual void FB2KAPI on_playback_starting(play_control::t_track_command p_command,bool p_paused)=0;
+ //! Playback advanced to new track.
+ virtual void FB2KAPI on_playback_new_track(metadb_handle_ptr p_track) = 0;
+ //! Playback stopped.
+ virtual void FB2KAPI on_playback_stop(play_control::t_stop_reason p_reason)=0;
+ //! User has seeked to specific time.
+ virtual void FB2KAPI on_playback_seek(double p_time)=0;
+ //! Called on pause/unpause.
+ virtual void FB2KAPI on_playback_pause(bool p_state)=0;
+ //! Called when currently played file gets edited.
+ virtual void FB2KAPI on_playback_edited(metadb_handle_ptr p_track) = 0;
+ //! Dynamic info (VBR bitrate etc) change.
+ virtual void FB2KAPI on_playback_dynamic_info(const file_info & p_info) = 0;
+ //! Per-track dynamic info (stream track titles etc) change. Happens less often than on_playback_dynamic_info().
+ virtual void FB2KAPI on_playback_dynamic_info_track(const file_info & p_info) = 0;
+ //! Called every second, for time display
+ virtual void FB2KAPI on_playback_time(double p_time) = 0;
+ //! User changed volume settings. Possibly called when not playing.
+ //! @param p_new_val new volume level in dB; 0 for full volume.
+ virtual void FB2KAPI on_volume_change(float p_new_val) = 0;
+
+ enum {
+ flag_on_playback_starting = 1 << 0,
+ flag_on_playback_new_track = 1 << 1,
+ flag_on_playback_stop = 1 << 2,
+ flag_on_playback_seek = 1 << 3,
+ flag_on_playback_pause = 1 << 4,
+ flag_on_playback_edited = 1 << 5,
+ flag_on_playback_dynamic_info = 1 << 6,
+ flag_on_playback_dynamic_info_track = 1 << 7,
+ flag_on_playback_time = 1 << 8,
+ flag_on_volume_change = 1 << 9,
+
+ flag_on_playback_all = flag_on_playback_starting | flag_on_playback_new_track |
+ flag_on_playback_stop | flag_on_playback_seek |
+ flag_on_playback_pause | flag_on_playback_edited |
+ flag_on_playback_dynamic_info | flag_on_playback_dynamic_info_track | flag_on_playback_time,
+ };
+protected:
+ play_callback() {}
+ ~play_callback() {}
+};
+
+//! Standard API (always present); manages registrations of dynamic play_callbacks.
+//! Usage: use static_api_ptr_t<play_callback_manager>.
+//! Do not reimplement.
+class NOVTABLE play_callback_manager : public service_base
+{
+public:
+ //! Registers a play_callback object.
+ //! @param p_callback Interface to register.
+ //! @param p_flags Indicates which notifications are requested.
+ virtual void FB2KAPI register_callback(play_callback * p_callback,unsigned p_flags,bool p_forward_status_on_register) = 0;
+ //! Unregisters a play_callback object.
+ //! @p_callback Previously registered interface to unregister.
+ virtual void FB2KAPI unregister_callback(play_callback * p_callback) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(play_callback_manager);
+};
+
+
+//! Static (autoregistered) version of play_callback. Use play_callback_static_factory_t to register.
+class play_callback_static : public service_base, public play_callback {
+public:
+ //! Controls which methods your callback wants called; returned value should not change in run time, you should expect it to be queried only once (on startup). See play_callback::flag_* constants.
+ virtual unsigned get_flags() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(play_callback_static);
+};
+
+template<typename T>
+class play_callback_static_factory_t : public service_factory_single_t<T> {};
+
+
+//! Gets notified about tracks being played. Notification occurs when at least 60s of the track has been played, or the track has reached its end after at least 1/3 of it has been played through.
+//! Use playback_statistics_collector_factory_t to register.
+class NOVTABLE playback_statistics_collector : public service_base {
+public:
+ virtual void on_item_played(metadb_handle_ptr p_item) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(playback_statistics_collector);
+};
+
+template<typename T>
+class playback_statistics_collector_factory_t : public service_factory_single_t<T> {};
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playable_location.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playable_location.cpp
new file mode 100644
index 0000000..416c169
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playable_location.cpp
@@ -0,0 +1,23 @@
+#include "foobar2000.h"
+
+int playable_location::g_compare(const playable_location & p_item1,const playable_location & p_item2) {
+ int ret = metadb::path_compare(p_item1.get_path(),p_item2.get_path());
+ if (ret != 0) return 0;
+ return pfc::compare_t(p_item1.get_subsong(),p_item2.get_subsong());
+}
+
+pfc::string_base & operator<<(pfc::string_base & p_fmt,const playable_location & p_location)
+{
+ p_fmt << "\"" << file_path_display(p_location.get_path()) << "\"";
+ t_uint32 index = p_location.get_subsong_index();
+ if (index != 0) p_fmt << " / index: " << p_location.get_subsong_index();
+ return p_fmt;
+}
+
+
+bool playable_location::operator==(const playable_location & p_other) const {
+ return metadb::path_compare(get_path(),p_other.get_path()) == 0 && get_subsong() == p_other.get_subsong();
+}
+bool playable_location::operator!=(const playable_location & p_other) const {
+ return !(*this == p_other);
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playable_location.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playable_location.h
new file mode 100644
index 0000000..ac7b732
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playable_location.h
@@ -0,0 +1,87 @@
+#ifndef _FOOBAR2000_PLAYABLE_LOCATION_H_
+#define _FOOBAR2000_PLAYABLE_LOCATION_H_
+
+#include "service.h"
+
+//playable_location stores location of a playable resource, currently implemented as file path and integer for indicating multiple playable "subsongs" per file
+//also see: file_info.h
+//for getting more info about resource referenced by a playable_location, see metadb.h
+
+//char* strings are all UTF-8
+
+class NOVTABLE playable_location//interface (for passing around between DLLs)
+{
+public:
+ virtual const char * get_path() const =0;
+ virtual void set_path(const char*)=0;
+ virtual t_uint32 get_subsong() const =0;
+ virtual void set_subsong(t_uint32)=0;
+
+ void copy(const playable_location & p_other) {
+ set_path(p_other.get_path());
+ set_subsong(p_other.get_subsong());
+ }
+
+ static int g_compare(const playable_location & p_item1,const playable_location & p_item2);
+
+ const playable_location & operator=(const playable_location & src) {copy(src);return *this;}
+
+ bool operator==(const playable_location & p_other) const;
+ bool operator!=(const playable_location & p_other) const;
+
+ inline bool is_empty() {return get_path()[0]==0 && get_subsong()==0;}
+ inline void reset() {set_path("");set_subsong(0);}
+ inline t_uint32 get_subsong_index() const {return get_subsong();}
+ inline void set_subsong_index(t_uint32 v) {set_subsong(v);}
+
+protected:
+ playable_location() {}
+ ~playable_location() {}
+};
+
+typedef playable_location * pplayable_location;
+typedef playable_location const * pcplayable_location;
+typedef playable_location & rplayable_location;
+typedef playable_location const & rcplayable_location;
+
+class playable_location_impl : public playable_location//implementation
+{
+public:
+ const char * get_path() const {return m_path;}
+ void set_path(const char* p_path) {m_path=p_path;}
+ t_uint32 get_subsong() const {return m_subsong;}
+ void set_subsong(t_uint32 p_subsong) {m_subsong=p_subsong;}
+
+ const playable_location_impl & operator=(const playable_location & src) {copy(src);return *this;}
+ const playable_location_impl & operator=(const playable_location_impl & src) {copy(src);return *this;}
+
+ playable_location_impl() : m_subsong(0) {}
+ playable_location_impl(const char * p_path,t_uint32 p_subsong) : m_path(p_path), m_subsong(p_subsong) {}
+ playable_location_impl(const playable_location & src) {copy(src);}
+ playable_location_impl(const playable_location_impl & src) {copy(src);}
+
+private:
+ pfc::string_simple m_path;
+ t_uint32 m_subsong;
+};
+
+// usage: something( make_playable_location("file://c:\blah.ogg",0) );
+// only for use as a parameter to a function taking const playable_location &
+class make_playable_location : public playable_location
+{
+ const char * path;
+ t_uint32 num;
+
+ void set_path(const char*) {throw pfc::exception_not_implemented();}
+ void set_subsong(t_uint32) {throw pfc::exception_not_implemented();}
+
+public:
+ const char * get_path() const {return path;}
+ t_uint32 get_subsong() const {return num;}
+
+ make_playable_location(const char * p_path,t_uint32 p_num) : path(p_path), num(p_num) {}
+};
+
+pfc::string_base & operator<<(pfc::string_base & p_fmt,const playable_location & p_location);
+
+#endif //_FOOBAR2000_PLAYABLE_LOCATION_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playback_control.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playback_control.cpp
new file mode 100644
index 0000000..bf9c47b
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playback_control.cpp
@@ -0,0 +1,13 @@
+#include "foobar2000.h"
+
+
+double playback_control::playback_get_length()
+{
+ double rv = 0;
+ metadb_handle_ptr ptr;
+ if (get_now_playing(ptr))
+ {
+ rv = ptr->get_length();
+ }
+ return rv;
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playback_control.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playback_control.h
new file mode 100644
index 0000000..cedc0c7
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playback_control.h
@@ -0,0 +1,140 @@
+#ifndef _PLAY_CONTROL_H_
+#define _PLAY_CONTROL_H_
+
+//! Provides control for various playback-related operations.
+//! All methods provided by this interface work from main app thread only. Calling from another thread will do nothing or trigger an exception. If you need to trigger one of playback_control methods from another thread, see main_thread_callback.
+//! Do not call playback_control methods from inside any kind of global callback (e.g. playlist callback), otherwise race conditions may occur.
+//! Use static_api_ptr_t to instantiate. See static_api_ptr_t documentation for more info.
+class NOVTABLE playback_control : public service_base
+{
+public:
+
+ enum t_stop_reason {
+ stop_reason_user = 0,
+ stop_reason_eof,
+ stop_reason_starting_another,
+ stop_reason_shutting_down,
+ };
+
+
+ enum t_track_command {
+ track_command_default = 0,
+ track_command_play,
+ track_command_next,
+ track_command_prev,
+ track_command_settrack,
+ track_command_rand,
+ track_command_resume,
+ };
+
+ //! Retrieves now playing item handle.
+ //! @returns true on success, false on failure (not playing).
+ virtual bool get_now_playing(metadb_handle_ptr & p_out) = 0;
+ //! Starts playback. If playback is already active, existing process is stopped first.
+ //! @param p_command Specifies what track to start playback from. See t_track_Command enum for more info.
+ //! @param p_paused Specifies whether playback should be started as paused.
+ virtual void start(t_track_command p_command = track_command_play,bool p_paused = false) = 0;
+ //! Stops playback.
+ virtual void stop() = 0;
+ //! Returns whether playback is active.
+ virtual bool is_playing() = 0;
+ //! Returns whether playback is active and in paused state.
+ virtual bool is_paused() = 0;
+ //! Toggles pause state if playback is active.
+ //! @param p_state set to true when pausing or to false when unpausing.
+ virtual void pause(bool p_state) = 0;
+
+ //! Retrieves stop-after-current-track option state.
+ virtual bool get_stop_after_current() = 0;
+ //! Alters stop-after-current-track option state.
+ virtual void set_stop_after_current(bool p_state) = 0;
+
+ //! Alters playback volume level.
+ //! @param p_value volume in dB; 0 for full volume.
+ virtual void set_volume(float p_value) = 0;
+ //! Retrieves playback volume level.
+ //! @returns current playback volume level, in dB; 0 for full volume.
+ virtual float get_volume() = 0;
+ //! Alters playback volume level one step up.
+ virtual void volume_up() = 0;
+ //! Alters playback volume level one step down.
+ virtual void volume_down() = 0;
+ //! Toggles playback mute state.
+ virtual void volume_mute_toggle() = 0;
+ //! Seeks in currenly played track to specified time.
+ //! @param p_time target time in seconds.
+ virtual void playback_seek(double p_time) = 0;
+ //! Seeks in currently played track by specified time forward or back.
+ //! @param p_delta time in seconds to seek by; can be positive to seek forward or negative to seek back.
+ virtual void playback_seek_delta(double p_delta) = 0;
+ //! Returns whether currently played track is seekable. If it's not, playback_seek/playback_seek_delta calls will be ignored.
+ virtual bool playback_can_seek() = 0;
+ //! Returns current playback position within currently played track, in seconds.
+ virtual double playback_get_position() = 0;
+
+ //! Type used to indicate level of dynamic playback-related info displayed. Safe to use with <> opereators, e.g. level above N always includes information rendered by level N.
+ enum t_display_level {
+ //! No playback-related info
+ display_level_none,
+ //! Static info and is_playing/is_paused stats
+ display_level_basic,
+ //! Display_level_static + dynamic track titles on e.g. live streams
+ display_level_titles,
+ //! Display_level_titles + timing + VBR bitrate display etc
+ display_level_all,
+ };
+
+ //! Renders information about currently playing item.
+ //! @param p_hook Optional callback object overriding fields and functions; set to NULL if not used.
+ //! @param p_out String receiving the output on success.
+ //! @param p_script Titleformat script to use. Use titleformat_compiler service to create one.
+ //! @param p_filter Optional callback object allowing input to be filtered according to context (i.e. removal of linebreak characters present in tags when rendering playlist lines). Set to NULL when not used.
+ //! @param p_level Indicates level of dynamic playback-related info displayed. See t_display_level enum for more details.
+ //! @returns true on success, false when no item is currently being played.
+ virtual bool playback_format_title(titleformat_hook * p_hook,pfc::string_base & p_out,const service_ptr_t<class titleformat_object> & p_script,titleformat_text_filter * p_filter,t_display_level p_level) = 0;
+
+
+
+ //! Helper; renders info about any item, including currently playing item info if the item is currently played.
+ bool playback_format_title_ex(metadb_handle_ptr p_item,titleformat_hook * p_hook,pfc::string_base & p_out,const service_ptr_t<class titleformat_object> & p_script,titleformat_text_filter * p_filter,t_display_level p_level) {
+ if (p_item.is_empty()) return playback_format_title(p_hook,p_out,p_script,p_filter,p_level);
+ metadb_handle_ptr temp;
+ if (get_now_playing(temp)) {
+ if (temp == p_item) {
+ return playback_format_title(p_hook,p_out,p_script,p_filter,p_level);
+ }
+ }
+ p_item->format_title(p_hook,p_out,p_script,p_filter);
+ return true;
+ }
+
+ //! Helper; retrieves length of currently playing item.
+ double playback_get_length();
+
+ //! Toggles stop-after-current state.
+ void toggle_stop_after_current() {set_stop_after_current(!get_stop_after_current());}
+ //! Toggles pause state.
+ void toggle_pause() {pause(!is_paused());}
+
+ //! Starts playback if playback is inactive, otherwise toggles pause.
+ void play_or_pause() {if (is_playing()) toggle_pause(); else start();}
+
+ //deprecated
+ inline void play_start(t_track_command p_command = track_command_play,bool p_paused = false) {start(p_command,p_paused);}
+ //deprecated
+ inline void play_stop() {stop();}
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(playback_control);
+};
+
+class playback_control_v2 : public playback_control {
+public:
+ virtual float get_volume_step() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(playback_control_v2,playback_control);
+};
+
+//for compatibility with old code
+typedef playback_control play_control;
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist.cpp
new file mode 100644
index 0000000..e49a9a7
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist.cpp
@@ -0,0 +1,699 @@
+#include "foobar2000.h"
+
+
+namespace {
+ class enum_items_callback_retrieve_item : public playlist_manager::enum_items_callback
+ {
+ metadb_handle_ptr m_item;
+ public:
+ enum_items_callback_retrieve_item() : m_item(0) {}
+ bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
+ {
+ assert(m_item.is_empty());
+ m_item = p_location;
+ return false;
+ }
+ inline const metadb_handle_ptr & get_item() {return m_item;}
+ };
+
+ class enum_items_callback_retrieve_selection : public playlist_manager::enum_items_callback
+ {
+ bool m_state;
+ public:
+ enum_items_callback_retrieve_selection() : m_state(false) {}
+ bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
+ {
+ m_state = b_selected;
+ return false;
+ }
+ inline bool get_state() {return m_state;}
+ };
+
+ class enum_items_callback_retrieve_selection_mask : public playlist_manager::enum_items_callback
+ {
+ bit_array_var & m_out;
+ public:
+ enum_items_callback_retrieve_selection_mask(bit_array_var & p_out) : m_out(p_out) {}
+ bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
+ {
+ m_out.set(p_index,b_selected);
+ return true;
+ }
+ };
+
+ class enum_items_callback_retrieve_all_items : public playlist_manager::enum_items_callback
+ {
+ pfc::list_base_t<metadb_handle_ptr> & m_out;
+ public:
+ enum_items_callback_retrieve_all_items(pfc::list_base_t<metadb_handle_ptr> & p_out) : m_out(p_out) {m_out.remove_all();}
+ bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
+ {
+ m_out.add_item(p_location);
+ return true;
+ }
+ };
+
+ class enum_items_callback_retrieve_selected_items : public playlist_manager::enum_items_callback
+ {
+ pfc::list_base_t<metadb_handle_ptr> & m_out;
+ public:
+ enum_items_callback_retrieve_selected_items(pfc::list_base_t<metadb_handle_ptr> & p_out) : m_out(p_out) {}
+ bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
+ {
+ if (b_selected) m_out.add_item(p_location);
+ return true;
+ }
+ };
+
+ class enum_items_callback_count_selection : public playlist_manager::enum_items_callback
+ {
+ t_size m_counter,m_max;
+ public:
+ enum_items_callback_count_selection(t_size p_max) : m_max(p_max), m_counter(0) {}
+ bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
+ {
+ if (b_selected)
+ {
+ if (++m_counter >= m_max) return false;
+ }
+ return true;
+ }
+
+ inline t_size get_count() {return m_counter;}
+ };
+
+}
+
+void playlist_manager::playlist_get_all_items(t_size p_playlist,pfc::list_base_t<metadb_handle_ptr> & out)
+{
+ playlist_get_items(p_playlist,out,bit_array_true());
+}
+
+void playlist_manager::playlist_get_selected_items(t_size p_playlist,pfc::list_base_t<metadb_handle_ptr> & out)
+{
+ playlist_enum_items(p_playlist,enum_items_callback_retrieve_selected_items(out),bit_array_true());
+}
+
+void playlist_manager::playlist_get_selection_mask(t_size p_playlist,bit_array_var & out)
+{
+ playlist_enum_items(p_playlist,enum_items_callback_retrieve_selection_mask(out),bit_array_true());
+}
+
+bool playlist_manager::playlist_is_item_selected(t_size p_playlist,t_size p_item)
+{
+ enum_items_callback_retrieve_selection callback;
+ playlist_enum_items(p_playlist,callback,bit_array_one(p_item));
+ return callback.get_state();
+}
+
+bool playlist_manager::playlist_get_item_handle(metadb_handle_ptr & p_out,t_size p_playlist,t_size p_item)
+{
+ enum_items_callback_retrieve_item callback;
+ playlist_enum_items(p_playlist,callback,bit_array_one(p_item));
+ p_out = callback.get_item();
+ return p_out.is_valid();
+}
+
+bool playlist_manager::playlist_move_selection(t_size p_playlist,int p_delta)
+{
+ if (p_delta==0) return true;
+
+ t_size count = playlist_get_item_count(p_playlist);
+
+ pfc::array_t<t_size> order; order.set_size(count);
+ pfc::array_t<bool> selection; selection.set_size(count);
+
+ {
+ t_size n;
+ for(n=0;n<count;n++) order[n]=n;
+ }
+
+ playlist_get_selection_mask(p_playlist,bit_array_var_table(selection.get_ptr(),selection.get_size()));
+
+ if (p_delta<0)
+ {
+ for(;p_delta<0;p_delta++)
+ {
+ t_size idx;
+ for(idx=1;idx<count;idx++)
+ {
+ if (selection[idx] && !selection[idx-1])
+ {
+ pfc::swap_t(order[idx],order[idx-1]);
+ pfc::swap_t(selection[idx],selection[idx-1]);
+ }
+ }
+ }
+ }
+ else
+ {
+ for(;p_delta>0;p_delta--)
+ {
+ t_size idx;
+ for(idx=count-2;(int)idx>=0;idx--)
+ {
+ if (selection[idx] && !selection[idx+1])
+ {
+ pfc::swap_t(order[idx],order[idx+1]);
+ pfc::swap_t(selection[idx],selection[idx+1]);
+ }
+ }
+ }
+ }
+
+ return playlist_reorder_items(p_playlist,order.get_ptr(),count);
+}
+
+//retrieving status
+t_size playlist_manager::activeplaylist_get_item_count()
+{
+ t_size playlist = get_active_playlist();
+ if (playlist == infinite) return 0;
+ else return playlist_get_item_count(playlist);
+}
+
+void playlist_manager::activeplaylist_enum_items(enum_items_callback & p_callback,const bit_array & p_mask)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_enum_items(playlist,p_callback,p_mask);
+}
+
+t_size playlist_manager::activeplaylist_get_focus_item()
+{
+ t_size playlist = get_active_playlist();
+ if (playlist == infinite) return infinite;
+ else return playlist_get_focus_item(playlist);
+}
+
+bool playlist_manager::activeplaylist_get_name(pfc::string_base & p_out)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist == infinite) return false;
+ else return playlist_get_name(playlist,p_out);
+}
+
+//modifying playlist
+bool playlist_manager::activeplaylist_reorder_items(const t_size * order,t_size count)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_reorder_items(playlist,order,count);
+ else return false;
+}
+
+void playlist_manager::activeplaylist_set_selection(const bit_array & affected,const bit_array & status)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_set_selection(playlist,affected,status);
+}
+
+bool playlist_manager::activeplaylist_remove_items(const bit_array & mask)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_remove_items(playlist,mask);
+ else return false;
+}
+
+bool playlist_manager::activeplaylist_replace_item(t_size p_item,const metadb_handle_ptr & p_new_item)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_replace_item(playlist,p_item,p_new_item);
+ else return false;
+}
+
+void playlist_manager::activeplaylist_set_focus_item(t_size p_item)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_set_focus_item(playlist,p_item);
+}
+
+t_size playlist_manager::activeplaylist_insert_items(t_size p_base,const pfc::list_base_const_t<metadb_handle_ptr> & data,const bit_array & p_selection)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_insert_items(playlist,p_base,data,p_selection);
+ else return infinite;
+}
+
+void playlist_manager::activeplaylist_ensure_visible(t_size p_item)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_ensure_visible(playlist,p_item);
+}
+
+bool playlist_manager::activeplaylist_rename(const char * p_name,t_size p_name_len)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_rename(playlist,p_name,p_name_len);
+ else return false;
+}
+
+bool playlist_manager::activeplaylist_is_item_selected(t_size p_item)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_is_item_selected(playlist,p_item);
+ else return false;
+}
+
+bool playlist_manager::activeplaylist_get_item_handle(metadb_handle_ptr & p_out,t_size p_item)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_get_item_handle(p_out,playlist,p_item);
+ else return false;
+}
+
+void playlist_manager::activeplaylist_move_selection(int p_delta)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_move_selection(playlist,p_delta);
+}
+
+void playlist_manager::activeplaylist_get_selection_mask(bit_array_var & out)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_get_selection_mask(playlist,out);
+}
+
+void playlist_manager::activeplaylist_get_all_items(pfc::list_base_t<metadb_handle_ptr> & out)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_get_all_items(playlist,out);
+}
+
+void playlist_manager::activeplaylist_get_selected_items(pfc::list_base_t<metadb_handle_ptr> & out)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_get_selected_items(playlist,out);
+}
+
+bool playlist_manager::remove_playlist(t_size idx)
+{
+ return remove_playlists(bit_array_one(idx));
+}
+
+bool playlist_incoming_item_filter::process_location(const char * url,pfc::list_base_t<metadb_handle_ptr> & out,bool filter,const char * p_mask,const char * p_exclude,HWND p_parentwnd)
+{
+ return process_locations(pfc::list_single_ref_t<const char*>(url),out,filter,p_mask,p_exclude,p_parentwnd);
+}
+
+void playlist_manager::playlist_clear(t_size p_playlist)
+{
+ playlist_remove_items(p_playlist,bit_array_true());
+}
+
+void playlist_manager::activeplaylist_clear()
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_clear(playlist);
+}
+
+bool playlist_manager::playlist_add_items(t_size playlist,const pfc::list_base_const_t<metadb_handle_ptr> & data,const bit_array & p_selection)
+{
+ return playlist_insert_items(playlist,infinite,data,p_selection) != infinite;
+}
+
+bool playlist_manager::activeplaylist_add_items(const pfc::list_base_const_t<metadb_handle_ptr> & data,const bit_array & p_selection)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_add_items(playlist,data,p_selection);
+ else return false;
+}
+
+bool playlist_manager::playlist_insert_items_filter(t_size p_playlist,t_size p_base,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,bool p_select)
+{
+ metadb_handle_list temp;
+ static_api_ptr_t<playlist_incoming_item_filter> api;
+ if (!api->filter_items(p_data,temp))
+ return false;
+ return playlist_insert_items(p_playlist,p_base,temp,bit_array_val(p_select)) != infinite;
+}
+
+bool playlist_manager::activeplaylist_insert_items_filter(t_size p_base,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,bool p_select)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_insert_items_filter(playlist,p_base,p_data,p_select);
+ else return false;
+}
+
+bool playlist_manager::playlist_insert_locations(t_size p_playlist,t_size p_base,const pfc::list_base_const_t<const char*> & p_urls,bool p_select,HWND p_parentwnd)
+{
+ metadb_handle_list temp;
+ static_api_ptr_t<playlist_incoming_item_filter> api;
+ if (!api->process_locations(p_urls,temp,true,0,0,p_parentwnd)) return false;
+ return playlist_insert_items(p_playlist,p_base,temp,bit_array_val(p_select)) != infinite;
+}
+
+bool playlist_manager::activeplaylist_insert_locations(t_size p_base,const pfc::list_base_const_t<const char*> & p_urls,bool p_select,HWND p_parentwnd)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_insert_locations(playlist,p_base,p_urls,p_select,p_parentwnd);
+ else return false;
+}
+
+bool playlist_manager::playlist_add_items_filter(t_size p_playlist,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,bool p_select)
+{
+ return playlist_insert_items_filter(p_playlist,infinite,p_data,p_select);
+}
+
+bool playlist_manager::activeplaylist_add_items_filter(const pfc::list_base_const_t<metadb_handle_ptr> & p_data,bool p_select)
+{
+ return activeplaylist_insert_items_filter(infinite,p_data,p_select);
+}
+
+bool playlist_manager::playlist_add_locations(t_size p_playlist,const pfc::list_base_const_t<const char*> & p_urls,bool p_select,HWND p_parentwnd)
+{
+ return playlist_insert_locations(p_playlist,infinite,p_urls,p_select,p_parentwnd);
+}
+bool playlist_manager::activeplaylist_add_locations(const pfc::list_base_const_t<const char*> & p_urls,bool p_select,HWND p_parentwnd)
+{
+ return activeplaylist_insert_locations(infinite,p_urls,p_select,p_parentwnd);
+}
+
+void playlist_manager::reset_playing_playlist()
+{
+ set_playing_playlist(get_active_playlist());
+}
+
+void playlist_manager::playlist_clear_selection(t_size p_playlist)
+{
+ playlist_set_selection(p_playlist,bit_array_true(),bit_array_false());
+}
+
+void playlist_manager::activeplaylist_clear_selection()
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_clear_selection(playlist);
+}
+
+void playlist_manager::activeplaylist_undo_backup()
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_undo_backup(playlist);
+}
+
+bool playlist_manager::activeplaylist_undo_restore()
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_undo_restore(playlist);
+ else return false;
+}
+
+bool playlist_manager::activeplaylist_redo_restore()
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_redo_restore(playlist);
+ else return false;
+}
+
+void playlist_manager::playlist_remove_selection(t_size p_playlist,bool p_crop)
+{
+ bit_array_bittable table(playlist_get_item_count(p_playlist));
+ playlist_get_selection_mask(p_playlist,table);
+ if (p_crop) playlist_remove_items(p_playlist,bit_array_not(table));
+ else playlist_remove_items(p_playlist,table);
+}
+
+void playlist_manager::activeplaylist_remove_selection(bool p_crop)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_remove_selection(playlist,p_crop);
+}
+
+void playlist_manager::activeplaylist_item_format_title(t_size p_item,titleformat_hook * p_hook,pfc::string_base & out,const service_ptr_t<titleformat_object> & p_script,titleformat_text_filter * p_filter,play_control::t_display_level p_playback_info_level)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist == infinite) out = "NJET";
+ else playlist_item_format_title(playlist,p_item,p_hook,out,p_script,p_filter,p_playback_info_level);
+}
+
+void playlist_manager::playlist_set_selection_single(t_size p_playlist,t_size p_item,bool p_state)
+{
+ playlist_set_selection(p_playlist,bit_array_one(p_item),bit_array_val(p_state));
+}
+
+void playlist_manager::activeplaylist_set_selection_single(t_size p_item,bool p_state)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_set_selection_single(playlist,p_item,p_state);
+}
+
+t_size playlist_manager::playlist_get_selection_count(t_size p_playlist,t_size p_max)
+{
+ enum_items_callback_count_selection callback(p_max);
+ playlist_enum_items(p_playlist,callback,bit_array_true());
+ return callback.get_count();
+}
+
+t_size playlist_manager::activeplaylist_get_selection_count(t_size p_max)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_get_selection_count(playlist,p_max);
+ else return 0;
+}
+
+bool playlist_manager::playlist_get_focus_item_handle(metadb_handle_ptr & p_out,t_size p_playlist)
+{
+ t_size index = playlist_get_focus_item(p_playlist);
+ if (index == infinite) return false;
+ return playlist_get_item_handle(p_out,p_playlist,index);
+}
+
+bool playlist_manager::activeplaylist_get_focus_item_handle(metadb_handle_ptr & p_out)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_get_focus_item_handle(p_out,playlist);
+ else return false;
+}
+
+t_size playlist_manager::find_playlist(const char * p_name,t_size p_name_length)
+{
+ t_size n, m = get_playlist_count();
+ pfc::string8_fastalloc temp;
+ for(n=0;n<m;n++)
+ {
+ if (!playlist_get_name(n,temp)) break;
+ if (stricmp_utf8_ex(temp,temp.length(),p_name,p_name_length) == 0) return n;
+ }
+ return infinite;
+}
+
+t_size playlist_manager::find_or_create_playlist(const char * p_name,t_size p_name_length)
+{
+ t_size index = find_playlist(p_name,p_name_length);
+ if (index != infinite) return index;
+ return create_playlist(p_name,p_name_length,infinite);
+}
+
+t_size playlist_manager::create_playlist_autoname(t_size p_index) {
+ static const char new_playlist_text[] = "New Playlist";
+ if (find_playlist(new_playlist_text,infinite) == infinite) return create_playlist(new_playlist_text,infinite,p_index);
+ for(t_size walk = 2; ; walk++) {
+ pfc::string_fixed_t<64> namebuffer;
+ namebuffer << new_playlist_text << " (" << walk << ")";
+ if (find_playlist(namebuffer,infinite) == infinite) return create_playlist(namebuffer,infinite,p_index);
+ }
+}
+
+bool playlist_manager::activeplaylist_sort_by_format(const char * spec,bool p_sel_only)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) return playlist_sort_by_format(playlist,spec,p_sel_only);
+ else return false;
+}
+
+bool playlist_manager::highlight_playing_item()
+{
+ t_size playlist,item;
+ if (!get_playing_item_location(&playlist,&item)) return false;
+ set_active_playlist(playlist);
+ playlist_set_focus_item(playlist,item);
+ playlist_set_selection(playlist,bit_array_true(),bit_array_one(item));
+ playlist_ensure_visible(playlist,item);
+ return true;
+}
+
+void playlist_manager::playlist_get_items(t_size p_playlist,pfc::list_base_t<metadb_handle_ptr> & out,const bit_array & p_mask)
+{
+ playlist_enum_items(p_playlist,enum_items_callback_retrieve_all_items(out),p_mask);
+}
+
+void playlist_manager::activeplaylist_get_items(pfc::list_base_t<metadb_handle_ptr> & out,const bit_array & p_mask)
+{
+ t_size playlist = get_active_playlist();
+ if (playlist != infinite) playlist_get_items(playlist,out,p_mask);
+}
+
+void playlist_manager::active_playlist_fix()
+{
+ t_size playlist = get_active_playlist();
+ if (playlist == infinite)
+ {
+ t_size max = get_playlist_count();
+ if (max == 0)
+ {
+ create_playlist_autoname();
+ }
+ set_active_playlist(0);
+ }
+}
+
+namespace {
+ class enum_items_callback_remove_list : public playlist_manager::enum_items_callback
+ {
+ const metadb_handle_list & m_data;
+ bit_array_var & m_table;
+ t_size m_found;
+ public:
+ enum_items_callback_remove_list(const metadb_handle_list & p_data,bit_array_var & p_table) : m_data(p_data), m_table(p_table), m_found(0) {}
+ bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
+ {
+ bool found = m_data.bsearch_by_pointer(p_location) != infinite;
+ m_table.set(p_index,found);
+ if (found) m_found++;
+ return true;
+ }
+
+ inline t_size get_found() const {return m_found;}
+ };
+}
+
+void playlist_manager::remove_items_from_all_playlists(const pfc::list_base_const_t<metadb_handle_ptr> & p_data)
+{
+ t_size playlist_num, playlist_max = get_playlist_count();
+ if (playlist_max != infinite)
+ {
+ metadb_handle_list temp;
+ temp.add_items(p_data);
+ temp.sort_by_pointer();
+ for(playlist_num = 0; playlist_num < playlist_max; playlist_num++ )
+ {
+ t_size playlist_item_count = playlist_get_item_count(playlist_num);
+ if (playlist_item_count == infinite) break;
+ bit_array_bittable table(playlist_item_count);
+ enum_items_callback_remove_list callback(temp,table);
+ playlist_enum_items(playlist_num,callback,bit_array_true());
+ if (callback.get_found()>0)
+ playlist_remove_items(playlist_num,table);
+ }
+ }
+}
+
+bool playlist_manager::get_all_items(pfc::list_base_t<metadb_handle_ptr> & out)
+{
+ t_size n, m = get_playlist_count();
+ if (m == infinite) return false;
+ enum_items_callback_retrieve_all_items callback(out);
+ for(n=0;n<m;n++)
+ {
+ playlist_enum_items(n,callback,bit_array_true());
+ }
+ return true;
+}
+
+t_uint32 playlist_manager::activeplaylist_lock_get_filter_mask()
+{
+ t_size playlist = get_active_playlist();
+ if (playlist == infinite) return ~0;
+ else return playlist_lock_get_filter_mask(playlist);
+}
+
+bool playlist_manager::activeplaylist_is_undo_available()
+{
+ t_size playlist = get_active_playlist();
+ if (playlist == infinite) return false;
+ else return playlist_is_undo_available(playlist);
+}
+
+bool playlist_manager::activeplaylist_is_redo_available()
+{
+ t_size playlist = get_active_playlist();
+ if (playlist == infinite) return false;
+ else return playlist_is_redo_available(playlist);
+}
+
+bool playlist_manager::remove_playlist_switch(t_size idx)
+{
+ bool need_switch = get_active_playlist() == idx;
+ if (remove_playlist(idx))
+ {
+ if (need_switch)
+ {
+ t_size total = get_playlist_count();
+ if (total > 0)
+ {
+ if (idx >= total) idx = total-1;
+ set_active_playlist(idx);
+ }
+ }
+ return true;
+ }
+ else return false;
+}
+
+
+
+bool t_playback_queue_item::operator==(const t_playback_queue_item & p_item) const
+{
+ return m_handle == p_item.m_handle && m_playlist == p_item.m_playlist && m_item == p_item.m_item;
+}
+
+bool t_playback_queue_item::operator!=(const t_playback_queue_item & p_item) const
+{
+ return m_handle != p_item.m_handle || m_playlist != p_item.m_playlist || m_item != p_item.m_item;
+}
+
+
+
+bool playlist_manager::activeplaylist_execute_default_action(t_size p_item) {
+ t_size idx = get_active_playlist();
+ if (idx == infinite) return false;
+ else return playlist_execute_default_action(idx,p_item);
+}
+
+namespace {
+ class completion_notify_dfd : public completion_notify {
+ public:
+ completion_notify_dfd(const pfc::list_base_const_t<metadb_handle_ptr> & p_data,service_ptr_t<process_locations_notify> p_notify) : m_data(p_data), m_notify(p_notify) {}
+ void on_completion(unsigned p_code) {
+ switch(p_code) {
+ case metadb_io::load_info_aborted:
+ m_notify->on_aborted();
+ break;
+ default:
+ m_notify->on_completion(m_data);
+ break;
+ }
+ }
+ private:
+ metadb_handle_list m_data;
+ service_ptr_t<process_locations_notify> m_notify;
+ };
+};
+
+void dropped_files_data_impl::to_handles_async_ex(t_uint32 p_op_flags,HWND p_parentwnd,service_ptr_t<process_locations_notify> p_notify) {
+ if (m_is_paths) {
+ static_api_ptr_t<playlist_incoming_item_filter_v2>()->process_locations_async(
+ m_paths,
+ p_op_flags,
+ NULL,
+ NULL,
+ p_parentwnd,
+ p_notify);
+ } else {
+ t_uint32 flags = 0;
+ if (p_op_flags & playlist_incoming_item_filter_v2::op_flag_background) flags |= metadb_io_v2::op_flag_background;
+ if (p_op_flags & playlist_incoming_item_filter_v2::op_flag_delay_ui) flags |= metadb_io_v2::op_flag_delay_ui;
+ static_api_ptr_t<metadb_io_v2>()->load_info_async(m_handles,metadb_io::load_info_default,p_parentwnd,flags,new service_impl_t<completion_notify_dfd>(m_handles,p_notify));
+ }
+}
+void dropped_files_data_impl::to_handles_async(bool p_filter,HWND p_parentwnd,service_ptr_t<process_locations_notify> p_notify) {
+ to_handles_async_ex(p_filter ? 0 : playlist_incoming_item_filter_v2::op_flag_no_filter,p_parentwnd,p_notify);
+}
+
+bool dropped_files_data_impl::to_handles(pfc::list_base_t<metadb_handle_ptr> & p_out,bool p_filter,HWND p_parentwnd) {
+ if (m_is_paths) {
+ return static_api_ptr_t<playlist_incoming_item_filter>()->process_locations(m_paths,p_out,p_filter,NULL,NULL,p_parentwnd);
+ } else {
+ if (static_api_ptr_t<metadb_io>()->load_info_multi(m_handles,metadb_io::load_info_default,p_parentwnd,true) == metadb_io::load_info_aborted) return false;
+ p_out = m_handles;
+ return true;
+ }
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist.h
new file mode 100644
index 0000000..2d783cb
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist.h
@@ -0,0 +1,611 @@
+#ifndef _PLAYLIST_H_
+#define _PLAYLIST_H_
+
+//! This interface allows filtering of playlist modification operations.\n
+//! Implemented by components "locking" playlists; use playlist_manager::playlist_lock_install() etc to takeover specific playlist with your instance of playlist_lock.
+class NOVTABLE playlist_lock : public service_base {
+public:
+ enum {
+ filter_add = 1 << 0,
+ filter_remove = 1 << 1,
+ filter_reorder = 1 << 2,
+ filter_replace = 1 << 3,
+ filter_rename = 1 << 4,
+ filter_remove_playlist = 1 << 5,
+ filter_default_action = 1 << 6,
+ };
+
+ //! Queries whether specified item insertiion operation is allowed in the locked playlist.
+ //! @param p_base Index from which the items are being inserted.
+ //! @param p_data Items being inserted.
+ //! @param p_selection Caller-requested selection state of items being inserted.
+ //! @returns True to allow the operation, false to block it.
+ virtual bool query_items_add(t_size p_base, const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const bit_array & p_selection) = 0;
+ //! Queries whether specified item reorder operation is allowed in the locked playlist.
+ //! @param p_order Pointer to array containing permutation defining requested reorder operation.
+ //! @param p_count Number of items in array pointed to by p_order. This should always be equal to number of items on the locked playlist.
+ //! @returns True to allow the operation, false to block it.
+ virtual bool query_items_reorder(const t_size * p_order,t_size p_count) = 0;
+ //! Queries whether specified item removal operation is allowed in the locked playlist.
+ //! @param p_mask Specifies which items from locked playlist are being removed.
+ //! @param p_force If set to true, the call is made only for notification purpose and items are getting removed regardless (after e.g. they have been physically removed).
+ //! @returns True to allow the operation, false to block it. Note that return value is ignored if p_force is set to true.
+ virtual bool query_items_remove(const bit_array & p_mask,bool p_force) = 0;
+ //! Queries whether specified item replacement operation is allowed in the locked playlist.
+ //! @param p_index Index of the item being replaced.
+ //! @param p_old Old value of the item being replaced.
+ //! @param p_new New value of the item being replaced.
+ //! @returns True to allow the operation, false to block it.
+ virtual bool query_item_replace(t_size p_index,const metadb_handle_ptr & p_old,const metadb_handle_ptr & p_new)=0;
+ //! Queries whether renaming the locked playlist is allowed.
+ //! @param p_new_name Requested new name of the playlist; a UTF-8 encoded string.
+ //! @param p_new_name_len Length limit of the name string, in bytes (actual string may be shorter if null terminator is encountered before). Set this to infinite to use plain null-terminated strings.
+ //! @returns True to allow the operation, false to block it.
+ virtual bool query_playlist_rename(const char * p_new_name,t_size p_new_name_len) = 0;
+ //! Queries whether removal of the locked playlist is allowed. Note that the lock will be released when the playlist is removed.
+ //! @returns True to allow the operation, false to block it.
+ virtual bool query_playlist_remove() = 0;
+ //! Executes "default action" (doubleclick etc) for specified playlist item. When the playlist is not locked, default action starts playback of the item.
+ //! @returns True if custom default action was executed, false to fall-through to default one for non-locked playlists (start playback).
+ virtual bool execute_default_action(t_size p_item) = 0;
+ //! Notifies lock about changed index of the playlist, in result of user reordering playlists or removing other playlists.
+ virtual void on_playlist_index_change(t_size p_new_index) = 0;
+ //! Notifies lock about the locked playlist getting removed.
+ virtual void on_playlist_remove() = 0;
+ //! Retrieves human-readable name of playlist lock to display.
+ virtual void get_lock_name(pfc::string_base & p_out) = 0;
+ //! Requests user interface of component controlling the playlist lock to be shown.
+ virtual void show_ui() = 0;
+ //! Queries which actions the lock filters. The return value must not change while the lock is registered with playlist_manager. The return value is a combination of one or more filter_* constants.
+ virtual t_uint32 get_filter_mask() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(playlist_lock,service_base);
+};
+
+struct t_playback_queue_item {
+ metadb_handle_ptr m_handle;
+ t_size m_playlist,m_item;
+
+ bool operator==(const t_playback_queue_item & p_item) const;
+ bool operator!=(const t_playback_queue_item & p_item) const;
+};
+
+
+//! This service provides methods for all sorts of playlist interaction.\n
+//! All playlist_manager methods are valid only from main app thread.\n
+//! Usage: static_api_ptr_t<playlist_manager>.
+class NOVTABLE playlist_manager : public service_base
+{
+public:
+
+ //! Callback interface for playlist enumeration methods.
+ class NOVTABLE enum_items_callback {
+ public:
+ //! @returns True to continue enumeration, false to abort.
+ virtual bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected) = 0;//return false to stop
+ };
+
+ //! Retrieves number of playlists.
+ virtual t_size get_playlist_count() = 0;
+ //! Retrieves index of active playlist; infinite if no playlist is active.
+ virtual t_size get_active_playlist() = 0;
+ //! Sets active playlist (infinite to set no active playlist).
+ virtual void set_active_playlist(t_size p_index) = 0;
+ //! Retrieves playlist from which items to be played are taken from.
+ virtual t_size get_playing_playlist() = 0;
+ //! Sets playlist from which items to be played are taken from.
+ virtual void set_playing_playlist(t_size p_index) = 0;
+ //! Removes playlists according to specified mask. See also: bit_array.
+ virtual bool remove_playlists(const bit_array & p_mask) = 0;
+ //! Creates a new playlist.
+ //! @param p_name Name of playlist to create; a UTF-8 encoded string.
+ //! @param p_name_length Length limit of playlist name string, in bytes (actual string may be shorter if null terminator is encountered before). Set this to infinite to use plain null-terminated strings.
+ //! @param p_index Index at which to insert new playlist; set to infinite to put it at the end of playlist list.
+ //! @returns Actual index of newly inserted playlist, infinite on failure (call from invalid context).
+ virtual t_size create_playlist(const char * p_name,t_size p_name_length,t_size p_index) = 0;
+ //! Reorders playlist list according to specified permutation.
+ //! @returns True on success, false on failure (call from invalid context).
+ virtual bool reorder(const t_size * p_order,t_size p_count) = 0;
+
+
+ //! Retrieves number of items on specified playlist.
+ virtual t_size playlist_get_item_count(t_size p_playlist) = 0;
+ //! Enumerates contents of specified playlist.
+ virtual void playlist_enum_items(t_size p_playlist,enum_items_callback & p_callback,const bit_array & p_mask) = 0;
+ //! Retrieves index of focus item on specified playlist; returns infinite when no item has focus.
+ virtual t_size playlist_get_focus_item(t_size p_playlist) = 0;
+ //! Retrieves name of specified playlist.
+ virtual bool playlist_get_name(t_size p_playlist,pfc::string_base & p_out) = 0;
+
+ //! Reorders items in specified playlist according to specified permutation.
+ virtual bool playlist_reorder_items(t_size p_playlist,const t_size * p_order,t_size p_count) = 0;
+ //! Selects/deselects items on specified playlist.
+ //! @param p_playlist Index of playlist to alter.
+ //! @param p_affected Mask of items to alter.
+ //! @param p_status Mask of selected/deselected state to apply to items specified by p_affected.
+ virtual void playlist_set_selection(t_size p_playlist,const bit_array & p_affected,const bit_array & p_status) = 0;
+ //! Removes specified items from specified playlist. Returns true on success or false on failure (playlist locked).
+ virtual bool playlist_remove_items(t_size p_playlist,const bit_array & mask)=0;
+ //! Replaces specified item on specified playlist. Returns true on success or false on failure (playlist locked).
+ virtual bool playlist_replace_item(t_size p_playlist,t_size p_item,const metadb_handle_ptr & p_new_item) = 0;
+ //! Sets index of focus item on specified playlist; use infinite to set no focus item.
+ virtual void playlist_set_focus_item(t_size p_playlist,t_size p_item) = 0;
+ //! Inserts new items into specified playlist, at specified position.
+ virtual t_size playlist_insert_items(t_size p_playlist,t_size p_base,const pfc::list_base_const_t<metadb_handle_ptr> & data,const bit_array & p_selection) = 0;
+ //! Tells playlist renderers to make sure that specified item is visible.
+ virtual void playlist_ensure_visible(t_size p_playlist,t_size p_item) = 0;
+ //! Renames specified playlist.
+ //! @param p_name New name of playlist; a UTF-8 encoded string.
+ //! @param p_name_length Length limit of playlist name string, in bytes (actual string may be shorter if null terminator is encountered before). Set this to infinite to use plain null-terminated strings.
+ //! @returns True on success, false on failure (playlist locked).
+ virtual bool playlist_rename(t_size p_index,const char * p_name,t_size p_name_length) = 0;
+
+
+ //! Creates an undo restore point for specified playlist.
+ virtual void playlist_undo_backup(t_size p_playlist) = 0;
+ //! Reverts specified playlist to last undo restore point and generates a redo restore point.
+ //! @returns True on success, false on failure (playlist locked or no restore point available).
+ virtual bool playlist_undo_restore(t_size p_playlist) = 0;
+ //! Reverts specified playlist to next redo restore point and generates an undo restore point.
+ //! @returns True on success, false on failure (playlist locked or no restore point available).
+ virtual bool playlist_redo_restore(t_size p_playlist) = 0;
+ //! Returns whether an undo restore point is available for specified playlist.
+ virtual bool playlist_is_undo_available(t_size p_playlist) = 0;
+ //! Returns whether a redo restore point is available for specified playlist.
+ virtual bool playlist_is_redo_available(t_size p_playlist) = 0;
+
+ //! Renders information about specified playlist item, using specified titleformatting script parameters.
+ //! @param p_playlist Index of playlist containing item being processed.
+ //! @param p_item Index of item being processed in the playlist containing it.
+ //! @param p_hook Titleformatting script hook to use; see titleformat_hook documentation for more info. Set to NULL when hook functionality is not needed.
+ //! @param p_out String object receiving results.
+ //! @param p_script Compiled titleformatting script to use; see titleformat_object cocumentation for more info.
+ //! @param p_filter Text filter to use; see titleformat_text_filter documentation for more info. Set to NULL when text filter functionality is not needed.
+ //! @param p_playback_info_level Level of playback related information requested. See playback_control::t_display_level documentation for more info.
+ virtual void playlist_item_format_title(t_size p_playlist,t_size p_item,titleformat_hook * p_hook,pfc::string_base & p_out,const service_ptr_t<titleformat_object> & p_script,titleformat_text_filter * p_filter,playback_control::t_display_level p_playback_info_level)=0;
+
+
+ //! Retrieves playlist position of currently playing item.
+ //! @param p_playlist Receives index of playlist containing currently playing item on success.
+ //! @param p_index Receives index of currently playing item in the playlist that contains it on success.
+ //! @returns True on success, false on failure (not playing or currently played item has been removed from the playlist it was on when starting).
+ virtual bool get_playing_item_location(t_size * p_playlist,t_size * p_index) = 0;
+
+ //! Sorts specified playlist - entire playlist or selection only - by specified title formatting pattern, or randomizes the order.
+ //! @param p_playlist Index of playlist to alter.
+ //! @param p_pattern Title formatting pattern to sort by (an UTF-8 encoded null-termindated string). Set to NULL to randomize the order of items.
+ //! @param p_sel_only Set to false to sort/randomize whole playlist, or to true to sort/randomize only selection on the playlist.
+ //! @returns True on success, false on failure (playlist locked etc).
+ virtual bool playlist_sort_by_format(t_size p_playlist,const char * p_pattern,bool p_sel_only) = 0;
+
+ //! For internal use only; p_items must be sorted by metadb::path_compare; use file_operation_callback static methods instead of calling this directly.
+ virtual void on_files_deleted_sorted(const pfc::list_base_const_t<const char *> & p_items) = 0;
+ //! For internal use only; p_from must be sorted by metadb::path_compare; use file_operation_callback static methods instead of calling this directly.
+ virtual void on_files_moved_sorted(const pfc::list_base_const_t<const char *> & p_from,const pfc::list_base_const_t<const char *> & p_to) = 0;
+
+ virtual bool playlist_lock_install(t_size p_playlist,const service_ptr_t<playlist_lock> & p_lock) = 0;//returns false when invalid playlist or already locked
+ virtual bool playlist_lock_uninstall(t_size p_playlist,const service_ptr_t<playlist_lock> & p_lock) = 0;
+ virtual bool playlist_lock_is_present(t_size p_playlist) = 0;
+ virtual bool playlist_lock_query_name(t_size p_playlist,pfc::string_base & p_out) = 0;
+ virtual bool playlist_lock_show_ui(t_size p_playlist) = 0;
+ virtual t_uint32 playlist_lock_get_filter_mask(t_size p_playlist) = 0;
+
+
+ //! Retrieves number of available playback order modes.
+ virtual t_size playback_order_get_count() = 0;
+ //! Retrieves name of specified playback order move.
+ //! @param p_index Index of playback order mode to query, from 0 to playback_order_get_count() return value - 1.
+ //! @returns Null-terminated UTF-8 encoded string containing name of the playback order mode. Returned pointer points to statically allocated string and can be safely stored without having to free it later.
+ virtual const char * playback_order_get_name(t_size p_index) = 0;
+ //! Retrieves GUID of specified playback order mode. Used for managing playback modes without relying on names.
+ //! @param p_index Index of playback order mode to query, from 0 to playback_order_get_count() return value - 1.
+ virtual GUID playback_order_get_guid(t_size p_index) = 0;
+ //! Retrieves index of active playback order mode.
+ virtual t_size playback_order_get_active() = 0;
+ //! Sets index of active playback order mode.
+ virtual void playback_order_set_active(t_size p_index) = 0;
+
+ virtual void queue_remove_mask(bit_array const & p_mask) = 0;
+ virtual void queue_add_item_playlist(t_size p_playlist,t_size p_item) = 0;
+ virtual void queue_add_item(metadb_handle_ptr p_item) = 0;
+ virtual t_size queue_get_count() = 0;
+ virtual void queue_get_contents(pfc::list_base_t<t_playback_queue_item> & p_out) = 0;
+ //! Returns index (0-based) on success, infinite on failure (item not in queue).
+ virtual t_size queue_find_index(t_playback_queue_item const & p_item) = 0;
+
+ //! Registers a playlist callback; registered object receives notifications about any modifications of any of loaded playlists.
+ //! @param p_callback Callback interface to register.
+ //! @param p_flags Flags indicating which callback methods are requested. See playlist_callback::flag_* constants for more info. The main purpose of flags parameter is working set optimization by not calling methods that do nothing.
+ virtual void register_callback(class playlist_callback * p_callback,unsigned p_flags) = 0;
+ //! Registers a playlist callback; registered object receives notifications about any modifications of active playlist.
+ //! @param p_callback Callback interface to register.
+ //! @param p_flags Flags indicating which callback methods are requested. See playlist_callback_single::flag_* constants for more info. The main purpose of flags parameter is working set optimization by not calling methods that do nothing.
+ virtual void register_callback(class playlist_callback_single * p_callback,unsigned p_flags) = 0;
+ //! Unregisters a playlist callback (playlist_callback version).
+ virtual void unregister_callback(class playlist_callback * p_callback) = 0;
+ //! Unregisters a playlist callback (playlist_callback_single version).
+ virtual void unregister_callback(class playlist_callback_single * p_callback) = 0;
+ //! Modifies flags indicating which calback methods are requested (playlist_callback version).
+ virtual void modify_callback(class playlist_callback * p_callback,unsigned p_flags) = 0;
+ //! Modifies flags indicating which calback methods are requested (playlist_callback_single version).
+ virtual void modify_callback(class playlist_callback_single * p_callback,unsigned p_flags) = 0;
+
+ //! Executes default doubleclick/enter action for specified item on specified playlist (starts playing the item unless overridden by a lock to do something else).
+ virtual bool playlist_execute_default_action(t_size p_playlist,t_size p_item) = 0;
+
+
+ //! Helper; removes all items from the playback queue.
+ void queue_flush() {queue_remove_mask(bit_array_true());}
+ //! Helper; returns whether there are items in the playback queue.
+ bool queue_is_active() {return queue_get_count() > 0;}
+
+ //! Helper; highlights currently playing item; returns true on success or false on failure (not playing or currently played item has been removed from playlist since playback started).
+ bool highlight_playing_item();
+ //! Helper; removes single playlist of specified index.
+ bool remove_playlist(t_size p_playlist);
+ //! Helper; removes single playlist of specified index, and switches to another playlist when possible.
+ bool remove_playlist_switch(t_size p_playlist);
+
+ //! Helper; returns whether specified item on specified playlist is selected or not.
+ bool playlist_is_item_selected(t_size p_playlist,t_size p_item);
+ //! Helper; retrieves metadb_handle of specified playlist item. Returns true on success, false on failure (invalid parameters).
+ bool playlist_get_item_handle(metadb_handle_ptr & p_out,t_size p_playlist,t_size p_item);
+
+ //! Moves selected items up/down in the playlist by specified offset.
+ //! @param p_playlist Index of playlist to alter.
+ //! @param p_delta Offset to move items by. Set it to a negative valuye to move up, or to a positive value to move down.
+ //! @returns True on success, false on failure (e.g. playlist locked).
+ bool playlist_move_selection(t_size p_playlist,int p_delta);
+ //! Retrieves selection map of specific playlist, using bit_array_var interface.
+ void playlist_get_selection_mask(t_size p_playlist,bit_array_var & out);
+ void playlist_get_items(t_size p_playlist,pfc::list_base_t<metadb_handle_ptr> & out,const bit_array & p_mask);
+ void playlist_get_all_items(t_size p_playlist,pfc::list_base_t<metadb_handle_ptr> & out);
+ void playlist_get_selected_items(t_size p_playlist,pfc::list_base_t<metadb_handle_ptr> & out);
+
+ //! Clears contents of specified playlist (removes all items from it).
+ void playlist_clear(t_size p_playlist);
+ bool playlist_add_items(t_size playlist,const pfc::list_base_const_t<metadb_handle_ptr> & data,const bit_array & p_selection);
+ void playlist_clear_selection(t_size p_playlist);
+ void playlist_remove_selection(t_size p_playlist,bool p_crop = false);
+
+
+ //retrieving status
+ t_size activeplaylist_get_item_count();
+ void activeplaylist_enum_items(enum_items_callback & p_callback,const bit_array & p_mask);
+ t_size activeplaylist_get_focus_item();//focus may be infinite if no item is focused
+ bool activeplaylist_get_name(pfc::string_base & p_out);
+
+ //modifying playlist
+ bool activeplaylist_reorder_items(const t_size * order,t_size count);
+ void activeplaylist_set_selection(const bit_array & affected,const bit_array & status);
+ bool activeplaylist_remove_items(const bit_array & mask);
+ bool activeplaylist_replace_item(t_size p_item,const metadb_handle_ptr & p_new_item);
+ void activeplaylist_set_focus_item(t_size p_item);
+ t_size activeplaylist_insert_items(t_size p_base,const pfc::list_base_const_t<metadb_handle_ptr> & data,const bit_array & p_selection);
+ void activeplaylist_ensure_visible(t_size p_item);
+ bool activeplaylist_rename(const char * p_name,t_size p_name_len);
+
+ void activeplaylist_undo_backup();
+ bool activeplaylist_undo_restore();
+ bool activeplaylist_redo_restore();
+
+ bool activeplaylist_is_item_selected(t_size p_item);
+ bool activeplaylist_get_item_handle(metadb_handle_ptr & item,t_size p_item);
+ void activeplaylist_move_selection(int p_delta);
+ void activeplaylist_get_selection_mask(bit_array_var & out);
+ void activeplaylist_get_items(pfc::list_base_t<metadb_handle_ptr> & out,const bit_array & p_mask);
+ void activeplaylist_get_all_items(pfc::list_base_t<metadb_handle_ptr> & out);
+ void activeplaylist_get_selected_items(pfc::list_base_t<metadb_handle_ptr> & out);
+ void activeplaylist_clear();
+
+ bool activeplaylist_add_items(const pfc::list_base_const_t<metadb_handle_ptr> & data,const bit_array & p_selection);
+
+ bool playlist_insert_items_filter(t_size p_playlist,t_size p_base,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,bool p_select);
+ bool activeplaylist_insert_items_filter(t_size p_base,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,bool p_select);
+
+ //! DEPRECATED (0.9.3) - use playlist_incoming_item_filter_v2::process_locations_async whenever possible
+ bool playlist_insert_locations(t_size p_playlist,t_size p_base,const pfc::list_base_const_t<const char*> & p_urls,bool p_select,HWND p_parentwnd);
+ //! DEPRECATED (0.9.3) - use playlist_incoming_item_filter_v2::process_locations_async whenever possible
+ bool activeplaylist_insert_locations(t_size p_base,const pfc::list_base_const_t<const char*> & p_urls,bool p_select,HWND p_parentwnd);
+
+ bool playlist_add_items_filter(t_size p_playlist,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,bool p_select);
+ bool activeplaylist_add_items_filter(const pfc::list_base_const_t<metadb_handle_ptr> & p_data,bool p_select);
+
+ bool playlist_add_locations(t_size p_playlist,const pfc::list_base_const_t<const char*> & p_urls,bool p_select,HWND p_parentwnd);
+ bool activeplaylist_add_locations(const pfc::list_base_const_t<const char*> & p_urls,bool p_select,HWND p_parentwnd);
+
+ void reset_playing_playlist();
+
+ void activeplaylist_clear_selection();
+ void activeplaylist_remove_selection(bool p_crop = false);
+
+ void activeplaylist_item_format_title(t_size p_item,titleformat_hook * p_hook,pfc::string_base & out,const service_ptr_t<titleformat_object> & p_script,titleformat_text_filter * p_filter,play_control::t_display_level p_playback_info_level);
+
+ void playlist_set_selection_single(t_size p_playlist,t_size p_item,bool p_state);
+ void activeplaylist_set_selection_single(t_size p_item,bool p_state);
+
+ t_size playlist_get_selection_count(t_size p_playlist,t_size p_max);
+ t_size activeplaylist_get_selection_count(t_size p_max);
+
+ bool playlist_get_focus_item_handle(metadb_handle_ptr & p_item,t_size p_playlist);
+ bool activeplaylist_get_focus_item_handle(metadb_handle_ptr & item);
+
+ t_size find_playlist(const char * p_name,t_size p_name_length);
+ t_size find_or_create_playlist(const char * p_name,t_size p_name_length);
+
+ t_size create_playlist_autoname(t_size p_index = infinite);
+
+ bool activeplaylist_sort_by_format(const char * spec,bool p_sel_only);
+
+ t_uint32 activeplaylist_lock_get_filter_mask();
+ bool activeplaylist_is_undo_available();
+ bool activeplaylist_is_redo_available();
+
+ bool activeplaylist_execute_default_action(t_size p_item);
+
+ void remove_items_from_all_playlists(const pfc::list_base_const_t<metadb_handle_ptr> & p_data);
+
+ void active_playlist_fix();
+
+ bool get_all_items(pfc::list_base_t<metadb_handle_ptr> & out);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(playlist_manager);
+};
+
+class NOVTABLE playlist_callback
+{
+public:
+ virtual void FB2KAPI on_items_added(t_size p_playlist,t_size p_start, const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const bit_array & p_selection)=0;//inside any of these methods, you can call playlist APIs to get exact info about what happened (but only methods that read playlist state, not those that modify it)
+ virtual void FB2KAPI on_items_reordered(t_size p_playlist,const t_size * p_order,t_size p_count)=0;//changes selection too; doesnt actually change set of items that are selected or item having focus, just changes their order
+ virtual void FB2KAPI on_items_removing(t_size p_playlist,const bit_array & p_mask,t_size p_old_count,t_size p_new_count)=0;//called before actually removing them
+ virtual void FB2KAPI on_items_removed(t_size p_playlist,const bit_array & p_mask,t_size p_old_count,t_size p_new_count)=0;
+ virtual void FB2KAPI on_items_selection_change(t_size p_playlist,const bit_array & p_affected,const bit_array & p_state) = 0;
+ virtual void FB2KAPI on_item_focus_change(t_size p_playlist,t_size p_from,t_size p_to)=0;//focus may be -1 when no item has focus; reminder: focus may also change on other callbacks
+
+ virtual void FB2KAPI on_items_modified(t_size p_playlist,const bit_array & p_mask)=0;
+ virtual void FB2KAPI on_items_modified_fromplayback(t_size p_playlist,const bit_array & p_mask,play_control::t_display_level p_level)=0;
+
+ struct t_on_items_replaced_entry
+ {
+ t_size m_index;
+ metadb_handle_ptr m_old,m_new;
+ };
+
+ virtual void FB2KAPI on_items_replaced(t_size p_playlist,const bit_array & p_mask,const pfc::list_base_const_t<t_on_items_replaced_entry> & p_data)=0;
+
+ virtual void FB2KAPI on_item_ensure_visible(t_size p_playlist,t_size p_idx)=0;
+
+ virtual void FB2KAPI on_playlist_activate(t_size p_old,t_size p_new) = 0;
+ virtual void FB2KAPI on_playlist_created(t_size p_index,const char * p_name,t_size p_name_len) = 0;
+ virtual void FB2KAPI on_playlists_reorder(const t_size * p_order,t_size p_count) = 0;
+ virtual void FB2KAPI on_playlists_removing(const bit_array & p_mask,t_size p_old_count,t_size p_new_count) = 0;
+ virtual void FB2KAPI on_playlists_removed(const bit_array & p_mask,t_size p_old_count,t_size p_new_count) = 0;
+ virtual void FB2KAPI on_playlist_renamed(t_size p_index,const char * p_new_name,t_size p_new_name_len) = 0;
+
+ virtual void FB2KAPI on_default_format_changed() = 0;
+ virtual void FB2KAPI on_playback_order_changed(t_size p_new_index) = 0;
+ virtual void FB2KAPI on_playlist_locked(t_size p_playlist,bool p_locked) = 0;
+
+ enum {
+ flag_on_items_added = 1 << 0,
+ flag_on_items_reordered = 1 << 1,
+ flag_on_items_removing = 1 << 2,
+ flag_on_items_removed = 1 << 3,
+ flag_on_items_selection_change = 1 << 4,
+ flag_on_item_focus_change = 1 << 5,
+ flag_on_items_modified = 1 << 6,
+ flag_on_items_modified_fromplayback = 1 << 7,
+ flag_on_items_replaced = 1 << 8,
+ flag_on_item_ensure_visible = 1 << 9,
+ flag_on_playlist_activate = 1 << 10,
+ flag_on_playlist_created = 1 << 11,
+ flag_on_playlists_reorder = 1 << 12,
+ flag_on_playlists_removing = 1 << 13,
+ flag_on_playlists_removed = 1 << 14,
+ flag_on_playlist_renamed = 1 << 15,
+ flag_on_default_format_changed = 1 << 16,
+ flag_on_playback_order_changed = 1 << 17,
+ flag_on_playlist_locked = 1 << 18,
+
+ flag_all = ~0,
+ };
+protected:
+ playlist_callback() {}
+ ~playlist_callback() {}
+};
+
+class NOVTABLE playlist_callback_static : public service_base, public playlist_callback
+{
+public:
+ virtual unsigned get_flags() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(playlist_callback_static);
+};
+
+class NOVTABLE playlist_callback_single
+{
+public:
+ virtual void FB2KAPI on_items_added(t_size start, const pfc::list_base_const_t<metadb_handle_ptr> & p_data,const bit_array & p_selection)=0;//inside any of these methods, you can call playlist APIs to get exact info about what happened (but only methods that read playlist state, not those that modify it)
+ virtual void FB2KAPI on_items_reordered(const t_size * order,t_size count)=0;//changes selection too; doesnt actually change set of items that are selected or item having focus, just changes their order
+ virtual void FB2KAPI on_items_removing(const bit_array & p_mask,t_size p_old_count,t_size p_new_count)=0;//called before actually removing them
+ virtual void FB2KAPI on_items_removed(const bit_array & p_mask,t_size p_old_count,t_size p_new_count)=0;
+ virtual void FB2KAPI on_items_selection_change(const bit_array & p_affected,const bit_array & p_state) = 0;
+ virtual void FB2KAPI on_item_focus_change(t_size p_from,t_size p_to)=0;//focus may be -1 when no item has focus; reminder: focus may also change on other callbacks
+ virtual void FB2KAPI on_items_modified(const bit_array & p_mask)=0;
+ virtual void FB2KAPI on_items_modified_fromplayback(const bit_array & p_mask,play_control::t_display_level p_level)=0;
+ virtual void FB2KAPI on_items_replaced(const bit_array & p_mask,const pfc::list_base_const_t<playlist_callback::t_on_items_replaced_entry> & p_data)=0;
+ virtual void FB2KAPI on_item_ensure_visible(t_size p_idx)=0;
+
+ virtual void FB2KAPI on_playlist_switch() = 0;
+ virtual void FB2KAPI on_playlist_renamed(const char * p_new_name,t_size p_new_name_len) = 0;
+ virtual void FB2KAPI on_playlist_locked(bool p_locked) = 0;
+
+ virtual void FB2KAPI on_default_format_changed() = 0;
+ virtual void FB2KAPI on_playback_order_changed(t_size p_new_index) = 0;
+
+ enum {
+ flag_on_items_added = 1 << 0,
+ flag_on_items_reordered = 1 << 1,
+ flag_on_items_removing = 1 << 2,
+ flag_on_items_removed = 1 << 3,
+ flag_on_items_selection_change = 1 << 4,
+ flag_on_item_focus_change = 1 << 5,
+ flag_on_items_modified = 1 << 6,
+ flag_on_items_modified_fromplayback = 1 << 7,
+ flag_on_items_replaced = 1 << 8,
+ flag_on_item_ensure_visible = 1 << 9,
+ flag_on_playlist_switch = 1 << 10,
+ flag_on_playlist_renamed = 1 << 11,
+ flag_on_playlist_locked = 1 << 12,
+ flag_on_default_format_changed = 1 << 13,
+ flag_on_playback_order_changed = 1 << 14,
+ flag_all = ~0,
+ };
+protected:
+ playlist_callback_single() {}
+ ~playlist_callback_single() {}
+};
+
+class playlist_callback_single_static : public service_base, public playlist_callback_single
+{
+public:
+ virtual unsigned get_flags() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(playlist_callback_single_static);
+};
+
+
+//! Class used for async processing of IDataObject. Content of IDataObject can be dumped into dropped_files_data without any time-consuming operations - won't block calling app when used inside drag&drop handler - and actual time-consuming processing (listing directories and reading infos) can be done later.\n
+//! In 0.9.3 and up, instead of going thru dropped_files_data, you can use playlist_incoming_item_filter_v2::process_dropped_files_async().
+class NOVTABLE dropped_files_data {
+public:
+ virtual void set_paths(pfc::string_list_const const & p_paths) = 0;
+ virtual void set_handles(const pfc::list_base_const_t<metadb_handle_ptr> & p_handles) = 0;
+protected:
+ dropped_files_data() {}
+ ~dropped_files_data() {}
+};
+
+
+class NOVTABLE playlist_incoming_item_filter : public service_base
+{
+public:
+ virtual bool filter_items(const pfc::list_base_const_t<metadb_handle_ptr> & in,pfc::list_base_t<metadb_handle_ptr> & out) = 0;//sort / remove duplicates
+
+ //! Deprecated; use playlist_incoming_item_filter_v2::process_locations_async() when possible.\n
+ //! Converts one or more paths to a list of metadb_handles; displays a progress dialog.\n
+ //! Note that this function creates modal dialog and does not return until the operation has completed.
+ //! @returns True on success, false on user abort.
+ virtual bool process_locations(const pfc::list_base_const_t<const char*> & p_urls,pfc::list_base_t<metadb_handle_ptr> & p_out,bool p_filter,const char * p_restrict_mask_override, const char * p_exclude_mask_override,HWND p_parentwnd) = 0;
+
+ //! Deprecated; use playlist_incoming_item_filter_v2::process_dropped_files_async() when possible.\n
+ //! Converts an IDataObject to a list of metadb_handles.
+ //! Using this function is strongly disrecommended as it implies blocking the drag&drop source app (as well as our app).\n
+ //! @returns True on success, false on user abort or unknown data format.
+ virtual bool process_dropped_files(interface IDataObject * pDataObject,pfc::list_base_t<metadb_handle_ptr> & p_out,bool p_filter,HWND p_parentwnd) = 0;
+
+ //! Checks whether IDataObject contains one of known data formats that can be translated to a list of metadb_handles.
+ virtual bool process_dropped_files_check(interface IDataObject * pDataObject) = 0;
+
+ //! Checks whether IDataObject contains our own private data format (drag&drop within the app etc).
+ virtual bool process_dropped_files_check_if_native(interface IDataObject * pDataObject) = 0;
+
+ //! Creates an IDataObject from specified metadb_handle list.
+ virtual interface IDataObject * create_dataobject(const pfc::list_base_const_t<metadb_handle_ptr> & p_data) = 0;
+
+ //! Checks whether IDataObject contains one of known data formats that can be translated to a list of metadb_handles.\n
+ //! This function also returns drop effects to use (see: IDropTarget::DragEnter(), IDropTarget::DragOver() ). In certain cases, drag effects are necessary for drag&drop to work at all (such as dragging links from IE).\n
+ virtual bool process_dropped_files_check_ex(interface IDataObject * pDataObject, DWORD * p_effect) = 0;
+
+ //! Dumps IDataObject content to specified dropped_files_data object, without any time-consuming processing.\n
+ //! Using this function instead of process_dropped_files() and processing dropped_files_data outside drop handler allows you to avoid blocking drop source app when processing large directories etc.\n
+ //! Note: since 0.9.3, it is recommended to use playlist_incoming_item_filter_v2::process_dropped_files_async() instead.
+ //! @returns True on success, false when IDataObject does not contain any of known data formats.
+ virtual bool process_dropped_files_delayed(dropped_files_data & p_out,interface IDataObject * pDataObject) = 0;
+
+ //helper
+ bool process_location(const char * url,pfc::list_base_t<metadb_handle_ptr> & out,bool filter,const char * p_mask,const char * p_exclude,HWND p_parentwnd);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(playlist_incoming_item_filter);
+};
+
+//! For use with playlist_incoming_item_filter_v2::process_locations_async().
+class NOVTABLE process_locations_notify : public service_base {
+public:
+ virtual void on_completion(const pfc::list_base_const_t<metadb_handle_ptr> & p_items) = 0;
+ virtual void on_aborted() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(process_locations_notify,service_base);
+};
+
+typedef service_ptr_t<process_locations_notify> process_locations_notify_ptr;
+
+//! New (0.9.3)
+class NOVTABLE playlist_incoming_item_filter_v2 : public playlist_incoming_item_filter {
+public:
+ enum {
+ //! Set this to disable presorting (according to user settings) and duplicate removal in output list. Should be unset in most cases.
+ op_flag_no_filter = 1 << 0,
+ //! Set this flag to make the progress dialog not steal focus on creation.
+ op_flag_background = 1 << 1,
+ //! Set this flag to delay the progress dialog becoming visible, so it does not appear at all during short operations. Also implies op_flag_background effect.
+ op_flag_delay_ui = 1 << 2,
+ };
+
+ //! Converts one or more paths to a list of metadb_handles. The function returns immediately; specified callback object receives results when the operation has completed.
+ //! @param p_urls List of paths to process.
+ //! @param p_op_flags Can be null, or one or more of op_flag_* enum values combined, altering behaviors of the operation.
+ //! @param p_restrict_mask_override Override of "restrict incoming items to" setting. Pass NULL to use the value from preferences.
+ //! @param p_exclude_mask_override Override of "exclude file types" setting. Pass NULL to use value from preferences.
+ //! @param p_parentwnd Parent window for spawned progress dialogs.
+ //! @param p_notify Callback receiving notifications about success/abort of the operation as well as output item list.
+ virtual void process_locations_async(const pfc::list_base_const_t<const char*> & p_urls,t_uint32 p_op_flags,const char * p_restrict_mask_override, const char * p_exclude_mask_override,HWND p_parentwnd,process_locations_notify_ptr p_notify) = 0;
+
+ //! Converts an IDataObject to a list of metadb_handles. The function returns immediately; specified callback object receives results when the operation has completed.
+ //! @param p_dataobject IDataObject to process.
+ //! @param p_op_flags Can be null, or one or more of op_flag_* enum values combined, altering behaviors of the operation.
+ //! @param p_parentwnd Parent window for spawned progress dialogs.
+ //! @param p_notify Callback receiving notifications about success/abort of the operation as well as output item list.
+ virtual void process_dropped_files_async(interface IDataObject * p_dataobject,t_uint32 p_op_flags,HWND p_parentwnd,process_locations_notify_ptr p_notify) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(playlist_incoming_item_filter_v2,playlist_incoming_item_filter);
+};
+
+//! Implementation of dropped_files_data.
+class dropped_files_data_impl : public dropped_files_data {
+public:
+ dropped_files_data_impl() : m_is_paths(false) {}
+ void set_paths(pfc::string_list_const const & p_paths) {
+ m_is_paths = true;
+ m_paths = p_paths;
+ }
+ void set_handles(const pfc::list_base_const_t<metadb_handle_ptr> & p_handles) {
+ m_is_paths = false;
+ m_handles = p_handles;
+ }
+
+ void to_handles_async(bool p_filter,HWND p_parentwnd,service_ptr_t<process_locations_notify> p_notify);
+ //! @param p_op_flags Can be null, or one or more of playlist_incoming_item_filter_v2::op_flag_* enum values combined, altering behaviors of the operation.
+ void to_handles_async_ex(t_uint32 p_op_flags,HWND p_parentwnd,service_ptr_t<process_locations_notify> p_notify);
+ bool to_handles(pfc::list_base_t<metadb_handle_ptr> & p_out,bool p_filter,HWND p_parentwnd);
+private:
+ pfc::string_list_impl m_paths;
+ metadb_handle_list m_handles;
+ bool m_is_paths;
+};
+
+
+class NOVTABLE playback_queue_callback : public service_base
+{
+public:
+ enum t_change_origin {
+ changed_user_added,
+ changed_user_removed,
+ changed_playback_advance,
+ };
+ virtual void on_changed(t_change_origin p_origin) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(playback_queue_callback);
+};
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist_loader.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist_loader.cpp
new file mode 100644
index 0000000..511808a
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist_loader.cpp
@@ -0,0 +1,241 @@
+#include "foobar2000.h"
+
+static void process_path_internal(const char * p_path,const service_ptr_t<file> & p_reader,playlist_loader_callback & callback,playlist_loader_callback::t_entry_type type,const t_filestats & p_stats);
+
+namespace {
+ class archive_callback_impl : public archive_callback
+ {
+ public:
+ archive_callback_impl(playlist_loader_callback & p_callback) : m_callback(p_callback) {}
+ bool on_entry(archive * owner,const char * p_path,const t_filestats & p_stats,const service_ptr_t<file> & p_reader)
+ {
+ process_path_internal(p_path,p_reader,m_callback,playlist_loader_callback::entry_directory_enumerated,p_stats);
+ return !m_callback.is_aborting();
+ }
+ bool is_aborting() const {return m_callback.is_aborting();}
+ abort_callback_event get_abort_event() const {return m_callback.get_abort_event();}
+ private:
+ playlist_loader_callback & m_callback;
+ };
+}
+
+void playlist_loader::g_load_playlist(const char * p_path,playlist_loader_callback & callback)
+{
+ TRACK_CALL_TEXT("playlist_loader::g_load_playlist");
+ pfc::string8 filename;
+
+ filename = file_path_canonical(p_path);
+
+ service_enum_t<playlist_loader> e;
+ service_ptr_t<playlist_loader> l;
+
+ pfc::string_extension extension(filename);
+
+ service_ptr_t<file> l_file;
+
+ {
+ bool /*have_content_type, */have_extension;
+// string8 content_type;
+// have_content_type = r->get_content_type(content_type);
+ have_extension = extension.length()>0;
+
+ if (e.first(l)) do {
+ if (
+// have_content_type && l->is_our_content_type(content_type) ||
+ (have_extension && !stricmp_utf8(l->get_extension(),extension)))
+ {
+ if (l_file.is_empty()) {
+ filesystem::g_open_read(l_file,filename,callback);
+ }
+
+ TRACK_CODE("playlist_loader::open",l->open(filename,l_file,callback));
+ return;//success
+ }
+ } while(e.next(l));
+ }
+
+ throw exception_io_unsupported_format();
+}
+
+static void track_indexer__g_get_tracks_e(const char * p_path,const service_ptr_t<file> & p_reader,const t_filestats & p_stats,playlist_loader_callback::t_entry_type p_type,playlist_loader_callback & p_callback,bool & p_got_input)
+{
+ if (p_reader.is_empty() && filesystem::g_is_remote_safe(p_path))
+ {
+ metadb_handle_ptr handle;
+ p_callback.handle_create(handle,make_playable_location(p_path,0));
+ p_got_input = true;
+ p_callback.on_entry(handle,p_type,p_stats,true);
+ } else {
+ service_ptr_t<input_info_reader> instance;
+ input_entry::g_open_for_info_read(instance,p_reader,p_path,p_callback);
+
+ t_filestats stats = instance->get_file_stats(p_callback);
+
+ t_uint32 subsong,subsong_count = instance->get_subsong_count();
+ for(subsong=0;subsong<subsong_count;subsong++)
+ {
+ p_callback.check_e();
+ metadb_handle_ptr handle;
+ t_uint32 index = instance->get_subsong(subsong);
+ p_callback.handle_create(handle,make_playable_location(p_path,index));
+
+ p_got_input = true;
+ if (p_callback.want_info(handle,p_type,stats,true))
+ {
+ file_info_impl info;
+ instance->get_info(index,info,p_callback);
+ p_callback.on_entry_info(handle,p_type,stats,info,true);
+ }
+ else
+ {
+ p_callback.on_entry(handle,p_type,stats,true);
+ }
+ }
+ }
+}
+
+
+static void track_indexer__g_get_tracks_wrap(const char * p_path,const service_ptr_t<file> & p_reader,const t_filestats & p_stats,playlist_loader_callback::t_entry_type p_type,playlist_loader_callback & p_callback) {
+ bool got_input = false;
+ bool fail = false;
+ try {
+ track_indexer__g_get_tracks_e(p_path,p_reader,p_stats,p_type,p_callback,got_input);
+ } catch(exception_aborted) {
+ throw;
+ } catch(exception_io_unsupported_format) {
+ fail = true;
+ } catch(std::exception const & e) {
+ fail = true;
+ console::formatter() << "could not enumerate tracks (" << e << ") on:\n" << file_path_display(p_path);
+ }
+ if (fail) {
+ if (!got_input && !p_callback.is_aborting()) {
+ if (p_type == playlist_loader_callback::entry_user_requested)
+ {
+ metadb_handle_ptr handle;
+ p_callback.handle_create(handle,make_playable_location(p_path,0));
+ p_callback.on_entry(handle,p_type,p_stats,true);
+ }
+ }
+ }
+}
+
+
+static void process_path_internal(const char * p_path,const service_ptr_t<file> & p_reader,playlist_loader_callback & p_callback,playlist_loader_callback::t_entry_type p_type,const t_filestats & p_stats)
+{
+ //p_path must be canonical
+
+ p_callback.check_e();
+
+ p_callback.on_progress(p_path);
+
+
+ {
+ if (p_reader.is_empty()) {
+ directory_callback_impl directory_results(true);
+ try {
+ filesystem::g_list_directory(p_path,directory_results,p_callback);
+ for(t_size n=0;n<directory_results.get_count();n++) {
+ process_path_internal(directory_results.get_item(n),0,p_callback,playlist_loader_callback::entry_directory_enumerated,directory_results.get_item_stats(n));
+ }
+ return;
+ } catch(exception_aborted) {throw;}
+ catch(...) {
+ //do nothing, fall thru
+ //fixme - catch only filesystem exceptions?
+ }
+ }
+
+ bool found = false;
+
+
+ {
+ archive_callback_impl archive_results(p_callback);
+ service_enum_t<filesystem> e;
+ service_ptr_t<filesystem> f;
+ while(e.next(f)) {
+ p_callback.check_e();
+ service_ptr_t<archive> arch;
+ if (f->service_query_t(arch)) {
+ if (p_reader.is_valid()) p_reader->reopen(p_callback);
+
+ try {
+ TRACK_CODE("archive::archive_list",arch->archive_list(p_path,p_reader,archive_results,true));
+ return;
+ } catch(exception_aborted) {throw;}
+ catch(...) {}
+ }
+ }
+ }
+ }
+
+
+
+ {
+ service_ptr_t<link_resolver> ptr;
+ if (link_resolver::g_find(ptr,p_path))
+ {
+ if (p_reader.is_valid()) p_reader->reopen(p_callback);
+
+ pfc::string8 temp;
+ try {
+ TRACK_CODE("link_resolver::resolve",ptr->resolve(p_reader,p_path,temp,p_callback));
+
+ track_indexer__g_get_tracks_wrap(temp,0,filestats_invalid,playlist_loader_callback::entry_from_playlist,p_callback);
+ return;//success
+ } catch(exception_aborted) {throw;}
+ catch(...) {}
+ }
+ }
+
+ track_indexer__g_get_tracks_wrap(p_path,p_reader,p_stats,p_type,p_callback);
+}
+
+void playlist_loader::g_process_path(const char * p_filename,playlist_loader_callback & callback,playlist_loader_callback::t_entry_type type)
+{
+ TRACK_CALL_TEXT("playlist_loader::g_process_path");
+
+ file_path_canonical filename(p_filename);
+
+ process_path_internal(filename,0,callback,type,filestats_invalid);
+}
+
+void playlist_loader::g_save_playlist(const char * p_filename,const pfc::list_base_const_t<metadb_handle_ptr> & data,abort_callback & p_abort)
+{
+ TRACK_CALL_TEXT("playlist_loader::g_save_playlist");
+ pfc::string8 filename;
+ filesystem::g_get_canonical_path(p_filename,filename);
+ try {
+ service_ptr_t<file> r;
+ filesystem::g_open(r,filename,filesystem::open_mode_write_new,p_abort);
+
+ pfc::string_extension ext(filename);
+
+ service_enum_t<playlist_loader> e;
+ service_ptr_t<playlist_loader> l;
+ if (e.first(l)) do {
+ if (l->can_write() && !stricmp_utf8(ext,l->get_extension())) {
+ try {
+ TRACK_CODE("playlist_loader::write",l->write(filename,r,data,p_abort));
+ return;
+ } catch(exception_io_data) {}
+ }
+ } while(e.next(l));
+ throw exception_io_data();
+ } catch(...) {
+ try {filesystem::g_remove(filename,p_abort);} catch(...) {}
+ throw;
+ }
+}
+
+
+bool playlist_loader::g_process_path_ex(const char * filename,playlist_loader_callback & callback,playlist_loader_callback::t_entry_type type)
+{
+ try {
+ g_load_playlist(filename,callback);
+ return true;
+ } catch(exception_io_unsupported_format) {//not a playlist format
+ g_process_path(filename,callback,type);
+ return false;
+ }
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist_loader.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist_loader.h
new file mode 100644
index 0000000..40a226a
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist_loader.h
@@ -0,0 +1,136 @@
+#ifndef _PLAYLIST_LOADER_H_
+#define _PLAYLIST_LOADER_H_
+
+//! Callback interface receiving item locations from playlist loader. Also inherits abort_callback methods and can be passed to functions that require an abort_callback. \n
+//! See playlist_loader_callback_impl for a basic implementation of playlist_loader_callback. Typically, you call one of standard services such as playlist_incoming_item_filter instead of implementing this interface and calling playlist_loader methods directly.
+class NOVTABLE playlist_loader_callback : public abort_callback {
+public:
+ //! Enumeration type representing origin of item passed to playlist_loader_callback.
+ enum t_entry_type {
+ //! User-requested (such as directly dropped to window or picked in openfiledialog).
+ entry_user_requested,
+ //! From directory content enumeration.
+ entry_directory_enumerated,
+ //! Referenced by playlist file.
+ entry_from_playlist,
+ };
+ //! Indicates specified path being processed; provided for updating GUI. Note that optimally GUI should not be updated every time this is called because that could introduce a bottleneck.
+ virtual void on_progress(const char * p_path) = 0;
+
+ //! Receives an item from one of playlist_loader functions.
+ //! @param p_item Item location, in form of metadb_handle pointer.
+ //! @param p_type Origin of this item - see t_entry_type for more info.
+ //! @param p_stats File stats of this item; set to filestats_invalid if not available.
+ //! @param p_fresh Fresh flag; indicates whether stats are directly from filesystem (true) or as stored earlier in a playlist file (false).
+ virtual void on_entry(const metadb_handle_ptr & p_item,t_entry_type p_type,const t_filestats & p_stats,bool p_fresh) = 0;
+ //! Queries whether file_info for specified item is requested. In typical scenario, if want_info() returns false, on_entry() will be called with same parameters; otherwise caller will attempt to read info from the item and call on_entry_info() with same parameters and file_info read from the item.
+ //! @param p_item Item location, in form of metadb_handle pointer.
+ //! @param p_type Origin of this item - see t_entry_type for more info.
+ //! @param p_stats File stats of this item; set to filestats_invalid if not available.
+ //! @param p_fresh Fresh flag; indicates whether stats are directly from filesystem (true) or as stored earlier in a playlist file (false).
+ virtual bool want_info(const metadb_handle_ptr & p_item,t_entry_type p_type,const t_filestats & p_stats,bool p_fresh) = 0;
+ //! Receives an item from one of playlist_loader functions; including file_info data. Except for file_info to be typically used as hint for metadb backend, behavior of this method is same as on_entry().
+ //! @param p_item Item location, in form of metadb_handle pointer.
+ //! @param p_type Origin of this item - see t_entry_type for more info.
+ //! @param p_stats File stats of this item; set to filestats_invalid if not available.
+ //! @param p_info Information about the item, read from the file directly (if p_fresh is set to true) or from e.g. playlist file (if p_fresh is set to false).
+ //! @param p_fresh Fresh flag; indicates whether stats are directly from filesystem (true) or as stored earlier in a playlist file (false).
+ virtual void on_entry_info(const metadb_handle_ptr & p_item,t_entry_type p_type,const t_filestats & p_stats,const file_info & p_info,bool p_fresh) = 0;
+
+ //! Same as metadb::handle_create(); provided here to avoid repeated metadb instantiation bottleneck since calling code will need this function often.
+ virtual void handle_create(metadb_handle_ptr & p_out,const playable_location & p_location) = 0;
+
+protected:
+ playlist_loader_callback() {}
+ ~playlist_loader_callback() {}
+};
+
+//! Basic implementation of playlist_loader_callback.
+class playlist_loader_callback_impl : public playlist_loader_callback {
+public:
+
+ playlist_loader_callback_impl(abort_callback & p_abort) : m_abort(p_abort) {}
+
+ bool is_aborting() const {return m_abort.is_aborting();}
+ abort_callback_event get_abort_event() const {return m_abort.get_abort_event();}
+
+ const metadb_handle_ptr & get_item(t_size idx) const {return m_data[idx];}
+ const metadb_handle_ptr & operator[](t_size idx) const {return m_data[idx];}
+ t_size get_count() const {return m_data.get_count();}
+
+ const metadb_handle_list & get_data() const {return m_data;}
+
+ void on_progress(const char * path) {}
+
+ void on_entry(const metadb_handle_ptr & ptr,t_entry_type type,const t_filestats & p_stats,bool p_fresh) {m_data.add_item(ptr);}
+ bool want_info(const metadb_handle_ptr & ptr,t_entry_type type,const t_filestats & p_stats,bool p_fresh) {return false;}
+ void on_entry_info(const metadb_handle_ptr & ptr,t_entry_type type,const t_filestats & p_stats,const file_info & p_info,bool p_fresh) {m_data.add_item(ptr);}
+
+ void handle_create(metadb_handle_ptr & p_out,const playable_location & p_location) {m_api->handle_create(p_out,p_location);}
+
+private:
+ metadb_handle_list m_data;
+ abort_callback & m_abort;
+ static_api_ptr_t<metadb> m_api;
+};
+
+//! Service handling playlist file operations. There are multiple implementations handling different playlist formats; you can add new implementations to allow new custom playlist file formats to be read or written.\n
+//! Also provides static helper functions for turning a filesystem path into a list of playable item locations. \n
+//! Note that you should typically call playlist_incoming_item_filter methods instead of calling playlist_loader methods directly to get a list of playable items from a specified path; this way you get a core-implemented threading and abortable dialog displaying progress.\n
+//! To register your own implementation, use playlist_loader_factory_t template.\n
+//! To call existing implementations, use static helper methods of playlist_loader class.
+class NOVTABLE playlist_loader : public service_base {
+public:
+ //! Parses specified playlist file into list of playable locations. Throws exception_io or derivatives on failure, exception_aborted on abort. If specified file is not a recognized playlist file, exception_io_unsupported_format is thrown.
+ //! @param p_path Path of playlist file to parse. Used for relative path handling purposes (p_file parameter is used for actual file access).
+ //! @param p_file File interface to use for reading. Read/write pointer must be set to beginning by caller before calling.
+ //! @param p_callback Callback object receiving enumerated playable item locations as well as signaling user aborting the operation.
+ virtual void open(const char * p_path, const service_ptr_t<file> & p_file,playlist_loader_callback & p_callback) = 0;
+ //! Writes a playlist file containing specific item list to specified file. Will fail (pfc::exception_not_implemented) if specified playlist_loader is read-only (can_write() returns false).
+ //! @param p_path Path of playlist file to write. Used for relative path handling purposes (p_file parameter is used for actual file access).
+ //! @param p_file File interface to use for writing. Caller should ensure that the file is empty (0 bytes long) before calling.
+ //! @param p_data List of items to save to playlist file.
+ //! @param p_abort abort_callback object signaling user aborting the operation. Note that aborting a save playlist operation will most likely leave user with corrupted/incomplete file.
+ virtual void write(const char * p_path, const service_ptr_t<file> & p_file,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,abort_callback & p_abort) = 0;
+ //! Returns extension of file format handled by this playlist_loader implementation (a UTF-8 encoded null-terminated string).
+ virtual const char * get_extension() = 0;
+ //! Returns whether this playlist_loader implementation supports writing. If can_write() returns false, all write() calls will fail.
+ virtual bool can_write() = 0;
+ //! Returns whether specified content type is one of playlist types supported by this playlist_loaded implementation or not.
+ //! @param p_content_type Content type to query, a UTF-8 encoded null-terminated string.
+ virtual bool is_our_content_type(const char* p_content_type) = 0;
+ //! Returns whether playlist format extension supported by this implementation should be listed on file types associations page.
+ virtual bool is_associatable() = 0;
+
+ //! Attempts to load a playlist file from specified filesystem path. Throws exception_io or derivatives on failure, exception_aborted on abort. If specified file is not a recognized playlist file, exception_io_unsupported_format is thrown.
+ //! @param p_path Filesystem path to load playlist from, a UTF-8 encoded null-terminated string.
+ //! @param p_callback Callback object receiving enumerated playable item locations as well as signaling user aborting the operation.
+ static void g_load_playlist(const char * p_path,playlist_loader_callback & p_callback);
+
+ //! Saves specified list of locations into a playlist file. Throws exception_io or derivatives on failure, exception_aborted on abort.
+ //! @param p_path Filesystem path to save playlist to, a UTF-8 encoded null-terminated string.
+ //! @param p_data List of items to save to playlist file.
+ //! @param p_abort abort_callback object signaling user aborting the operation. Note that aborting a save playlist operation will most likely leave user with corrupted/incomplete file.
+ static void g_save_playlist(const char * p_path,const pfc::list_base_const_t<metadb_handle_ptr> & p_data,abort_callback & p_abort);
+
+ //! Processes specified path to generate list of playable items. Includes recursive directory/archive enumeration. \n
+ //! Does not touch playlist files encountered - use g_process_path_ex() if specified path is possibly a playlist file; playlist files found inside directories or archives are ignored regardless.\n
+ //! Warning: caller must handle exceptions which will occur in case of I/O failure.
+ //! @param p_path Filesystem path to process; a UTF-8 encoded null-terminated string.
+ //! @param p_callback Callback object receiving enumerated playable item locations as well as signaling user aborting the operation.
+ //! @param p_type Origin of p_path string. Reserved for internal use in recursive calls, should be left at default value; it controls various internal behaviors.
+ static void g_process_path(const char * p_path,playlist_loader_callback & p_callback,playlist_loader_callback::t_entry_type p_type = playlist_loader_callback::entry_user_requested);
+
+ //! Calls attempts to process specified path as a playlist; if that fails (i.e. not a playlist), calls g_process_path with same parameters. See g_process_path for parameter descriptions. \n
+ //! Warning: caller must handle exceptions which will occur in case of I/O failure or playlist parsing failure.
+ //! @returns True if specified path was processed as a playlist file, false otherwise (relevant in some scenarios where output is sorted after loading, playlist file contents should not be sorted).
+ static bool g_process_path_ex(const char * p_path,playlist_loader_callback & p_callback,playlist_loader_callback::t_entry_type p_type = playlist_loader_callback::entry_user_requested);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(playlist_loader);
+};
+
+template<typename t_myclass>
+class playlist_loader_factory_t : public service_factory_single_t<t_myclass> {};
+
+
+#endif //_PLAYLIST_LOADER_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist_lock.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist_lock.cpp
new file mode 100644
index 0000000..a8e9aba
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/playlist_lock.cpp
@@ -0,0 +1 @@
+#include "foobar2000.h"
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/popup_message.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/popup_message.cpp
new file mode 100644
index 0000000..7c62cb9
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/popup_message.cpp
@@ -0,0 +1,6 @@
+#include "foobar2000.h"
+
+void popup_message::g_show_ex(const char * p_msg,unsigned p_msg_length,const char * p_title,unsigned p_title_length,t_icon p_icon)
+{
+ static_api_ptr_t<popup_message>()->show_ex(p_msg,p_msg_length,p_title,p_title_length,p_icon);
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/popup_message.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/popup_message.h
new file mode 100644
index 0000000..34beef0
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/popup_message.h
@@ -0,0 +1,34 @@
+#ifndef _POPUP_MESSAGE_H_
+#define _POPUP_MESSAGE_H_
+
+
+//! This interface allows you to show generic nonmodal noninteractive dialog with a text message. This should be used instead of MessageBox where possible.\n
+//! Usage: use popup_message::g_show / popup_message::g_show_ex static helpers, or static_api_ptr_t<popup_message>.\n
+//! Note that all strings are UTF-8.
+
+class NOVTABLE popup_message : public service_base {
+public:
+ enum t_icon {icon_information, icon_error, icon_query};
+ //! Activates the popup dialog; returns immediately (the dialog remains visible).
+ //! @param p_msg Message to show (UTF-8 encoded string).
+ //! @param p_msg_length Length limit of message string to show, in bytes (actual string may be shorter if null terminator is encountered before). Set this to infinite to use plain null-terminated strings.
+ //! @param p_title Title of dialog to show (UTF-8 encoded string).
+ //! @param p_title_length Length limit of the title string, in bytes (actual string may be shorter if null terminator is encountered before). Set this to infinite to use plain null-terminated strings.
+ //! @param p_icon Icon of the dialog - can be set to icon_information, icon_error or icon_query.
+ virtual void show_ex(const char * p_msg,unsigned p_msg_length,const char * p_title,unsigned p_title_length,t_icon p_icon = icon_information) = 0;
+
+ //! Activates the popup dialog; returns immediately (the dialog remains visible); helper function built around show_ex(), takes null terminated strings with no length limit parameters.
+ //! @param p_msg Message to show (UTF-8 encoded string).
+ //! @param p_title Title of dialog to show (UTF-8 encoded string).
+ //! @param p_icon Icon of the dialog - can be set to icon_information, icon_error or icon_query.
+ inline void show(const char * p_msg,const char * p_title,t_icon p_icon = icon_information) {show_ex(p_msg,infinite,p_title,infinite,p_icon);}
+
+ //! Static helper function instantiating the service and activating the message dialog. See show_ex() for description of parameters.
+ static void g_show_ex(const char * p_msg,unsigned p_msg_length,const char * p_title,unsigned p_title_length,t_icon p_icon = icon_information);
+ //! Static helper function instantiating the service and activating the message dialog. See show() for description of parameters.
+ static inline void g_show(const char * p_msg,const char * p_title,t_icon p_icon = icon_information) {g_show_ex(p_msg,infinite,p_title,infinite,p_icon);}
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(popup_message);
+};
+
+#endif //_POPUP_MESSAGE_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/preferences_page.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/preferences_page.cpp
new file mode 100644
index 0000000..c60c963
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/preferences_page.cpp
@@ -0,0 +1,12 @@
+#include "foobar2000.h"
+
+bool preferences_page::get_help_url(pfc::string_base & p_out)
+{
+ p_out = "http://help.foobar2000.org/";
+ p_out += core_version_info::g_get_version_string();
+ p_out += "/preferences/";
+ p_out += (const char*) pfc::print_guid(get_guid());
+ p_out += "/";
+ p_out += get_name();
+ return true;
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/preferences_page.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/preferences_page.h
new file mode 100644
index 0000000..cfa18ab
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/preferences_page.h
@@ -0,0 +1,82 @@
+#ifndef _FOOBAR2000_SDK_PREFERENCES_PAGE_H_
+#define _FOOBAR2000_SDK_PREFERENCES_PAGE_H_
+
+//! Implementing this service will generate a page in preferences dialog. Use preferences_page_factory_t template to register.
+class NOVTABLE preferences_page : public service_base {
+public:
+ //! Creates preferences page dialog window. It is safe to assume that two dialog instances will never coexist. Caller is responsible for embedding it into preferences dialog itself.
+ virtual HWND create(HWND p_parent) = 0;
+ //! Retrieves name of the prefernces page to be displayed in preferences tree (static string).
+ virtual const char * get_name() = 0;
+ //! Retrieves GUID of the page.
+ virtual GUID get_guid() = 0;
+ //! Retrieves GUID of parent page/branch of this page. See preferences_page::guid_* constants for list of standard parent GUIDs. Can also be a GUID of another page or a branch (see: preferences_branch).
+ virtual GUID get_parent_guid() = 0;
+ //! Queries whether this page supports "reset page" feature.
+ virtual bool reset_query() = 0;
+ //! Activates "reset page" feature. It is safe to assume that the preferences page dialog does not exist at the point this is called (caller destroys it before calling reset and creates it again afterwards).
+ virtual void reset() = 0;
+ //! Retrieves help URL. Without overriding it, it will redirect to foobar2000 wiki.
+ virtual bool get_help_url(pfc::string_base & p_out);
+
+ static const GUID guid_root, guid_hidden, guid_tools,guid_core,guid_display,guid_playback,guid_visualisations,guid_input,guid_tag_writing,guid_media_library;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(preferences_page);
+};
+
+class NOVTABLE preferences_page_v2 : public preferences_page {
+public:
+ //! Allows custom sorting order of preferences pages. Return lower value for higher priority (lower resulting index in the list). When sorting priority of two items matches, alphabetic sorting is used. Return 0 to use default alphabetic sorting without overriding priority.
+ virtual double get_sort_priority() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(preferences_page_v2,preferences_page);
+};
+
+template<class T>
+class preferences_page_factory_t : public service_factory_single_t<T> {};
+
+//! Creates a preferences branch - an empty page that only serves as a parent for other pages and is hidden when no child pages exist. Instead of implementing this, simply use preferences_branch_factory class to declare a preferences branch with specified parameters.
+class NOVTABLE preferences_branch : public service_base {
+public:
+ //! Retrieves name of the preferences branch.
+ virtual const char * get_name() = 0;
+ //! Retrieves GUID of the preferences branch. Use this GUID as parent GUID for pages/branches nested in this branch.
+ virtual GUID get_guid() = 0;
+ //! Retrieves GUID of parent page/branch of this branch. See preferences_page::guid_* constants for list of standard parent GUIDs. Can also be a GUID of another branch or a page.
+ virtual GUID get_parent_guid() = 0;
+
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(preferences_branch);
+};
+
+class preferences_branch_v2 : public preferences_branch {
+public:
+ //! Allows custom sorting order of preferences pages. Return lower value for higher priority (lower resulting index in the list). When sorting priority of two items matches, alphabetic sorting is used. Return 0 to use default alphabetic sorting without overriding priority.
+ virtual double get_sort_priority() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(preferences_branch_v2,preferences_branch);
+};
+
+class preferences_branch_impl : public preferences_branch_v2 {
+public:
+ preferences_branch_impl(const GUID & p_guid,const GUID & p_parent,const char * p_name,double p_sort_priority = 0) : m_guid(p_guid), m_parent(p_parent), m_name(p_name), m_sort_priority(p_sort_priority) {}
+ const char * get_name() {return m_name;}
+ GUID get_guid() {return m_guid;}
+ GUID get_parent_guid() {return m_parent;}
+ double get_sort_priority() {return m_sort_priority;}
+private:
+ const GUID m_guid,m_parent;
+ const pfc::string8 m_name;
+ const double m_sort_priority;
+};
+
+typedef service_factory_single_t<preferences_branch_impl> __preferences_branch_factory;
+
+//! Instantiating this class declares a preferences branch with specified parameters.\n
+//! Usage: static preferences_branch_factory g_mybranch(mybranchguid,parentbranchguid,"name of my preferences branch goes here");
+class preferences_branch_factory : public __preferences_branch_factory {
+public:
+ preferences_branch_factory(const GUID & p_guid,const GUID & p_parent,const char * p_name,double p_sort_priority = 0) : __preferences_branch_factory(p_guid,p_parent,p_name,p_sort_priority) {}
+};
+
+#endif //_FOOBAR2000_SDK_PREFERENCES_PAGE_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/replaygain.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/replaygain.cpp
new file mode 100644
index 0000000..1011745
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/replaygain.cpp
@@ -0,0 +1,223 @@
+#include "foobar2000.h"
+
+void t_replaygain_config::reset()
+{
+ m_source_mode = source_mode_none;
+ m_processing_mode = processing_mode_none;
+ m_preamp_without_rg = 0;
+ m_preamp_with_rg = 0;
+}
+
+audio_sample t_replaygain_config::query_scale(const file_info & p_info) const
+{
+ const audio_sample peak_margin = 1.0;//used to be 0.999 but it must not trigger on lossless
+
+ audio_sample peak = peak_margin;
+ audio_sample gain = 0;
+
+ bool have_rg_gain = false, have_rg_peak = false;
+
+ if (m_source_mode == source_mode_track || m_source_mode == source_mode_album)
+ {
+ replaygain_info info = p_info.get_replaygain();
+ float gain_select = replaygain_info::gain_invalid, peak_select = replaygain_info::peak_invalid;
+ if (m_source_mode == source_mode_track)
+ {
+ if (info.is_track_gain_present()) {gain = info.m_track_gain; have_rg_gain = true; }
+ else if (info.is_album_gain_present()) {gain = info.m_album_gain; have_rg_gain = true; }
+ if (info.is_track_peak_present()) {peak = info.m_track_peak; have_rg_peak = true; }
+ else if (info.is_album_peak_present()) {peak = info.m_album_peak; have_rg_peak = true; }
+ }
+ else
+ {
+ if (info.is_album_gain_present()) {gain = info.m_album_gain; have_rg_gain = true; }
+ else if (info.is_track_gain_present()) {gain = info.m_track_gain; have_rg_gain = true; }
+ if (info.is_album_peak_present()) {peak = info.m_album_peak; have_rg_peak = true; }
+ else if (info.is_track_peak_present()) {peak = info.m_track_peak; have_rg_peak = true; }
+ }
+ }
+
+ gain += have_rg_gain ? m_preamp_with_rg : m_preamp_without_rg;
+
+ audio_sample scale = 1.0;
+
+ if (m_processing_mode == processing_mode_gain || m_processing_mode == processing_mode_gain_and_peak)
+ {
+ scale *= audio_math::gain_to_scale(gain);
+ }
+
+ if (m_processing_mode == processing_mode_peak || m_processing_mode == processing_mode_gain_and_peak)
+ {
+ if (scale * peak > peak_margin)
+ scale = (audio_sample)(peak_margin / peak);
+ }
+
+ return scale;
+}
+
+audio_sample t_replaygain_config::query_scale(const metadb_handle_ptr & p_object) const
+{
+ audio_sample rv = 1.0;
+ p_object->metadb_lock();
+ const file_info * info;
+ if (p_object->get_info_async_locked(info))
+ rv = query_scale(*info);
+ p_object->metadb_unlock();
+ return rv;
+}
+
+audio_sample replaygain_manager::core_settings_query_scale(const file_info & p_info)
+{
+ t_replaygain_config temp;
+ get_core_settings(temp);
+ return temp.query_scale(p_info);
+}
+
+audio_sample replaygain_manager::core_settings_query_scale(const metadb_handle_ptr & info)
+{
+ t_replaygain_config temp;
+ get_core_settings(temp);
+ return temp.query_scale(info);
+}
+
+//enum t_source_mode {source_mode_none,source_mode_track,source_mode_album};
+//enum t_processing_mode {processing_mode_none,processing_mode_gain,processing_mode_gain_and_peak,processing_mode_peak};
+namespace {
+class format_dbdelta
+{
+public:
+ format_dbdelta(double p_val);
+ operator const char*() const {return m_buffer;}
+private:
+ pfc::string_fixed_t<128> m_buffer;
+};
+static const char * querysign(int val) {
+ return val<0 ? "-" : val>0 ? "+" : "\xc2\xb1";
+}
+
+format_dbdelta::format_dbdelta(double p_val) {
+ int val = (int)(p_val * 10);
+ m_buffer << querysign(val) << (abs(val)/10) << "." << (abs(val)%10) << "dB";
+}
+}
+void t_replaygain_config::format_name(pfc::string_base & p_out) const
+{
+ switch(m_processing_mode)
+ {
+ case processing_mode_none:
+ p_out = "None.";
+ break;
+ case processing_mode_gain:
+ switch(m_source_mode)
+ {
+ case source_mode_none:
+ if (m_preamp_without_rg == 0) p_out = "None.";
+ else p_out = pfc::string_formatter() << "Preamp : " << format_dbdelta(m_preamp_without_rg);
+ break;
+ case source_mode_track:
+ {
+ pfc::string_formatter fmt;
+ fmt << "Apply track gain";
+ if (m_preamp_without_rg != 0 || m_preamp_with_rg != 0) fmt << ", with preamp";
+ fmt << ".";
+ p_out = fmt;
+ }
+ break;
+ case source_mode_album:
+ {
+ pfc::string_formatter fmt;
+ fmt << "Apply album gain";
+ if (m_preamp_without_rg != 0 || m_preamp_with_rg != 0) fmt << ", with preamp";
+ fmt << ".";
+ p_out = fmt;
+ }
+ break;
+ };
+ break;
+ case processing_mode_gain_and_peak:
+ switch(m_source_mode)
+ {
+ case source_mode_none:
+ if (m_preamp_without_rg >= 0) p_out = "None.";
+ else p_out = pfc::string_formatter() << "Preamp : " << format_dbdelta(m_preamp_without_rg);
+ break;
+ case source_mode_track:
+ {
+ pfc::string_formatter fmt;
+ fmt << "Apply track gain";
+ if (m_preamp_without_rg != 0 || m_preamp_with_rg != 0) fmt << ", with preamp";
+ fmt << ", prevent clipping according to track peak.";
+ p_out = fmt;
+ }
+ break;
+ case source_mode_album:
+ {
+ pfc::string_formatter fmt;
+ fmt << "Apply album gain";
+ if (m_preamp_without_rg != 0 || m_preamp_with_rg != 0) fmt << ", with preamp";
+ fmt << ", prevent clipping according to album peak.";
+ p_out = fmt;
+ }
+ break;
+ };
+ break;
+ case processing_mode_peak:
+ switch(m_source_mode)
+ {
+ case source_mode_none:
+ p_out = "None.";
+ break;
+ case source_mode_track:
+ p_out = "Prevent clipping according to track peak.";
+ break;
+ case source_mode_album:
+ p_out = "Prevent clipping according to album peak.";
+ break;
+ };
+ break;
+ }
+}
+
+bool t_replaygain_config::is_active() const
+{
+ switch(m_processing_mode)
+ {
+ case processing_mode_none:
+ return false;
+ case processing_mode_gain:
+ switch(m_source_mode)
+ {
+ case source_mode_none:
+ return m_preamp_without_rg != 0;
+ case source_mode_track:
+ return true;
+ case source_mode_album:
+ return true;
+ };
+ return false;
+ case processing_mode_gain_and_peak:
+ switch(m_source_mode)
+ {
+ case source_mode_none:
+ return m_preamp_without_rg < 0;
+ case source_mode_track:
+ return true;
+ case source_mode_album:
+ return true;
+ };
+ return false;
+ case processing_mode_peak:
+ switch(m_source_mode)
+ {
+ case source_mode_none:
+ return false;
+ case source_mode_track:
+ return true;
+ case source_mode_album:
+ return true;
+ };
+ return false;
+ default:
+ return false;
+ }
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/replaygain.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/replaygain.h
new file mode 100644
index 0000000..4dc3ff4
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/replaygain.h
@@ -0,0 +1,53 @@
+#ifndef _FOOBAR2000_SDK_REPLAYGAIN_H_
+#define _FOOBAR2000_SDK_REPLAYGAIN_H_
+
+//! Structure storing ReplayGain configuration: album/track source data modes, gain/peak processing modes and preamp values.
+struct t_replaygain_config
+{
+ enum t_source_mode {source_mode_none,source_mode_track,source_mode_album};
+ enum t_processing_mode {processing_mode_none,processing_mode_gain,processing_mode_gain_and_peak,processing_mode_peak};
+
+ t_replaygain_config() {reset();}
+ t_replaygain_config(const t_replaygain_config & p_source) {*this = p_source;}
+ t_replaygain_config(t_source_mode p_source_mode,t_processing_mode p_processing_mode,float p_preamp_without_rg, float p_preamp_with_rg)
+ : m_source_mode(p_source_mode), m_processing_mode(p_processing_mode), m_preamp_without_rg(p_preamp_without_rg), m_preamp_with_rg(p_preamp_with_rg) {}
+
+
+ t_source_mode m_source_mode;
+ t_processing_mode m_processing_mode;
+ float m_preamp_without_rg, m_preamp_with_rg;//preamp values in dB
+
+ void reset();
+ audio_sample query_scale(const file_info & info) const;
+ audio_sample query_scale(const metadb_handle_ptr & info) const;
+
+ void format_name(pfc::string_base & p_out) const;
+ bool is_active() const;
+};
+
+//! Core service providing methods to retrieve/alter playback ReplayGain settings, as well as use ReplayGain configuration dialog.
+class NOVTABLE replaygain_manager : public service_base {
+public:
+ //! Retrieves playback ReplayGain settings.
+ virtual void get_core_settings(t_replaygain_config & p_out) = 0;
+
+ //! Creates embedded version of ReplayGain settings dialog. Note that embedded dialog sends WM_COMMAND with id/BN_CLICKED to parent window when user makes changes to settings.
+ virtual HWND configure_embedded(const t_replaygain_config & p_initdata,HWND p_parent,unsigned p_id,bool p_from_modal) = 0;
+ //! Retrieves settings from embedded version of ReplayGain settings dialog.
+ virtual void configure_embedded_retrieve(HWND wnd,t_replaygain_config & p_data) = 0;
+
+ //! Shows popup/modal version of ReplayGain settings dialog. Returns true when user changed the settings, false when user cancelled the operation. Title parameter can be null to use default one.
+ virtual bool configure_popup(t_replaygain_config & p_data,HWND p_parent,const char * p_title) = 0;
+
+ //! Alters playback ReplayGain settings.
+ virtual void set_core_settings(const t_replaygain_config & p_config) = 0;
+
+ //! Helper; queries scale value for specified item according to core playback settings.
+ audio_sample core_settings_query_scale(const file_info & p_info);
+ //! Helper; queries scale value for specified item according to core playback settings.
+ audio_sample core_settings_query_scale(const metadb_handle_ptr & info);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(replaygain_manager);
+};
+
+#endif //_FOOBAR2000_SDK_REPLAYGAIN_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/replaygain_info.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/replaygain_info.cpp
new file mode 100644
index 0000000..e1c5640
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/replaygain_info.cpp
@@ -0,0 +1,136 @@
+#include "foobar2000.h"
+
+bool replaygain_info::g_format_gain(float p_value,char p_buffer[text_buffer_size])
+{
+ fpu_control_roundnearest bah;
+ if (p_value == gain_invalid)
+ {
+ p_buffer[0] = 0;
+ return false;
+ }
+ else
+ {
+ pfc::float_to_string(p_buffer,text_buffer_size - 4,p_value,2,true);
+ strcat(p_buffer," dB");
+ return true;
+ }
+}
+
+bool replaygain_info::g_format_peak(float p_value,char p_buffer[text_buffer_size])
+{
+ fpu_control_roundnearest bah;
+ if (p_value == peak_invalid)
+ {
+ p_buffer[0] = 0;
+ return false;
+ }
+ else
+ {
+ pfc::float_to_string(p_buffer,text_buffer_size,p_value,6,false);
+ return true;
+ }
+}
+
+void replaygain_info::reset()
+{
+ m_album_gain = gain_invalid;
+ m_track_gain = gain_invalid;
+ m_album_peak = peak_invalid;
+ m_track_peak = peak_invalid;
+}
+
+static const char meta_album_gain[] = "replaygain_album_gain", meta_album_peak[] = "replaygain_album_peak", meta_track_gain[] = "replaygain_track_gain", meta_track_peak[] = "replaygain_track_peak";
+
+bool replaygain_info::g_is_meta_replaygain(const char * p_name,t_size p_name_len)
+{
+ return
+ stricmp_utf8_ex(p_name,p_name_len,meta_album_gain,infinite) == 0 ||
+ stricmp_utf8_ex(p_name,p_name_len,meta_album_peak,infinite) == 0 ||
+ stricmp_utf8_ex(p_name,p_name_len,meta_track_gain,infinite) == 0 ||
+ stricmp_utf8_ex(p_name,p_name_len,meta_track_peak,infinite) == 0;
+}
+
+bool replaygain_info::set_from_meta_ex(const char * p_name,t_size p_name_len,const char * p_value,t_size p_value_len)
+{
+ fpu_control_roundnearest bah;
+ if (stricmp_utf8_ex(p_name,p_name_len,meta_album_gain,infinite) == 0)
+ {
+ m_album_gain = (float)pfc::string_to_float(p_value,p_value_len);
+ return true;
+ }
+ else if (stricmp_utf8_ex(p_name,p_name_len,meta_album_peak,infinite) == 0)
+ {
+ m_album_peak = (float)pfc::string_to_float(p_value,p_value_len);
+ if (m_album_peak < 0) m_album_peak = 0;
+ return true;
+ }
+ else if (stricmp_utf8_ex(p_name,p_name_len,meta_track_gain,infinite) == 0)
+ {
+ m_track_gain = (float)pfc::string_to_float(p_value,p_value_len);
+ return true;
+ }
+ else if (stricmp_utf8_ex(p_name,p_name_len,meta_track_peak,infinite) == 0)
+ {
+ m_track_peak = (float)pfc::string_to_float(p_value,p_value_len);
+ if (m_track_peak < 0) m_track_peak = 0;
+ return true;
+ }
+ else return false;
+}
+
+
+t_size replaygain_info::get_value_count()
+{
+ t_size ret = 0;
+ if (is_album_gain_present()) ret++;
+ if (is_album_peak_present()) ret++;
+ if (is_track_gain_present()) ret++;
+ if (is_track_peak_present()) ret++;
+ return ret;
+}
+
+void replaygain_info::set_album_gain_text(const char * p_text,t_size p_text_len)
+{
+ fpu_control_roundnearest bah;
+ if (p_text != 0 && p_text_len > 0 && *p_text != 0)
+ m_album_gain = (float)pfc::string_to_float(p_text,p_text_len);
+ else
+ remove_album_gain();
+}
+
+void replaygain_info::set_track_gain_text(const char * p_text,t_size p_text_len)
+{
+ fpu_control_roundnearest bah;
+ if (p_text != 0 && p_text_len > 0 && *p_text != 0)
+ m_track_gain = (float)pfc::string_to_float(p_text,p_text_len);
+ else
+ remove_track_gain();
+}
+
+void replaygain_info::set_album_peak_text(const char * p_text,t_size p_text_len)
+{
+ fpu_control_roundnearest bah;
+ if (p_text != 0 && p_text_len > 0 && *p_text != 0)
+ m_album_peak = (float)pfc::string_to_float(p_text,p_text_len);
+ else
+ remove_album_peak();
+}
+
+void replaygain_info::set_track_peak_text(const char * p_text,t_size p_text_len)
+{
+ fpu_control_roundnearest bah;
+ if (p_text != 0 && p_text_len > 0 && *p_text != 0)
+ m_track_peak = (float)pfc::string_to_float(p_text,p_text_len);
+ else
+ remove_track_peak();
+}
+
+replaygain_info replaygain_info::g_merge(replaygain_info r1,replaygain_info r2)
+{
+ replaygain_info ret = r1;
+ if (!ret.is_album_gain_present()) ret.m_album_gain = r2.m_album_gain;
+ if (!ret.is_album_peak_present()) ret.m_album_peak = r2.m_album_peak;
+ if (!ret.is_track_gain_present()) ret.m_track_gain = r2.m_track_gain;
+ if (!ret.is_track_peak_present()) ret.m_track_peak = r2.m_track_peak;
+ return ret;
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/resampler.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/resampler.h
new file mode 100644
index 0000000..1b3b7f3
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/resampler.h
@@ -0,0 +1,25 @@
+class NOVTABLE resampler_entry : public dsp_entry
+{
+public:
+ virtual bool is_conversion_supported(unsigned p_srate_from,unsigned p_srate_to) = 0;
+ virtual bool create_preset(dsp_preset & p_out,unsigned p_target_srate,float p_qualityscale) = 0;//p_qualityscale is 0...1
+ virtual float get_priority() = 0;//value is 0...1, where high-quality (SSRC etc) has 1
+
+ static bool g_get_interface(service_ptr_t<resampler_entry> & p_out,unsigned p_srate_from,unsigned p_srate_to);
+ static bool g_create(service_ptr_t<dsp> & p_out,unsigned p_srate_from,unsigned p_srate_to,float p_qualityscale);
+ static bool g_create_preset(dsp_preset & p_out,unsigned p_srate_from,unsigned p_srate_to,float p_qualityscale);
+
+ FB2K_MAKE_SERVICE_INTERFACE(resampler_entry,dsp_entry);
+};
+
+template<typename T>
+class resampler_entry_impl_t : public dsp_entry_impl_t<T,resampler_entry>
+{
+public:
+ bool is_conversion_supported(unsigned p_srate_from,unsigned p_srate_to) {return T::g_is_conversion_supported(p_srate_from,p_srate_to);}
+ bool create_preset(dsp_preset & p_out,unsigned p_target_srate,float p_qualityscale) {return T::g_create_preset(p_out,p_target_srate,p_qualityscale);}
+ float get_priority() {return T::g_get_priority();}
+};
+
+template<typename T>
+class resampler_factory_t : public service_factory_single_t<resampler_entry_impl_t<T> > {}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/service.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/service.cpp
new file mode 100644
index 0000000..dda21f0
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/service.cpp
@@ -0,0 +1,24 @@
+#include "foobar2000.h"
+#include "component.h"
+
+foobar2000_api * g_api;
+
+service_class_ref service_factory_base::enum_find_class(const GUID & p_guid)
+{
+ PFC_ASSERT(core_api::are_services_available() && g_api);
+ return g_api->service_enum_find_class(p_guid);
+}
+
+bool service_factory_base::enum_create(service_ptr_t<service_base> & p_out,service_class_ref p_class,t_size p_index)
+{
+ PFC_ASSERT(core_api::are_services_available() && g_api);
+ return g_api->service_enum_create(p_out,p_class,p_index);
+}
+
+t_size service_factory_base::enum_get_count(service_class_ref p_class)
+{
+ PFC_ASSERT(core_api::are_services_available() && g_api);
+ return g_api->service_enum_get_count(p_class);
+}
+
+service_factory_base * service_factory_base::__internal__list = NULL;
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/service.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/service.h
new file mode 100644
index 0000000..117f84e
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/service.h
@@ -0,0 +1,454 @@
+#ifndef _SERVICE_H_
+#define _SERVICE_H_
+
+typedef const void* service_class_ref;
+
+PFC_DECLARE_EXCEPTION(exception_service_not_found,pfc::exception,"Service not found");
+PFC_DECLARE_EXCEPTION(exception_service_extension_not_found,pfc::exception,"Service extension not found");
+PFC_DECLARE_EXCEPTION(exception_service_duplicated,pfc::exception,"Service duplicated");
+
+#ifdef _MSC_VER
+#define FOOGUIDDECL __declspec(selectany)
+#else
+#define FOOGUIDDECL
+#endif
+
+
+#define DECLARE_GUID(NAME,A,S,D,F,G,H,J,K,L,Z,X) FOOGUIDDECL const GUID NAME = {A,S,D,{F,G,H,J,K,L,Z,X}};
+#define DECLARE_CLASS_GUID(NAME,A,S,D,F,G,H,J,K,L,Z,X) FOOGUIDDECL const GUID NAME::class_guid = {A,S,D,{F,G,H,J,K,L,Z,X}};
+
+//! Special hack to ensure errors when someone tries to ->service_add_ref()/->service_release() on a service_ptr_t
+template<typename T> class service_obscure_refcounting : public T {
+private:
+ int service_add_ref() throw();
+ int service_release() throw();
+};
+
+//! Converts a service interface pointer to a pointer that obscures service counter functionality.
+template<typename T> static inline service_obscure_refcounting<T>* service_obscure_refcounting_cast(T * p_source) throw() {return static_cast<service_obscure_refcounting<T>*>(p_source);}
+
+//! Multiple inheritance SNAFU fix. In some cases, old service_release_safe method of service_base would not get a NULL this pointer when called on a NULL pointer.
+template<typename T> static void service_release_safe(T * p_ptr) throw() {
+ if (p_ptr != NULL) p_ptr->service_release();
+}
+
+//! Multiple inheritance SNAFU fix. In some cases, old service_add_ref_safe method of service_base would not get a NULL this pointer when called on a NULL pointer.
+template<typename T> static void service_add_ref_safe(T * p_ptr) throw() {
+ if (p_ptr != NULL) p_ptr->service_add_ref();
+}
+
+//! Autopointer class to be used with all services. Manages reference counter calls behind-the-scenes.
+template<typename T>
+class service_ptr_t {
+private:
+ typedef service_ptr_t<T> t_self;
+public:
+ inline service_ptr_t() throw() : m_ptr(NULL) {}
+ inline service_ptr_t(T* p_ptr) throw() : m_ptr(NULL) {copy(p_ptr);}
+ inline service_ptr_t(const t_self & p_source) throw() : m_ptr(NULL) {copy(p_source);}
+
+ template<typename t_source>
+ inline service_ptr_t(t_source * p_ptr) throw() : m_ptr(NULL) {copy(p_ptr);}
+
+ template<typename t_source>
+ inline service_ptr_t(const service_ptr_t<t_source> & p_source) throw() : m_ptr(NULL) {copy(p_source);}
+
+ inline ~service_ptr_t() throw() {service_release_safe(m_ptr);}
+
+ template<typename t_source>
+ void copy(t_source * p_ptr) throw() {
+ service_release_safe(m_ptr);
+ m_ptr = pfc::safe_ptr_cast<T>(p_ptr);
+ service_add_ref_safe(m_ptr);
+ }
+
+ template<typename t_source>
+ inline void copy(const service_ptr_t<t_source> & p_source) throw() {copy(p_source.get_ptr());}
+
+
+ inline const t_self & operator=(const t_self & p_source) throw() {copy(p_source); return *this;}
+ inline const t_self & operator=(T * p_ptr) throw() {copy(p_ptr); return *this;}
+
+ template<typename t_source> inline t_self & operator=(const service_ptr_t<t_source> & p_source) throw() {copy(p_source); return *this;}
+ template<typename t_source> inline t_self & operator=(t_source * p_ptr) throw() {copy(p_ptr); return *this;}
+
+ inline void release() throw() {
+ service_release_safe(m_ptr);
+ m_ptr = NULL;
+ }
+
+
+ inline service_obscure_refcounting<T>* operator->() const throw() {PFC_ASSERT(m_ptr != NULL);return service_obscure_refcounting_cast(m_ptr);}
+
+ inline T* get_ptr() const throw() {return m_ptr;}
+
+ inline bool is_valid() const throw() {return m_ptr != NULL;}
+ inline bool is_empty() const throw() {return m_ptr == NULL;}
+
+ inline bool operator==(const t_self & p_item) const throw() {return m_ptr == p_item.get_ptr();}
+ inline bool operator!=(const t_self & p_item) const throw() {return m_ptr != p_item.get_ptr();}
+ inline bool operator>(const t_self & p_item) const throw() {return m_ptr > p_item.get_ptr();}
+ inline bool operator<(const t_self & p_item) const throw() {return m_ptr < p_item.get_ptr();}
+
+ template<typename t_other>
+ inline t_self & operator<<(service_ptr_t<t_other> & p_source) throw() {__unsafe_set(p_source.__unsafe_detach());return *this;}
+ template<typename t_other>
+ inline t_self & operator>>(service_ptr_t<t_other> & p_dest) throw() {p_dest.__unsafe_set(__unsafe_detach());return *this;}
+
+
+ inline T* __unsafe_duplicate() const throw() {//should not be used ! temporary !
+ service_add_ref_safe(m_ptr);
+ return m_ptr;
+ }
+
+ inline T* __unsafe_detach() throw() {//should not be used ! temporary !
+ return pfc::replace_null_t(m_ptr);
+ }
+
+ template<typename t_source>
+ inline void __unsafe_set(t_source * p_ptr) throw() {//should not be used ! temporary !
+ service_release_safe(m_ptr);
+ m_ptr = pfc::safe_ptr_cast<T>(p_ptr);
+ }
+private:
+ T* m_ptr;
+};
+
+namespace pfc {
+ template<typename T>
+ class traits_t<service_ptr_t<T> > : public traits_default {
+ public:
+ enum { realloc_safe = true, constructor_may_fail = false};
+ };
+}
+
+
+template<typename T, template<typename> class t_alloc = pfc::alloc_fast>
+class service_list_t : public pfc::list_t<service_ptr_t<T>, t_alloc >
+{
+};
+
+//! Helper macro for use when defining a service class. Generates standard features of a service, without ability to register using service_factory / enumerate using service_enum_t. \n
+//! This is used for declaring services that are meant to be instantiated by means other than service_enum_t (or non-entrypoint services), or extensions of services (including extension of entrypoint services). \n
+//! Sample non-entrypoint declaration: class myclass : public service_base {...; FB2K_MAKE_SERVICE_INTERFACE(myclass, service_base); }; \n
+//! Sample extension declaration: class myclass : public myotherclass {...; FB2K_MAKE_SERVICE_INTERFACE(myclass, myotherclass); }; \n
+//! This macro is intended for use ONLY WITH INTERFACE CLASSES, not with implementation classes.
+#define FB2K_MAKE_SERVICE_INTERFACE(THISCLASS,PARENTCLASS) \
+ public: \
+ typedef THISCLASS t_interface; \
+ typedef PARENTCLASS t_interface_parent; \
+ \
+ static const GUID class_guid; \
+ \
+ virtual bool service_query(service_ptr_t<service_base> & p_out,const GUID & p_guid) { \
+ if (p_guid == class_guid) {p_out = this; return true;} \
+ else return PARENTCLASS::service_query(p_out,p_guid); \
+ } \
+ protected: \
+ THISCLASS() {} \
+ ~THISCLASS() {} \
+ private: \
+ const THISCLASS & operator=(const THISCLASS &) {throw pfc::exception_not_implemented();} \
+ THISCLASS(const THISCLASS &) {throw pfc::exception_not_implemented();} \
+ private: \
+ void __private__service_declaration_selftest() { \
+ pfc::assert_same_type<PARENTCLASS,PARENTCLASS::t_interface>(); /*parentclass must be an interface*/ \
+ __validate_service_class_helper<THISCLASS>(); /*service_base must be reachable by walking t_interface_parent*/ \
+ pfc::safe_cast<service_base*>(this); /*this class must derive from service_base, directly or indirectly, and be implictly castable to it*/ \
+ }
+
+//! Helper macro for use when defining an entrypoint service class. Generates standard features of a service, including ability to register using service_factory and enumerate using service_enum. \n
+//! Sample declaration: class myclass : public service_base {...; FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(myclass); }; \n
+//! Note that entrypoint service classes must directly derive from service_base, and not from another service class.
+//! This macro is intended for use ONLY WITH INTERFACE CLASSES, not with implementation classes.
+#define FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(THISCLASS) \
+ public: \
+ typedef THISCLASS t_interface_entrypoint; \
+ FB2K_MAKE_SERVICE_INTERFACE(THISCLASS,service_base)
+
+
+#define FB2K_DECLARE_SERVICE_BEGIN(THISCLASS,BASECLASS) \
+ class NOVTABLE THISCLASS : public BASECLASS { \
+ FB2K_MAKE_SERVICE_INTERFACE(THISCLASS,BASECLASS); \
+ public:
+
+#define FB2K_DECLARE_SERVICE_END() \
+ };
+
+#define FB2K_DECLARE_SERVICE_ENTRYPOINT_BEGIN(THISCLASS) \
+ class NOVTABLE THISCLASS : public service_base { \
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(THISCLASS) \
+ public:
+
+
+//! Base class for all service classes.\n
+//! Provides interfaces for reference counter and querying for different interfaces supported by the object.\n
+class NOVTABLE service_base
+{
+public:
+ //! Decrements reference count; deletes the object if reference count reaches zero. This is normally not called directly but managed by service_ptr_t<> template.
+ //! @returns New reference count. For debug purposes only, in certain conditions return values may be unreliable.
+ virtual int service_release() throw() = 0;
+ //! Increments reference count. This is normally not called directly but managed by service_ptr_t<> template.
+ //! @returns New reference count. For debug purposes only, in certain conditions return values may be unreliable.
+ virtual int service_add_ref() throw() = 0;
+ //! Queries whether the object supports specific interface and retrieves a pointer to that interface. This is normally not called directly but managed by service_query_t<> function template.
+ //! Typical implementation checks the parameter against GUIDs of interfaces supported by this object, if the GUID is one of supported interfaces, p_out is set to service_base pointer that can be static_cast<>'ed to queried interface and the method returns true; otherwise the method returns false.
+ virtual bool service_query(service_ptr_t<service_base> & p_out,const GUID & p_guid) {return false;}
+
+ //! Queries whether the object supports specific interface and retrieves a pointer to that interface.
+ //! @param p_out Receives pointer to queried interface on success.
+ //! returns true on success, false on failure (interface not supported by the object).
+ template<class T>
+ bool service_query_t(service_ptr_t<T> & p_out)
+ {
+ pfc::assert_same_type<T,T::t_interface>();
+ service_ptr_t<service_base> temp;
+ if (!service_query(temp,T::class_guid)) return false;
+ p_out.__unsafe_set(static_cast<T*>(temp.__unsafe_detach()));
+ return true;
+ }
+
+ typedef service_base t_interface;
+
+protected:
+ service_base() {}
+ ~service_base() {}
+private:
+ service_base(const service_base&) {throw pfc::exception_not_implemented();}
+ const service_base & operator=(const service_base&) {throw pfc::exception_not_implemented();}
+};
+
+template<typename T>
+static void __validate_service_class_helper() {
+ __validate_service_class_helper<T::t_interface_parent>();
+}
+
+template<>
+static void __validate_service_class_helper<service_base>() {}
+
+
+#include "service_impl.h"
+
+class NOVTABLE service_factory_base {
+protected:
+ inline service_factory_base(const GUID & p_guid) : m_guid(p_guid) {PFC_ASSERT(!core_api::are_services_available());__internal__next=__internal__list;__internal__list=this;}
+ inline ~service_factory_base() {PFC_ASSERT(!core_api::are_services_available());}
+public:
+ inline const GUID & get_class_guid() const {return m_guid;}
+
+ static service_class_ref enum_find_class(const GUID & p_guid);
+ static bool enum_create(service_ptr_t<service_base> & p_out,service_class_ref p_class,t_size p_index);
+ static t_size enum_get_count(service_class_ref p_class);
+
+ inline static bool is_service_present(const GUID & g) {return enum_get_count(enum_find_class(g))>0;}
+
+ //! Throws std::bad_alloc or another exception on failure.
+ virtual void instance_create(service_ptr_t<service_base> & p_out) = 0;
+
+ //! FOR INTERNAL USE ONLY
+ static service_factory_base *__internal__list;
+ //! FOR INTERNAL USE ONLY
+ service_factory_base * __internal__next;
+private:
+ const GUID & m_guid;
+};
+
+
+template<typename B>
+class service_factory_base_t : public service_factory_base {
+public:
+ service_factory_base_t() : service_factory_base(B::class_guid) {
+ pfc::assert_same_type<B,B::t_interface_entrypoint>();
+ }
+
+};
+
+
+
+
+template<class T> static bool service_enum_create_t(service_ptr_t<T> & p_out,t_size p_index) {
+ pfc::assert_same_type<T,T::t_interface_entrypoint>();
+ service_ptr_t<service_base> ptr;
+ if (service_factory_base::enum_create(ptr,service_factory_base::enum_find_class(T::class_guid),p_index)) {
+ p_out = static_cast<T*>(ptr.get_ptr());
+ return true;
+ } else {
+ p_out.release();
+ return false;
+ }
+}
+
+template<typename T> class service_class_helper_t {
+public:
+ service_class_helper_t() : m_class(service_factory_base::enum_find_class(T::class_guid)) {
+ pfc::assert_same_type<T,T::t_interface_entrypoint>();
+ }
+ t_size get_count() const {
+ return service_factory_base::enum_get_count(m_class);
+ }
+
+ bool create(service_ptr_t<T> & p_out,t_size p_index) const {
+ service_ptr_t<service_base> temp;
+ if (!service_factory_base::enum_create(temp,m_class,p_index)) return false;
+ p_out.__unsafe_set(static_cast<T*>(temp.__unsafe_detach()));
+ return true;
+ }
+
+ service_ptr_t<T> create(t_size p_index) const {
+ service_ptr_t<T> temp;
+ if (!create(temp,p_index)) throw pfc::exception_bug_check();
+ return temp;
+ }
+private:
+ service_class_ref m_class;
+};
+
+template<typename T> static void standard_api_create_t(service_ptr_t<T> & p_out) {
+ if (pfc::is_same_type<T,T::t_interface_entrypoint>::value) {
+ service_class_helper_t<T::t_interface_entrypoint> helper;
+ switch(helper.get_count()) {
+ case 0:
+ throw exception_service_not_found();
+ case 1:
+ if (!helper.create(reinterpret_cast<service_ptr_t<T::t_interface_entrypoint>&>(p_out),0)) throw pfc::exception_bug_check();
+ break;
+ default:
+ throw exception_service_duplicated();
+ }
+ } else {
+ service_ptr_t<T::t_interface_entrypoint> temp;
+ standard_api_create_t(temp);
+ if (!temp->service_query_t(p_out)) throw exception_service_extension_not_found();
+ }
+}
+
+template<typename T> static service_ptr_t<T> standard_api_create_t() {
+ service_ptr_t<T> temp;
+ standard_api_create_t(temp);
+ return temp;
+}
+
+//! Helper template used to easily access core services. \n
+//! Usage: static_api_ptr_t<myclass> api; api->dosomething();
+//! Can be used at any point of code, WITH EXCEPTION of static objects that are initialized during DLL load before service system is initialized; such as static static_api_ptr_t objects or having static_api_ptr_t as members of statically created objects.
+//! Throws exception_service_not_found if service could not be reached (which can be ignored for core APIs that are always present unless there is some kind of bug in the code).
+template<typename t_interface>
+class static_api_ptr_t {
+public:
+ static_api_ptr_t() {
+ standard_api_create_t(m_ptr);
+ }
+ service_obscure_refcounting<t_interface>* operator->() const {return service_obscure_refcounting_cast(m_ptr.get_ptr());}
+ t_interface* get_ptr() const {return m_ptr.get_ptr();}
+private:
+ service_ptr_t<t_interface> m_ptr;
+};
+
+//! Helper; simulates array with instance of each available implementation of given service class.
+template<typename T> class service_instance_array_t {
+public:
+ typedef service_ptr_t<T> t_ptr;
+ service_instance_array_t() {
+ service_class_helper_t<T> helper;
+ const t_size count = helper.get_count();
+ m_data.set_size(count);
+ for(t_size n=0;n<count;n++) m_data[n] = helper.create(n);
+ }
+
+ t_size get_size() const {return m_data.get_size();}
+ const t_ptr & operator[](t_size p_index) const {return m_data[p_index];}
+
+ //nonconst version to allow sorting/bsearching; do not abuse
+ t_ptr & operator[](t_size p_index) {return m_data[p_index];}
+private:
+ pfc::array_t<t_ptr> m_data;
+};
+
+template<typename t_interface>
+class service_enum_t {
+public:
+ service_enum_t() : m_index(0) {
+ pfc::assert_same_type<t_interface,typename t_interface::t_interface_entrypoint>();
+ }
+ void reset() {m_index = 0;}
+
+ template<typename t_query>
+ bool first(service_ptr_t<t_query> & p_out) {
+ reset();
+ return next(p_out);
+ }
+
+ template<typename t_query>
+ bool next(service_ptr_t<t_query> & p_out) {
+ pfc::assert_same_type<typename t_query::t_interface_entrypoint,t_interface>();
+ if (pfc::is_same_type<t_query,t_interface>::value) {
+ return __next(reinterpret_cast<service_ptr_t<t_interface>&>(p_out));
+ } else {
+ service_ptr_t<t_interface> temp;
+ while(__next(temp)) {
+ if (temp->service_query_t(p_out)) return true;
+ }
+ return false;
+ }
+ }
+
+private:
+ bool __next(service_ptr_t<t_interface> & p_out) {
+ return m_helper.create(p_out,m_index++);
+ }
+ unsigned m_index;
+ service_class_helper_t<t_interface> m_helper;
+};
+
+template<typename T>
+class service_factory_t : public service_factory_base_t<typename T::t_interface_entrypoint> {
+public:
+ void instance_create(service_ptr_t<service_base> & p_out) {
+ p_out = pfc::safe_cast<service_base*>(pfc::safe_cast<typename T::t_interface_entrypoint*>(pfc::safe_cast<T*>( new service_impl_t<T> )));
+ }
+};
+
+template<typename T>
+class service_factory_single_t : public service_factory_base_t<typename T::t_interface_entrypoint> {
+ service_impl_single_t<T> g_instance;
+public:
+ TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(service_factory_single_t,g_instance)
+
+ void instance_create(service_ptr_t<service_base> & p_out) {
+ p_out = pfc::safe_cast<service_base*>(pfc::safe_cast<typename T::t_interface_entrypoint*>(pfc::safe_cast<T*>(&g_instance)));
+ }
+
+ inline T& get_static_instance() {return g_instance;}
+};
+
+template<typename T>
+class service_factory_single_ref_t : public service_factory_base_t<typename T::t_interface_entrypoint>
+{
+private:
+ T & instance;
+public:
+ service_factory_single_ref_t(T& param) : instance(param) {}
+
+ void instance_create(service_ptr_t<service_base> & p_out) {
+ p_out = pfc::safe_cast<service_base*>(pfc::safe_cast<typename T::t_interface_entrypoint*>(pfc::safe_cast<T*>(&instance)));
+ }
+
+ inline T& get_static_instance() {return instance;}
+};
+
+
+template<typename T>
+class service_factory_single_transparent_t : public service_factory_base_t<typename T::t_interface_entrypoint>, public service_impl_single_t<T>
+{
+public:
+ TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(service_factory_single_transparent_t,service_impl_single_t<T>)
+
+ void instance_create(service_ptr_t<service_base> & p_out) {
+ p_out = pfc::safe_cast<service_base*>(pfc::safe_cast<typename T::t_interface_entrypoint*>(pfc::safe_cast<T*>(this)));
+ }
+
+ inline T& get_static_instance() {return *(T*)this;}
+};
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/service_impl.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/service_impl.h
new file mode 100644
index 0000000..9e07fa7
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/service_impl.h
@@ -0,0 +1,28 @@
+//! Template implementing reference-counting features of service_base. Intended for dynamic instantiation: "new service_impl_t<someclass>(param1,param2);"; should not be instantiated otherwise (no local/static/member objects) because it does a "delete this;" when reference count reaches zero.\n
+//! Note that some constructor parameters such as NULL will need explicit typecasts to ensure correctly guessed types for constructor function template (null string needs to be (const char*)NULL rather than just NULL, etc).
+template<typename T>
+class service_impl_t : public T
+{
+public:
+ int FB2KAPI service_release() throw() {
+ int ret = --m_counter;
+ if (ret == 0) try { delete this; } catch(...) {PFC_ASSERT(0);}
+ return ret;}
+ int FB2KAPI service_add_ref() throw() {return ++m_counter;}
+
+ TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(service_impl_t,T)
+private:
+ pfc::refcounter m_counter;
+};
+
+//! Template implementing dummy version of reference-counting features of service_base. Intended for static/local/member instantiation: "static service_impl_single_t<someclass> myvar(params);". Because reference counting features are disabled (dummy reference counter), code instantiating it is responsible for deleting it as well as ensuring that no references are active when the object gets deleted.\n
+//! Note that some constructor parameters such as NULL will need explicit typecasts to ensure correctly guessed types for constructor function template (null string needs to be (const char*)NULL rather than just NULL, etc).
+template<typename T>
+class service_impl_single_t : public T
+{
+public:
+ int FB2KAPI service_release() throw() {return 1;}
+ int FB2KAPI service_add_ref() throw() {return 1;}
+
+ TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(service_impl_single_t,T)
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/shared.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/shared.h
new file mode 100644
index 0000000..f49bfe5
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/shared.h
@@ -0,0 +1,11 @@
+//DEPRECATED
+
+#ifndef _FOOBAR2000_SHARED_H_
+#define _FOOBAR2000_SHARED_H_
+
+#include "../shared/shared.h"
+
+HWND uCreateDialog(UINT id,HWND parent,DLGPROC proc,LPARAM param=0);
+int uDialogBox(UINT id,HWND parent,DLGPROC proc,LPARAM param=0);
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/shortcut_actions.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/shortcut_actions.h
new file mode 100644
index 0000000..cfc068a
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/shortcut_actions.h
@@ -0,0 +1 @@
+#error DEPRECATED
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/stdafx.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/stdafx.cpp
new file mode 100644
index 0000000..ea4f0bd
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/stdafx.cpp
@@ -0,0 +1,2 @@
+//cpp used to generate precompiled header
+#include "foobar2000.h" \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/tag_processor.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/tag_processor.cpp
new file mode 100644
index 0000000..784f6ad
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/tag_processor.cpp
@@ -0,0 +1,169 @@
+#include "foobar2000.h"
+
+void tag_processor_trailing::write_id3v1(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort)
+{
+ write(p_file,p_info,flag_id3v1,p_abort);
+}
+
+void tag_processor_trailing::write_apev2(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort)
+{
+ write(p_file,p_info,flag_apev2,p_abort);
+}
+
+void tag_processor_trailing::write_apev2_id3v1(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort)
+{
+ write(p_file,p_info,flag_id3v1|flag_apev2,p_abort);
+}
+
+
+
+
+enum {
+ g_flag_id3v1 = 1<<0,
+ g_flag_id3v2 = 1<<1,
+ g_flag_apev2 = 1<<2
+};
+
+static void tagtype_list_append(pfc::string_base & p_out,const char * p_name)
+{
+ if (!p_out.is_empty()) p_out += "|";
+ p_out += p_name;
+}
+
+static void g_write_tags_ex(tag_write_callback & p_callback,unsigned p_flags,const service_ptr_t<file> & p_file,const file_info * p_info,abort_callback & p_abort) {
+ PFC_ASSERT( p_flags == 0 || p_info != 0 );
+
+
+ if (p_flags & (g_flag_id3v1 | g_flag_apev2)) {
+ switch(p_flags & (g_flag_id3v1 | g_flag_apev2)) {
+ case g_flag_id3v1 | g_flag_apev2:
+ static_api_ptr_t<tag_processor_trailing>()->write_apev2_id3v1(p_file,*p_info,p_abort);
+ break;
+ case g_flag_id3v1:
+ static_api_ptr_t<tag_processor_trailing>()->write_id3v1(p_file,*p_info,p_abort);
+ break;
+ case g_flag_apev2:
+ static_api_ptr_t<tag_processor_trailing>()->write_apev2(p_file,*p_info,p_abort);
+ break;
+ default:
+ throw exception_io_data();
+ }
+ } else {
+ static_api_ptr_t<tag_processor_trailing>()->remove(p_file,p_abort);
+ }
+
+ if (p_flags & g_flag_id3v2)
+ {
+ static_api_ptr_t<tag_processor_id3v2>()->write_ex(p_callback,p_file,*p_info,p_abort);
+ }
+ else
+ {
+ t_uint64 dummy;
+ tag_processor_id3v2::g_remove_ex(p_callback,p_file,dummy,p_abort);
+ }
+}
+
+static void g_write_tags(unsigned p_flags,const service_ptr_t<file> & p_file,const file_info * p_info,abort_callback & p_abort) {
+ g_write_tags_ex(tag_write_callback_dummy(),p_flags,p_file,p_info,p_abort);
+}
+
+
+void tag_processor::write_multi(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort,bool p_write_id3v1,bool p_write_id3v2,bool p_write_apev2) {
+ unsigned flags = 0;
+ if (p_write_id3v1) flags |= g_flag_id3v1;
+ if (p_write_id3v2) flags |= g_flag_id3v2;
+ if (p_write_apev2) flags |= g_flag_apev2;
+ g_write_tags(flags,p_file,&p_info,p_abort);
+}
+
+void tag_processor::write_multi_ex(tag_write_callback & p_callback,const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort,bool p_write_id3v1,bool p_write_id3v2,bool p_write_apev2) {
+ unsigned flags = 0;
+ if (p_write_id3v1) flags |= g_flag_id3v1;
+ if (p_write_id3v2) flags |= g_flag_id3v2;
+ if (p_write_apev2) flags |= g_flag_apev2;
+ g_write_tags_ex(p_callback,flags,p_file,&p_info,p_abort);
+}
+
+void tag_processor::write_id3v1(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort) {
+ g_write_tags(g_flag_id3v1,p_file,&p_info,p_abort);
+}
+
+void tag_processor::write_apev2(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort) {
+ g_write_tags(g_flag_apev2,p_file,&p_info,p_abort);
+}
+
+void tag_processor::write_apev2_id3v1(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort) {
+ g_write_tags(g_flag_apev2|g_flag_id3v1,p_file,&p_info,p_abort);
+}
+
+void tag_processor::write_id3v2(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort) {
+ g_write_tags(g_flag_id3v2,p_file,&p_info,p_abort);
+}
+
+void tag_processor::write_id3v2_id3v1(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort) {
+ g_write_tags(g_flag_id3v2|g_flag_id3v1,p_file,&p_info,p_abort);
+}
+
+void tag_processor::remove_trailing(const service_ptr_t<file> & p_file,abort_callback & p_abort) {
+ return static_api_ptr_t<tag_processor_trailing>()->remove(p_file,p_abort);
+}
+
+void tag_processor::remove_id3v2(const service_ptr_t<file> & p_file,abort_callback & p_abort) {
+ t_uint64 dummy;
+ tag_processor_id3v2::g_remove(p_file,dummy,p_abort);
+}
+
+void tag_processor::remove_id3v2_trailing(const service_ptr_t<file> & p_file,abort_callback & p_abort) {
+ remove_id3v2(p_file,p_abort);
+ remove_trailing(p_file,p_abort);
+}
+
+void tag_processor::read_trailing(const service_ptr_t<file> & p_file,file_info & p_info,abort_callback & p_abort) {
+ static_api_ptr_t<tag_processor_trailing>()->read(p_file,p_info,p_abort);
+}
+
+void tag_processor::read_trailing_ex(const service_ptr_t<file> & p_file,file_info & p_info,t_uint64 & p_tagoffset,abort_callback & p_abort) {
+ static_api_ptr_t<tag_processor_trailing>()->read_ex(p_file,p_info,p_tagoffset,p_abort);
+}
+
+void tag_processor::read_id3v2(const service_ptr_t<file> & p_file,file_info & p_info,abort_callback & p_abort) {
+ static_api_ptr_t<tag_processor_id3v2>()->read(p_file,p_info,p_abort);
+}
+
+void tag_processor::read_id3v2_trailing(const service_ptr_t<file> & p_file,file_info & p_info,abort_callback & p_abort)
+{
+ file_info_i temp_infos[2];
+ bool have_id3v2 = true, have_trailing = true;
+ try {
+ read_id3v2(p_file,temp_infos[0],p_abort);
+ } catch(exception_io_data) {
+ have_id3v2 = false;
+ }
+ try {
+ read_trailing(p_file,temp_infos[1],p_abort);
+ } catch(exception_io_data) {
+ have_trailing = false;
+ }
+
+ if (!have_id3v2 && !have_trailing) throw exception_tag_not_found();
+ else {
+ pfc::ptr_list_t<const file_info> blargh;
+ if (have_id3v2) blargh.add_item(&temp_infos[0]);
+ if (have_trailing) blargh.add_item(&temp_infos[1]);
+ p_info.merge(blargh);
+ }
+}
+
+void tag_processor::skip_id3v2(const service_ptr_t<file> & p_file,t_uint64 & p_size_skipped,abort_callback & p_abort) {
+ tag_processor_id3v2::g_skip(p_file,p_size_skipped,p_abort);
+}
+
+bool tag_processor::is_id3v1_sufficient(const file_info & p_info)
+{
+ return static_api_ptr_t<tag_processor_trailing>()->is_id3v1_sufficient(p_info);
+}
+
+void tag_processor::truncate_to_id3v1(file_info & p_info)
+{
+ static_api_ptr_t<tag_processor_trailing>()->truncate_to_id3v1(p_info);
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/tag_processor.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/tag_processor.h
new file mode 100644
index 0000000..8c5187a
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/tag_processor.h
@@ -0,0 +1,103 @@
+#ifndef _TAG_PROCESSOR_H_
+#define _TAG_PROCESSOR_H_
+
+
+PFC_DECLARE_EXCEPTION(exception_tag_not_found,exception_io_data,"Tag not found");
+
+//! Callback interface for write-tags-to-temp-file-and-swap scheme, used for ID3v2 tag updates and such where entire file needs to be rewritten.
+//! As a speed optimization, file content can be copied to a temporary file in the same directory as the file being updated, and then source file can be swapped for the newly created file with updated tags.
+//! This also gives better security against data loss on crash compared to rewriting the file in place and using memory or generic temporary file APIs to store content being rewritten.
+class NOVTABLE tag_write_callback {
+public:
+ //! Called only once per operation (or not called at all when operation being performed can be done in-place).
+ //! Requests a temporary file to be created in the same directory
+ virtual bool open_temp_file(service_ptr_t<file> & p_out,abort_callback & p_abort) = 0;
+protected:
+ tag_write_callback() {}
+ ~tag_write_callback() {}
+private:
+ tag_write_callback(const tag_write_callback &) {throw pfc::exception_not_implemented();}
+ const tag_write_callback & operator=(const tag_write_callback &) {throw pfc::exception_not_implemented();}
+};
+
+class tag_write_callback_dummy : public tag_write_callback {
+public:
+ bool open_temp_file(service_ptr_t<file> & p_out,abort_callback & p_abort) {return false;}
+};
+
+class NOVTABLE tag_processor_id3v2 : public service_base
+{
+public:
+ virtual void read(const service_ptr_t<file> & p_file,file_info & p_info,abort_callback & p_abort) = 0;
+ virtual void write(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort) = 0;
+ virtual void write_ex(tag_write_callback & p_callback,const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort) = 0;
+
+ static bool g_get(service_ptr_t<tag_processor_id3v2> & p_out);
+ static void g_skip(const service_ptr_t<file> & p_file,t_filesize & p_size_skipped,abort_callback & p_abort);
+ static void g_remove(const service_ptr_t<file> & p_file,t_filesize & p_size_removed,abort_callback & p_abort);
+ static void g_remove_ex(tag_write_callback & p_callback,const service_ptr_t<file> & p_file,t_filesize & p_size_removed,abort_callback & p_abort);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(tag_processor_id3v2);
+};
+
+class NOVTABLE tag_processor_trailing : public service_base
+{
+public:
+ enum {
+ flag_apev2 = 1,
+ flag_id3v1 = 2,
+ };
+
+ virtual void read(const service_ptr_t<file> & p_file,file_info & p_info,abort_callback & p_abort) = 0;
+ virtual void write(const service_ptr_t<file> & p_file,const file_info & p_info,unsigned p_flags,abort_callback & p_abort) = 0;
+ virtual void remove(const service_ptr_t<file> & p_file,abort_callback & p_abort) = 0;
+ virtual bool is_id3v1_sufficient(const file_info & p_info) = 0;
+ virtual void truncate_to_id3v1(file_info & p_info) = 0;
+ virtual void read_ex(const service_ptr_t<file> & p_file,file_info & p_info,t_filesize & p_tagoffset,abort_callback & p_abort) = 0;
+
+ void write_id3v1(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort);
+ void write_apev2(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort);
+ void write_apev2_id3v1(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort);
+
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(tag_processor_trailing);
+};
+
+namespace tag_processor {
+ //! Strips all recognized tags from the file and writes an ID3v1 tag with specified info.
+ void write_id3v1(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort);
+ //! Strips all recognized tags from the file and writes an APEv2 tag with specified info.
+ void write_apev2(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort);
+ //! Strips all recognized tags from the file and writes ID3v1+APEv2 tags with specified info.
+ void write_apev2_id3v1(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort);
+ //! Strips all recognized tags from the file and writes an ID3v2 tag with specified info.
+ void write_id3v2(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort);
+ //! Strips all recognized tags from the file and writes ID3v1+ID3v2 tags with specified info.
+ void write_id3v2_id3v1(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort);
+ //! Strips all recognized tags from the file and writes new tags with specified info according to parameters.
+ void write_multi(const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort,bool p_write_id3v1,bool p_write_id3v2,bool p_write_apev2);
+ //! Strips all recognized tags from the file and writes new tags with specified info according to parameters. Extended to allow write-tags-to-temp-file-and-swap scheme.
+ void write_multi_ex(tag_write_callback & p_callback,const service_ptr_t<file> & p_file,const file_info & p_info,abort_callback & p_abort,bool p_write_id3v1,bool p_write_id3v2,bool p_write_apev2);
+ //! Removes trailing tags from the file.
+ void remove_trailing(const service_ptr_t<file> & p_file,abort_callback & p_abort);
+ //! Removes ID3v2 tags from the file.
+ void remove_id3v2(const service_ptr_t<file> & p_file,abort_callback & p_abort);
+ //! Removes ID3v2 and trailing tags from specified file (not to be confused with trailing ID3v2 which are not yet supported).
+ void remove_id3v2_trailing(const service_ptr_t<file> & p_file,abort_callback & p_abort);
+ //! Reads trailing tags from the file.
+ void read_trailing(const service_ptr_t<file> & p_file,file_info & p_info,abort_callback & p_abort);
+ //! Reads trailing tags from the file. Extended version, returns offset at which parsed tags start.
+ void read_trailing_ex(const service_ptr_t<file> & p_file,file_info & p_info,t_filesize & p_tagoffset,abort_callback & p_abort);
+ //! Reads ID3v2 tags from specified file.
+ void read_id3v2(const service_ptr_t<file> & p_file,file_info & p_info,abort_callback & p_abort);
+ //! Reads ID3v2 and trailing tags from specified file (not to be confused with trailing ID3v2 which are not yet supported).
+ void read_id3v2_trailing(const service_ptr_t<file> & p_file,file_info & p_info,abort_callback & p_abort);
+
+ void skip_id3v2(const service_ptr_t<file> & p_file,t_filesize & p_size_skipped,abort_callback & p_abort);
+
+ bool is_id3v1_sufficient(const file_info & p_info);
+ void truncate_to_id3v1(file_info & p_info);
+
+};
+
+#endif //_TAG_PROCESSOR_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/tag_processor_id3v2.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/tag_processor_id3v2.cpp
new file mode 100644
index 0000000..accff2e
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/tag_processor_id3v2.cpp
@@ -0,0 +1,97 @@
+#include "foobar2000.h"
+
+bool tag_processor_id3v2::g_get(service_ptr_t<tag_processor_id3v2> & p_out)
+{
+ return service_enum_t<tag_processor_id3v2>().first(p_out);
+}
+
+void tag_processor_id3v2::g_remove(const service_ptr_t<file> & p_file,t_uint64 & p_size_removed,abort_callback & p_abort) {
+ g_remove_ex(tag_write_callback_dummy(),p_file,p_size_removed,p_abort);
+}
+
+void tag_processor_id3v2::g_remove_ex(tag_write_callback & p_callback,const service_ptr_t<file> & p_file,t_uint64 & p_size_removed,abort_callback & p_abort)
+{
+ p_file->ensure_seekable();
+
+ t_filesize len;
+
+ len = p_file->get_size(p_abort);
+
+ if (len == filesize_invalid) throw exception_io_no_length();;
+
+ p_file->seek(0,p_abort);
+
+ t_uint64 offset;
+ g_skip(p_file,offset,p_abort);
+
+ if (offset>0 && offset<len)
+ {
+ len-=offset;
+ service_ptr_t<file> temp;
+ if (p_callback.open_temp_file(temp,p_abort)) {
+ file::g_transfer_object(p_file,temp,len,p_abort);
+ } else {
+ if (len > 16*1024*1024) filesystem::g_open_temp(temp,p_abort);
+ else filesystem::g_open_tempmem(temp,p_abort);
+ file::g_transfer_object(p_file,temp,len,p_abort);
+ p_file->seek(0,p_abort);
+ p_file->set_eof(p_abort);
+ temp->seek(0,p_abort);
+ file::g_transfer_object(temp,p_file,len,p_abort);
+ }
+ }
+ p_size_removed = offset;
+}
+
+void tag_processor_id3v2::g_skip(const service_ptr_t<file> & p_file,t_uint64 & p_size_skipped,abort_callback & p_abort)
+{
+
+ unsigned char tmp[10];
+
+ t_size io_bytes_done;
+
+ p_file->seek ( 0, p_abort );
+
+ io_bytes_done = p_file->read( tmp, sizeof(tmp), p_abort);
+ if (io_bytes_done != sizeof(tmp)) {
+ p_file->seek ( 0, p_abort );
+ p_size_skipped = 0;
+ return;
+ }
+
+ if ( 0 != memcmp ( tmp, "ID3", 3) ) {
+ p_file->seek ( 0, p_abort );
+ p_size_skipped = 0;
+ return;
+ }
+
+ int Unsynchronisation = tmp[5] & 0x80;
+ int ExtHeaderPresent = tmp[5] & 0x40;
+ int ExperimentalFlag = tmp[5] & 0x20;
+ int FooterPresent = tmp[5] & 0x10;
+
+ if ( tmp[5] & 0x0F ) {
+ p_file->seek ( 0, p_abort );
+ p_size_skipped = 0;
+ return;
+ }
+
+ if ( (tmp[6] | tmp[7] | tmp[8] | tmp[9]) & 0x80 ) {
+ p_file->seek ( 0, p_abort );
+ p_size_skipped = 0;
+ return;
+ }
+
+ t_uint32 ret;
+ ret = tmp[6] << 21;
+ ret += tmp[7] << 14;
+ ret += tmp[8] << 7;
+ ret += tmp[9] ;
+ ret += 10;
+ if ( FooterPresent ) ret += 10;
+
+ p_file->seek ( ret, p_abort );
+
+ p_size_skipped = ret;
+
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/threaded_process.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/threaded_process.cpp
new file mode 100644
index 0000000..567bd30
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/threaded_process.cpp
@@ -0,0 +1,36 @@
+#include "foobar2000.h"
+
+void threaded_process_status::set_progress(t_size p_state,t_size p_max)
+{
+ set_progress( progress_min + MulDiv_Size(p_state,progress_max-progress_min,p_max) );
+}
+
+void threaded_process_status::set_progress_secondary(t_size p_state,t_size p_max)
+{
+ set_progress_secondary( progress_min + MulDiv_Size(p_state,progress_max-progress_min,p_max) );
+}
+
+void threaded_process_status::set_progress_float(double p_state)
+{
+ if (p_state < 0.0) set_progress(progress_min);
+ else if (p_state < 1.0) set_progress( progress_min + (t_size)(p_state * (progress_max - progress_min)));
+ else set_progress(progress_max);
+}
+
+void threaded_process_status::set_progress_secondary_float(double p_state)
+{
+ if (p_state < 0.0) set_progress_secondary(progress_min);
+ else if (p_state < 1.0) set_progress_secondary( progress_min + (t_size)(p_state * (progress_max - progress_min)));
+ else set_progress_secondary(progress_max);
+}
+
+
+bool threaded_process::g_run_modal(service_ptr_t<threaded_process_callback> p_callback,unsigned p_flags,HWND p_parent,const char * p_title,t_size p_title_len)
+{
+ return static_api_ptr_t<threaded_process>()->run_modal(p_callback,p_flags,p_parent,p_title,p_title_len);
+}
+
+bool threaded_process::g_run_modeless(service_ptr_t<threaded_process_callback> p_callback,unsigned p_flags,HWND p_parent,const char * p_title,t_size p_title_len)
+{
+ return static_api_ptr_t<threaded_process>()->run_modeless(p_callback,p_flags,p_parent,p_title,p_title_len);
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/threaded_process.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/threaded_process.h
new file mode 100644
index 0000000..6a071bf
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/threaded_process.h
@@ -0,0 +1,62 @@
+#ifndef _foobar2000_sdk_threaded_process_h_
+#define _foobar2000_sdk_threaded_process_h_
+
+class NOVTABLE threaded_process_status
+{
+public:
+ enum {progress_min = 0, progress_max = 5000};
+
+ virtual void set_progress(t_size p_state) = 0;
+ virtual void set_progress_secondary(t_size p_state) = 0;
+ virtual void set_item(const char * p_item,t_size p_item_len = ~0) = 0;
+ virtual void set_item_path(const char * p_item,t_size p_item_len = ~0) = 0;
+ virtual void set_title(const char * p_title,t_size p_title_len = ~0) = 0;
+ virtual void force_update() = 0;
+ virtual bool is_paused() = 0;
+ virtual bool process_pause() = 0;//checks if process is paused and sleeps if needed; returns false when process should be aborted, true on success
+
+ void set_progress(t_size p_state,t_size p_max);
+ void set_progress_secondary(t_size p_state,t_size p_max);
+ void set_progress_float(double p_state);
+ void set_progress_secondary_float(double p_state);
+protected:
+ threaded_process_status() {}
+ ~threaded_process_status() {}
+};
+
+
+class NOVTABLE threaded_process_callback : public service_base
+{
+public:
+ virtual void on_init(HWND p_wnd) {}
+ virtual void run(threaded_process_status & p_status,abort_callback & p_abort) = 0;
+ virtual void on_done(HWND p_wnd,bool p_was_aborted) {}
+
+ FB2K_MAKE_SERVICE_INTERFACE(threaded_process_callback,service_base);
+};
+
+class NOVTABLE threaded_process : public service_base {
+public:
+ enum {
+ flag_show_abort = 1,
+ flag_show_minimize = 1 << 1,
+ flag_show_progress = 1 << 2,
+ flag_show_progress_dual = 1 << 3,//implies flag_show_progress
+ flag_show_item = 1 << 4,
+ flag_show_pause = 1 << 5,
+ flag_high_priority = 1 << 6,
+ flag_show_delayed = 1 << 7,//modeless-only
+ flag_no_focus = 1 << 8,//new (0.9.3)
+ };
+
+ virtual bool run_modal(service_ptr_t<threaded_process_callback> p_callback,unsigned p_flags,HWND p_parent,const char * p_title,t_size p_title_len) = 0;
+ virtual bool run_modeless(service_ptr_t<threaded_process_callback> p_callback,unsigned p_flags,HWND p_parent,const char * p_title,t_size p_title_len) = 0;
+
+ static bool g_run_modal(service_ptr_t<threaded_process_callback> p_callback,unsigned p_flags,HWND p_parent,const char * p_title,t_size p_title_len = infinite);
+ static bool g_run_modeless(service_ptr_t<threaded_process_callback> p_callback,unsigned p_flags,HWND p_parent,const char * p_title,t_size p_title_len = infinite);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(threaded_process);
+};
+
+
+#endif //_foobar2000_sdk_threaded_process_h_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat.cpp
new file mode 100644
index 0000000..ba9d503
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat.cpp
@@ -0,0 +1,748 @@
+#include "foobar2000.h"
+
+void titleformat_compiler::remove_color_marks(const char * src,pfc::string_base & out)//helper
+{
+ out.reset();
+ while(*src)
+ {
+ if (*src==3)
+ {
+ src++;
+ while(*src && *src!=3) src++;
+ if (*src==3) src++;
+ }
+ else out.add_byte(*src++);
+ }
+}
+
+static bool test_for_bad_char(const char * source,t_size source_char_len,const char * reserved)
+{
+ return pfc::strstr_ex(reserved,(t_size)(-1),source,source_char_len) != (t_size)(-1);
+}
+
+void titleformat_compiler::remove_forbidden_chars(titleformat_text_out * p_out,const GUID & p_inputtype,const char * p_source,t_size p_source_len,const char * p_reserved_chars)
+{
+ if (p_reserved_chars == 0 || *p_reserved_chars == 0)
+ {
+ p_out->write(p_inputtype,p_source,p_source_len);
+ }
+ else
+ {
+ p_source_len = pfc::strlen_max(p_source,p_source_len);
+ t_size index = 0;
+ t_size good_byte_count = 0;
+ while(index < p_source_len)
+ {
+ t_size delta = pfc::utf8_char_len(p_source + index,p_source_len - index);
+ if (delta == 0) break;
+ if (test_for_bad_char(p_source+index,delta,p_reserved_chars))
+ {
+ if (good_byte_count > 0) {p_out->write(p_inputtype,p_source+index-good_byte_count,good_byte_count);good_byte_count=0;}
+ p_out->write(p_inputtype,"_",1);
+ }
+ else
+ {
+ good_byte_count += delta;
+ }
+ index += delta;
+ }
+ if (good_byte_count > 0) {p_out->write(p_inputtype,p_source+index-good_byte_count,good_byte_count);good_byte_count=0;}
+ }
+}
+
+void titleformat_compiler::remove_forbidden_chars_string_append(pfc::string_receiver & p_out,const char * p_source,t_size p_source_len,const char * p_reserved_chars)
+{
+ remove_forbidden_chars(&titleformat_text_out_impl_string(p_out),pfc::guid_null,p_source,p_source_len,p_reserved_chars);
+}
+
+void titleformat_compiler::remove_forbidden_chars_string(pfc::string_base & p_out,const char * p_source,t_size p_source_len,const char * p_reserved_chars)
+{
+ p_out.reset();
+ remove_forbidden_chars_string_append(p_out,p_source,p_source_len,p_reserved_chars);
+}
+
+void titleformat_hook_impl_file_info::process_codec(titleformat_text_out * p_out)
+{
+ pfc::string8 temp;
+ const char * val = m_info->info_get("codec");
+ if (val)
+ {
+ p_out->write(titleformat_inputtypes::meta,val);
+ }
+ else
+ {
+ val = m_info->info_get("referenced_file");
+ if (val) uAddStringUpper(temp,pfc::string_extension(val));
+ else uAddStringUpper(temp,pfc::string_extension(m_location.get_path()));
+ p_out->write(titleformat_inputtypes::meta,temp);
+ }
+}
+
+bool titleformat_hook_impl_file_info::remap_meta(t_size & p_meta_index, const char * p_name, t_size p_name_length)
+{
+ p_meta_index = infinite;
+ if (!stricmp_utf8_ex(p_name, p_name_length, "album", infinite))
+ {
+ p_meta_index = m_info->meta_find("album");
+ if (p_meta_index != infinite) return true;
+ p_meta_index = m_info->meta_find("venue");
+ if (p_meta_index != infinite) return true;
+ return false;
+ }
+ else if (!stricmp_utf8_ex(p_name, p_name_length, "artist", infinite))
+ {
+ p_meta_index = m_info->meta_find("artist");
+ if (p_meta_index != infinite) return true;
+ p_meta_index = m_info->meta_find("album artist");
+ if (p_meta_index != infinite) return true;
+ p_meta_index = m_info->meta_find("composer");
+ if (p_meta_index != infinite) return true;
+ p_meta_index = m_info->meta_find("performer");
+ if (p_meta_index != infinite) return true;
+ return false;
+ }
+ else if (!stricmp_utf8_ex(p_name, p_name_length, "album artist", infinite))
+ {
+ p_meta_index = m_info->meta_find("album artist");
+ if (p_meta_index != infinite) return true;
+ p_meta_index = m_info->meta_find("artist");
+ if (p_meta_index != infinite) return true;
+ p_meta_index = m_info->meta_find("composer");
+ if (p_meta_index != infinite) return true;
+ p_meta_index = m_info->meta_find("performer");
+ if (p_meta_index != infinite) return true;
+ return false;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"track artist",infinite))
+ {
+ t_size index_artist, index_album_artist;
+
+ index_artist = m_info->meta_find("artist");
+ if (index_artist == infinite) return false;
+ index_album_artist = m_info->meta_find("album artist");
+ if (index_album_artist == infinite) return false;
+ if (m_info->are_meta_fields_identical(index_artist, index_album_artist)) return false;
+
+ p_meta_index = index_artist;
+ return true;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"track",infinite) || !stricmp_utf8_ex(p_name,p_name_length,"tracknumber",infinite))
+ {
+ p_meta_index = m_info->meta_find("tracknumber");
+ if (p_meta_index != infinite) return true;
+ p_meta_index = m_info->meta_find("track");
+ if (p_meta_index != infinite) return true;
+ return false;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"disc",infinite) || !stricmp_utf8_ex(p_name,p_name_length,"discnumber",infinite))
+ {
+ p_meta_index = m_info->meta_find("discnumber");
+ if (p_meta_index != infinite) return true;
+ p_meta_index = m_info->meta_find("disc");
+ if (p_meta_index != infinite) return true;
+ return false;
+ }
+ else
+ {
+ p_meta_index = m_info->meta_find_ex(p_name,p_name_length);
+ return p_meta_index != infinite;
+ }
+}
+
+bool titleformat_hook_impl_file_info::process_field(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,bool & p_found_flag)
+{
+ p_found_flag = false;
+
+ //todo make this bsearch someday
+ if (stricmp_utf8_ex(p_name,p_name_length,"filename",infinite) == 0 || stricmp_utf8_ex(p_name,p_name_length,"_filename",infinite) == 0) {
+ pfc::string8 temp;
+ filesystem::g_get_display_path(m_location.get_path(),temp);
+ p_out->write(titleformat_inputtypes::unknown,pfc::string_filename(temp),infinite);
+ p_found_flag = true;
+ return true;
+ } else if (stricmp_utf8_ex(p_name,p_name_length,"filename_ext",infinite) == 0 || stricmp_utf8_ex(p_name,p_name_length,"_filename_ext",infinite) == 0) {
+ pfc::string8 temp;
+ filesystem::g_get_display_path(m_location.get_path(),temp);
+ p_out->write(titleformat_inputtypes::unknown,pfc::string_filename_ext(temp),infinite);
+ p_found_flag = true;
+ return true;
+ } else if (!stricmp_utf8_ex(p_name,p_name_length,"filename_sort",infinite)) {
+ pfc::string8 temp;
+ filesystem::g_get_display_path(m_location.get_path(),temp);
+ p_out->write(titleformat_inputtypes::unknown,pfc::string_filename(temp),infinite);
+ p_out->write(titleformat_inputtypes::unknown,"|",infinite);
+ p_out->write(titleformat_inputtypes::unknown,pfc::format_uint(m_location.get_subsong(),10),infinite);
+ p_found_flag = true;
+ return true;
+ } else if (stricmp_utf8_ex(p_name,p_name_length,"path",infinite) == 0 || stricmp_utf8_ex(p_name,p_name_length,"_path",infinite) == 0) {
+ pfc::string8 temp;
+ filesystem::g_get_display_path(m_location.get_path(),temp);
+ p_out->write(titleformat_inputtypes::unknown,temp.is_empty() ? "n/a" : temp.get_ptr(),infinite);
+ p_found_flag = true;
+ return true;
+ } else if (!stricmp_utf8_ex(p_name,p_name_length,"path_sort",infinite)) {
+ pfc::string8_fastalloc temp;
+ filesystem::g_get_display_path(m_location.get_path(),temp);
+ p_out->write(titleformat_inputtypes::unknown,temp,infinite);
+ p_out->write(titleformat_inputtypes::unknown,"|",infinite);
+ p_out->write(titleformat_inputtypes::unknown,pfc::format_uint(m_location.get_subsong(),10),infinite);
+ p_found_flag = true;
+ return true;
+ } else if (stricmp_utf8_ex(p_name,p_name_length,"directoryname",infinite) == 0 || stricmp_utf8_ex(p_name,p_name_length,"_directoryname",infinite) == 0 || stricmp_utf8_ex(p_name,p_name_length,"directory",infinite) == 0) {
+ int count = 1;
+ if (count > 0)
+ {
+ pfc::string8_fastalloc temp;
+ filesystem::g_get_display_path(m_location.get_path(),temp);
+
+ for(;count;count--)
+ {
+ t_size ptr = temp.scan_filename();
+ if (ptr==0) {temp.reset();break;}
+ ptr--;
+ temp.truncate(ptr);
+ }
+
+ if (temp.is_empty())
+ {
+ p_found_flag = false;
+ }
+ else
+ {
+ p_out->write(titleformat_inputtypes::meta,temp + temp.scan_filename(),infinite);
+ p_found_flag = true;
+ }
+ }
+ return true;
+ }
+ else if (stricmp_utf8_ex(p_name,p_name_length,"subsong",infinite) == 0 || stricmp_utf8_ex(p_name,p_name_length,"_subsong",infinite) == 0)
+ {
+ p_out->write_int(titleformat_inputtypes::unknown,m_location.get_subsong());
+ p_found_flag = true;
+ return true;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"channels",infinite))
+ {
+ unsigned val = (unsigned)m_info->info_get_int("channels");
+ switch(val)
+ {
+ case 0: p_out->write(titleformat_inputtypes::meta,"N/A",infinite); break;
+ case 1: p_out->write(titleformat_inputtypes::meta,"mono",infinite); p_found_flag = true; break;
+ case 2: p_out->write(titleformat_inputtypes::meta,"stereo",infinite); p_found_flag = true; break;
+ default: p_out->write_int(titleformat_inputtypes::meta,val); p_out->write(titleformat_inputtypes::meta,"ch",infinite); p_found_flag = true; break;
+ }
+ return true;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"bitrate",infinite))
+ {
+ const char * value = m_info->info_get("bitrate_dynamic");
+ if (value == 0 || *value == 0) value = m_info->info_get("bitrate");
+ if (value == 0 || *value == 0) return false;
+ p_out->write(titleformat_inputtypes::meta,value);
+ p_found_flag = true;
+ return true;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"samplerate",infinite))
+ {
+ const char * value = m_info->info_get("samplerate");
+ if (value == 0 || *value == 0) return false;
+ p_out->write(titleformat_inputtypes::meta,value);
+ p_found_flag = true;
+ return true;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"title",infinite))
+ {
+ if (process_meta(p_out,p_name,p_name_length,", ",2,", ",2))
+ {
+ p_found_flag = true;
+ return true;
+ }
+ else
+ {
+ pfc::string8 temp;
+ filesystem::g_get_display_path(m_location.get_path(),temp);
+ pfc::string_filename fn(temp);
+ if (fn.is_empty()) p_out->write(titleformat_inputtypes::meta,temp);
+ else p_out->write(titleformat_inputtypes::meta,fn);
+ p_found_flag = true;
+ return true;
+ }
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"codec",infinite))
+ {
+ process_codec(p_out);
+ p_found_flag = true;
+ return true;
+ } else if (!stricmp_utf8_ex(p_name,p_name_length,"codec_profile",infinite)) {
+ const char * profile = m_info->info_get("codec_profile");
+ if (profile == NULL) return false;
+ p_out->write(titleformat_inputtypes::meta,profile,infinite);
+ p_found_flag = true;
+ return true;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"track",infinite) || !stricmp_utf8_ex(p_name,p_name_length,"tracknumber",infinite))
+ {
+ const t_size pad = 2;
+ const char * val = m_info->meta_get_ex("tracknumber",infinite,0);
+ if (val == 0) m_info->meta_get_ex("track",infinite,0);
+ if (val != 0)
+ {
+ p_found_flag = true;
+ t_size val_len = strlen(val);
+ if (val_len < pad)
+ {
+ t_size n = pad - val_len;
+ do {
+ p_out->write(titleformat_inputtypes::meta,"0",1);
+ n--;
+ } while(n > 0);
+ }
+ p_out->write(titleformat_inputtypes::meta,val);
+ }
+ return true;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"disc",infinite) || !stricmp_utf8_ex(p_name,p_name_length,"discnumber",infinite))
+ {
+ const t_size pad = 1;
+ const char * val = m_info->meta_get_ex("discnumber",infinite,0);
+ if (val == 0) val = m_info->meta_get_ex("disc",infinite,0);
+ if (val != 0)
+ {
+ p_found_flag = true;
+ t_size val_len = strlen(val);
+ if (val_len < pad)
+ {
+ t_size n = pad - val_len;
+ do {
+ p_out->write(titleformat_inputtypes::meta,"0");
+ n--;
+ } while(n > 0);
+ }
+ p_out->write(titleformat_inputtypes::meta,val);
+ }
+ return true;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"totaltracks",infinite)) {
+ const t_size pad = 2;
+ const char * val = m_info->meta_get_ex("totaltracks",infinite,0);
+ if (val != NULL)
+ {
+ p_found_flag = true;
+ t_size val_len = strlen(val);
+ if (val_len < pad)
+ {
+ t_size n = pad - val_len;
+ do {
+ p_out->write(titleformat_inputtypes::meta,"0",1);
+ n--;
+ } while(n > 0);
+ }
+ p_out->write(titleformat_inputtypes::meta,val);
+ }
+ return true;
+ } else if (stricmp_utf8_ex(p_name,p_name_length,"length",infinite) == 0 || stricmp_utf8_ex(p_name,p_name_length,"_length",infinite) == 0) {
+ double len = m_info->get_length();
+ if (len>0)
+ {
+ p_out->write(titleformat_inputtypes::unknown,pfc::format_time(pfc::rint64(len)));
+ p_found_flag = true;
+ return true;
+ }
+ else return false;
+ } else if (stricmp_utf8_ex(p_name,p_name_length,"length_ex",infinite) == 0 || stricmp_utf8_ex(p_name,p_name_length,"_length_ex",infinite) == 0) {
+ double len = m_info->get_length();
+ if (len>0)
+ {
+ p_out->write(titleformat_inputtypes::unknown,pfc::format_time_ex(len),infinite);
+ p_found_flag = true;
+ return true;
+ }
+ else return false;
+ } else if (stricmp_utf8_ex(p_name,p_name_length,"length_seconds",infinite) == 0 || stricmp_utf8_ex(p_name,p_name_length,"_length_seconds",infinite) == 0) {
+ double len = m_info->get_length();
+ if (len>0) {
+ p_out->write_int(titleformat_inputtypes::unknown,(t_uint64)len);
+ p_found_flag = true;
+ return true;
+ } else return false;
+ } else if (stricmp_utf8_ex(p_name,p_name_length,"length_seconds_fp",infinite) == 0 || stricmp_utf8_ex(p_name,p_name_length,"_length_seconds_fp",infinite) == 0) {
+ double len = m_info->get_length();
+ if (len>0) {
+ p_out->write(titleformat_inputtypes::unknown,pfc::string_fixed_t<64>()<<len);
+ p_found_flag = true;
+ return true;
+ } else return false;
+ } else if (stricmp_utf8_ex(p_name,p_name_length,"length_samples",infinite) == 0 || stricmp_utf8_ex(p_name,p_name_length,"_length_samples",infinite) == 0) {
+ t_int64 val = m_info->info_get_length_samples();
+ if (val>0) {
+ p_out->write_int(titleformat_inputtypes::unknown,val);
+ p_found_flag = true;
+ return true;
+ } else return false;
+ }
+ else if (p_name_length > 2 && p_name[0] == '_' && p_name[1] == '_')
+ {//info
+ if (!stricmp_utf8_ex(p_name,p_name_length,"__replaygain_album_gain",infinite))
+ {
+ char rgtemp[replaygain_info::text_buffer_size];
+ m_info->get_replaygain().format_album_gain(rgtemp);
+ if (rgtemp[0] == 0) return false;
+ p_out->write(titleformat_inputtypes::meta,rgtemp);
+ p_found_flag = true;
+ return true;
+ }
+ if (!stricmp_utf8_ex(p_name,p_name_length,"__replaygain_album_peak",infinite))
+ {
+ char rgtemp[replaygain_info::text_buffer_size];
+ m_info->get_replaygain().format_album_peak(rgtemp);
+ if (rgtemp[0] == 0) return false;
+ p_out->write(titleformat_inputtypes::meta,rgtemp);
+ p_found_flag = true;
+ return true;
+ }
+ if (!stricmp_utf8_ex(p_name,p_name_length,"__replaygain_track_gain",infinite))
+ {
+ char rgtemp[replaygain_info::text_buffer_size];
+ m_info->get_replaygain().format_track_gain(rgtemp);
+ if (rgtemp[0] == 0) return false;
+ p_out->write(titleformat_inputtypes::meta,rgtemp);
+ p_found_flag = true;
+ return true;
+ }
+ if (!stricmp_utf8_ex(p_name,p_name_length,"__replaygain_track_peak",infinite))
+ {
+ char rgtemp[replaygain_info::text_buffer_size];
+ m_info->get_replaygain().format_track_peak(rgtemp);
+ if (rgtemp[0] == 0) return false;
+ p_out->write(titleformat_inputtypes::meta,rgtemp);
+ p_found_flag = true;
+ return true;
+ }
+ const char * value = m_info->info_get_ex(p_name+2,p_name_length-2);
+ if (value == 0 || *value == 0) return false;
+ p_out->write(titleformat_inputtypes::meta,value);
+ p_found_flag = true;
+ return true;
+ }
+ else if (p_name_length > 1 && p_name[0] == '_')
+ {//special field
+ bool found = process_extra(p_out,p_name+1,p_name_length-1);
+ p_found_flag = found;
+ return found;
+ }
+ else
+ {//meta
+ t_size index;
+ if (remap_meta(index, p_name, p_name_length))
+ {
+ bool status = process_meta(p_out,index,", ",2,", ",2);
+ p_found_flag = status;
+ return status;
+ }
+ return false;
+ }
+}
+
+bool titleformat_hook_impl_file_info::process_function(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,titleformat_hook_function_params * p_params,bool & p_found_flag)
+{
+ p_found_flag = false;
+ if (!stricmp_utf8_ex(p_name,p_name_length,"meta",infinite))
+ {
+ switch(p_params->get_param_count())
+ {
+ case 1:
+ {
+ const char * name;
+ t_size name_length;
+ p_params->get_param(0,name,name_length);
+ bool status = process_meta(p_out,name,name_length,", ",2,", ",2);
+ p_found_flag = status;
+ return true;
+ }
+ case 2:
+ {
+ const char * name;
+ t_size name_length;
+ p_params->get_param(0,name,name_length);
+ t_size index_val = p_params->get_param_uint(1);
+ const char * value = m_info->meta_get_ex(name,name_length,index_val);
+ if (value != 0)
+ {
+ p_found_flag = true;
+ p_out->write(titleformat_inputtypes::meta,value,infinite);
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"meta_sep",infinite))
+ {
+ switch(p_params->get_param_count())
+ {
+ case 2:
+ {
+ const char * name, * sep1;
+ t_size name_length, sep1_length;
+ p_params->get_param(0,name,name_length);
+ p_params->get_param(1,sep1,sep1_length);
+ bool status = process_meta(p_out,name,name_length,sep1,sep1_length,sep1,sep1_length);
+ p_found_flag = status;
+ return true;
+ }
+ case 3:
+ {
+ const char * name, * sep1, * sep2;
+ t_size name_length, sep1_length, sep2_length;
+ p_params->get_param(0,name,name_length);
+ p_params->get_param(1,sep1,sep1_length);
+ p_params->get_param(2,sep2,sep2_length);
+ bool status = process_meta(p_out,name,name_length,sep1,sep1_length,sep2,sep2_length);
+ p_found_flag = status;
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"meta_test",infinite))
+ {
+ t_size n, count = p_params->get_param_count();
+ if (count == 0) return false;
+ bool found_all = true;
+ for(n=0;n<count;n++)
+ {
+ const char * name;
+ t_size name_length;
+ p_params->get_param(n,name,name_length);
+ if (!m_info->meta_exists_ex(name,name_length))
+ {
+ found_all = false;
+ break;
+ }
+ }
+ if (found_all)
+ {
+ p_found_flag = true;
+ p_out->write_int(titleformat_inputtypes::meta,1);
+ }
+ return true;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"meta_num",infinite))
+ {
+ if (p_params->get_param_count() != 1) return false;
+ const char * name;
+ t_size name_length;
+ p_params->get_param(0,name,name_length);
+ t_size count = m_info->meta_get_count_by_name_ex(name,name_length);
+ p_out->write_int(titleformat_inputtypes::meta,count);
+ if (count > 0) p_found_flag = true;
+ return true;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"info",infinite))
+ {
+ if (p_params->get_param_count() != 1) return false;
+ const char * name;
+ t_size name_length;
+ p_params->get_param(0,name,name_length);
+ const char * value = m_info->info_get_ex(name,name_length);
+ if (value != 0)
+ {
+ p_found_flag = true;
+ p_out->write(titleformat_inputtypes::meta,value);
+ }
+ return true;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"extra",infinite))
+ {
+ if (p_params->get_param_count() != 1) return false;
+ const char * name;
+ t_size name_length;
+ p_params->get_param(0,name,name_length);
+ if (process_extra(p_out,name,name_length)) p_found_flag = true;
+ return true;
+ } else if (!stricmp_utf8_ex(p_name,p_name_length,"codec",infinite))
+ {
+ if (p_params->get_param_count() != 0) return false;
+ process_codec(p_out);
+ p_found_flag = true;
+ return true;
+ } else if (!stricmp_utf8_ex(p_name,p_name_length,"channels",infinite))
+ {
+ if (p_params->get_param_count() != 0) return false;
+ unsigned val = (unsigned)m_info->info_get_int("channels");
+ switch(val)
+ {
+ case 0: p_out->write(titleformat_inputtypes::meta,"N/A",infinite); break;
+ case 1: p_out->write(titleformat_inputtypes::meta,"mono",infinite); p_found_flag = true; break;
+ case 2: p_out->write(titleformat_inputtypes::meta,"stereo",infinite); p_found_flag = true; break;
+ default: p_out->write_int(titleformat_inputtypes::meta,val); p_out->write(titleformat_inputtypes::meta,"ch",infinite); p_found_flag = true; break;
+ }
+ return true;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"tracknumber",infinite))
+ {
+ t_size pad = 2;
+ t_size param_count = p_params->get_param_count();
+ if (param_count > 1) return false;
+ if (param_count == 1) pad = (t_size)p_params->get_param_uint(0);
+ const char * val = m_info->meta_get_ex("tracknumber",infinite,0);
+ if (val != 0)
+ {
+ p_found_flag = true;
+ t_size val_len = strlen(val);
+ if (val_len < pad)
+ {
+ t_size n = pad - val_len;
+ do {
+ p_out->write(titleformat_inputtypes::meta,"0",1);
+ n--;
+ } while(n > 0);
+ }
+ p_out->write(titleformat_inputtypes::meta,val,infinite);
+ }
+ return true;
+ }
+ else return false;
+}
+
+bool titleformat_hook_impl_file_info::process_meta(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,const char * p_sep1,t_size p_sep1_length,const char * p_sep2,t_size p_sep2_length)
+{
+ t_size index = m_info->meta_find_ex(p_name,p_name_length);
+ return process_meta(p_out, index, p_sep1, p_sep1_length, p_sep2, p_sep2_length);
+}
+
+bool titleformat_hook_impl_file_info::process_meta(titleformat_text_out * p_out,t_size p_index,const char * p_sep1,t_size p_sep1_length,const char * p_sep2,t_size p_sep2_length)
+{
+ if (p_index == infinite) return false;
+
+ t_size n, m = m_info->meta_enum_value_count(p_index);
+ for(n=0;n<m;n++)
+ {
+ if (n>0)
+ {
+ if (n+1 == m) p_out->write(titleformat_inputtypes::meta,p_sep2,p_sep2_length);
+ else p_out->write(titleformat_inputtypes::meta,p_sep1,p_sep1_length);
+ }
+ p_out->write(titleformat_inputtypes::meta,m_info->meta_enum_value(p_index,n),infinite);
+ }
+ return true;
+}
+
+bool titleformat_hook_impl_file_info::process_extra(titleformat_text_out * p_out,const char * p_name,t_size p_name_length)
+{
+ if (!stricmp_utf8_ex(p_name,p_name_length,"PATH_RAW",infinite))
+ {
+ p_out->write(titleformat_inputtypes::unknown,m_location.get_path(),infinite);
+ return true;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"FOOBAR2000_VERSION",infinite))
+ {
+ p_out->write(titleformat_inputtypes::unknown,core_version_info::g_get_version_string(),infinite);
+ return true;
+ }
+ else return false;
+}
+
+void titleformat_object::run_hook(const playable_location & p_location,const file_info * p_source,titleformat_hook * p_hook,pfc::string_base & p_out,titleformat_text_filter * p_filter)
+{
+ if (p_hook)
+ {
+ run(
+ &titleformat_hook_impl_splitter(
+ &titleformat_hook_impl_file_info(p_location,p_source),
+ p_hook),
+ p_out,p_filter);
+ }
+ else
+ {
+ run(
+ &titleformat_hook_impl_file_info(p_location,p_source),
+ p_out,p_filter);
+ }
+}
+
+void titleformat_object::run_simple(const playable_location & p_location,const file_info * p_source,pfc::string_base & p_out)
+{
+ run(&titleformat_hook_impl_file_info(p_location,p_source),p_out,NULL);
+}
+
+t_size titleformat_hook_function_params::get_param_uint(t_size index)
+{
+ const char * str;
+ t_size str_len;
+ get_param(index,str,str_len);
+ return pfc::atoui_ex(str,str_len);
+}
+
+
+void titleformat_text_out_impl_filter_chars::write(const GUID & p_inputtype,const char * p_data,t_size p_data_length)
+{
+ titleformat_compiler::remove_forbidden_chars(m_chain,p_inputtype,p_data,p_data_length,m_restricted_chars);
+}
+
+bool titleformat_hook_impl_splitter::process_field(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,bool & p_found_flag)
+{
+ p_found_flag = false;
+ if (m_hook1 && m_hook1->process_field(p_out,p_name,p_name_length,p_found_flag)) return true;
+ p_found_flag = false;
+ if (m_hook2 && m_hook2->process_field(p_out,p_name,p_name_length,p_found_flag)) return true;
+ p_found_flag = false;
+ return false;
+}
+
+bool titleformat_hook_impl_splitter::process_function(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,titleformat_hook_function_params * p_params,bool & p_found_flag)
+{
+ p_found_flag = false;
+ if (m_hook1 && m_hook1->process_function(p_out,p_name,p_name_length,p_params,p_found_flag)) return true;
+ p_found_flag = false;
+ if (m_hook2 && m_hook2->process_function(p_out,p_name,p_name_length,p_params,p_found_flag)) return true;
+ p_found_flag = false;
+ return false;
+}
+
+void titleformat_text_out::write_int_padded(const GUID & p_inputtype,t_int64 val,t_int64 maxval)
+{
+ const t_size bufsize = 64;
+ char temp[bufsize+1];
+ t_size len = 0;
+ while(maxval) {maxval/=10;len++;}
+ if (len == 0) len = 1;
+ t_size n;
+ for(n=0;n<bufsize;n++) temp[n] = '0';
+ temp[n] = 0;
+ _i64toa(val,temp+bufsize/2,10);
+ write(p_inputtype,temp + strlen(temp) - len,infinite);
+}
+
+void titleformat_text_out::write_int(const GUID & p_inputtype,t_int64 val)
+{
+ write(p_inputtype,pfc::format_int(val));
+}
+void titleformat_text_filter_impl_reserved_chars::write(const GUID & p_inputtype,pfc::string_receiver & p_out,const char * p_data,t_size p_data_length)
+{
+ if (p_inputtype == titleformat_inputtypes::meta) titleformat_compiler::remove_forbidden_chars_string_append(p_out,p_data,p_data_length,m_reserved_chars);
+ else p_out.add_string(p_data,p_data_length);
+}
+
+void titleformat_compiler::run(titleformat_hook * p_source,pfc::string_base & p_out,const char * p_spec)
+{
+ service_ptr_t<titleformat_object> ptr;
+ if (!compile(ptr,p_spec)) p_out = "[COMPILATION ERROR]";
+ else ptr->run(p_source,p_out,NULL);
+}
+
+void titleformat_compiler::compile_safe(service_ptr_t<titleformat_object> & p_out,const char * p_spec)
+{
+ if (!compile(p_out,p_spec)) {
+ if (!compile(p_out,"%filename%"))
+ throw pfc::exception_bug_check();
+ }
+}
+
+
+namespace titleformat_inputtypes {
+ const GUID meta = { 0xcd839c8e, 0x5c66, 0x4ae1, { 0x8d, 0xad, 0x71, 0x1f, 0x86, 0x0, 0xa, 0xe3 } };
+ const GUID unknown = { 0x673aa1cd, 0xa7a8, 0x40c8, { 0xbf, 0x9b, 0x34, 0x37, 0x99, 0x29, 0x16, 0x3b } };
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat.h
new file mode 100644
index 0000000..eccf69a
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat.h
@@ -0,0 +1,149 @@
+#ifndef _FOOBAR2000_TITLEFORMAT_H_
+#define _FOOBAR2000_TITLEFORMAT_H_
+
+namespace titleformat_inputtypes {
+ extern const GUID meta, unknown;
+};
+
+class NOVTABLE titleformat_text_out {
+public:
+ virtual void write(const GUID & p_inputtype,const char * p_data,t_size p_data_length = infinite) = 0;
+ void write_int(const GUID & p_inputtype,t_int64 val);
+ void write_int_padded(const GUID & p_inputtype,t_int64 val,t_int64 maxval);
+protected:
+ titleformat_text_out() {}
+ ~titleformat_text_out() {}
+};
+
+
+class NOVTABLE titleformat_text_filter {
+public:
+ virtual void write(const GUID & p_inputtype,pfc::string_receiver & p_out,const char * p_data,t_size p_data_length) = 0;
+protected:
+ titleformat_text_filter() {}
+ ~titleformat_text_filter() {}
+};
+
+class NOVTABLE titleformat_hook_function_params
+{
+public:
+ virtual t_size get_param_count() = 0;
+ virtual void get_param(t_size index,const char * & p_string,t_size & p_string_len) = 0;//warning: not a null-terminated string
+
+ //helper
+ t_size get_param_uint(t_size index);
+};
+
+class NOVTABLE titleformat_hook
+{
+public:
+ virtual bool process_field(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,bool & p_found_flag) = 0;
+ virtual bool process_function(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,titleformat_hook_function_params * p_params,bool & p_found_flag) = 0;
+};
+//! Represents precompiled executable title-formatting script. Use titleformat_compiler to instantiate; do not reimplement.
+class NOVTABLE titleformat_object : public service_base
+{
+public:
+ virtual void run(titleformat_hook * p_source,pfc::string_base & p_out,titleformat_text_filter * p_filter)=0;
+
+ void run_hook(const playable_location & p_location,const file_info * p_source,titleformat_hook * p_hook,pfc::string_base & p_out,titleformat_text_filter * p_filter);
+ void run_simple(const playable_location & p_location,const file_info * p_source,pfc::string_base & p_out);
+
+ FB2K_MAKE_SERVICE_INTERFACE(titleformat_object,service_base);
+};
+
+//! Standard service for instantiating titleformat_object. Implemented by the core; do not reimplement.
+//! To instantiate, use static_api_ptr_t<titleformat_compiler>.
+class NOVTABLE titleformat_compiler : public service_base
+{
+public:
+ //! Returns false in case of a compilation error.
+ virtual bool compile(service_ptr_t<titleformat_object> & p_out,const char * p_spec) = 0;
+ //! Helper;
+ void run(titleformat_hook * p_source,pfc::string_base & p_out,const char * p_spec);
+ //! Should never fail, falls back to %filename% in case of failure.
+ void compile_safe(service_ptr_t<titleformat_object> & p_out,const char * p_spec);
+
+ //! Throws bug check when script can't be compiled. For use with hardcoded scripts only.
+ void compile_force(service_ptr_t<titleformat_object> & p_out,const char * p_spec) {if (!compile(p_out,p_spec)) throw pfc::exception_bug_check();}
+
+
+ static void remove_color_marks(const char * src,pfc::string_base & out);//helper
+ static void remove_forbidden_chars(titleformat_text_out * p_out,const GUID & p_inputtype,const char * p_source,t_size p_source_len,const char * p_forbidden_chars);
+ static void remove_forbidden_chars_string_append(pfc::string_receiver & p_out,const char * p_source,t_size p_source_len,const char * p_forbidden_chars);
+ static void remove_forbidden_chars_string(pfc::string_base & p_out,const char * p_source,t_size p_source_len,const char * p_forbidden_chars);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(titleformat_compiler);
+};
+
+
+class titleformat_object_wrapper {
+public:
+ titleformat_object_wrapper(const char * p_script) {
+ static_api_ptr_t<titleformat_compiler>()->compile_force(m_script,p_script);
+ }
+
+ operator const service_ptr_t<titleformat_object> &() const {return m_script;}
+
+private:
+ service_ptr_t<titleformat_object> m_script;
+};
+
+
+//helpers
+
+
+class titleformat_text_out_impl_filter_chars : public titleformat_text_out
+{
+public:
+ inline titleformat_text_out_impl_filter_chars(titleformat_text_out * p_chain,const char * p_restricted_chars)
+ : m_chain(p_chain), m_restricted_chars(p_restricted_chars) {}
+ void write(const GUID & p_inputtype,const char * p_data,t_size p_data_length);
+private:
+ titleformat_text_out * m_chain;
+ const char * m_restricted_chars;
+};
+
+class titleformat_text_out_impl_string : public titleformat_text_out {
+public:
+ titleformat_text_out_impl_string(pfc::string_receiver & p_string) : m_string(p_string) {}
+ void write(const GUID & p_inputtype,const char * p_data,t_size p_data_length) {m_string.add_string(p_data,p_data_length);}
+private:
+ pfc::string_receiver & m_string;
+};
+
+class titleformat_hook_impl_file_info : public titleformat_hook
+{
+public:
+ titleformat_hook_impl_file_info(const playable_location & p_location,const file_info * p_info) : m_location(p_location), m_info(p_info) {}//caller must ensure that referenced file_info object is alive as long as the titleformat_hook_impl_file_info instance
+ bool process_field(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,bool & p_found_flag);
+ bool process_function(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,titleformat_hook_function_params * p_params,bool & p_found_flag);
+protected:
+ bool process_meta(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,const char * p_sep1,t_size p_sep1_length,const char * p_sep2,t_size p_sep2_length);
+ bool process_meta(titleformat_text_out * p_out,t_size p_index,const char * p_sep1,t_size p_sep1_length,const char * p_sep2,t_size p_sep2_length);
+ bool process_extra(titleformat_text_out * p_out,const char * p_name,t_size p_name_length);
+ bool remap_meta(t_size & p_index, const char * p_name, t_size p_name_length);
+ const file_info * m_info;
+private:
+ void process_codec(titleformat_text_out * p_out);
+ const playable_location & m_location;
+};
+
+class titleformat_hook_impl_splitter : public titleformat_hook {
+public:
+ inline titleformat_hook_impl_splitter(titleformat_hook * p_hook1,titleformat_hook * p_hook2) : m_hook1(p_hook1), m_hook2(p_hook2) {}
+ bool process_field(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,bool & p_found_flag);
+ bool process_function(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,titleformat_hook_function_params * p_params,bool & p_found_flag);
+private:
+ titleformat_hook * m_hook1, * m_hook2;
+};
+
+class titleformat_text_filter_impl_reserved_chars : public titleformat_text_filter {
+public:
+ titleformat_text_filter_impl_reserved_chars(const char * p_reserved_chars) : m_reserved_chars(p_reserved_chars) {}
+ virtual void write(const GUID & p_inputtype,pfc::string_receiver & p_out,const char * p_data,t_size p_data_length);
+private:
+ const char * m_reserved_chars;
+};
+
+#endif //_FOOBAR2000_TITLEFORMAT_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat_config.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat_config.cpp
new file mode 100644
index 0000000..f607121
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat_config.cpp
@@ -0,0 +1,112 @@
+#include "foobar2000.h"
+
+
+//void on_change(const char * p_name,const char * p_value,unsigned p_value_length) ;
+
+void titleformat_config_callback::g_on_change(const GUID & p_guid,const char * p_name,const char * p_value,t_size p_value_length)
+{
+ service_ptr_t<titleformat_config_callback> ptr;
+ service_enum_t<titleformat_config_callback> e;
+ while(e.next(ptr))
+ ptr->on_change(p_guid,p_name,p_value,p_value_length);
+}
+
+const char * titleformat_config_impl::get_name()
+{
+ return m_name;
+}
+
+
+void titleformat_config_impl::get_data(pfc::string_base & p_out)
+{
+ insync(m_sync);
+ p_out = m_value;
+}
+
+
+void titleformat_config_impl::set_data(const char * p_string,unsigned p_string_length)
+{
+ core_api::ensure_main_thread();
+ {
+ insync(m_sync);
+ m_value.set_string(p_string,p_string_length);
+ m_compilation_failed = false;
+ m_instance.release();
+ }
+ titleformat_config_callback::g_on_change(m_guid,m_name,p_string,p_string_length);
+}
+
+bool titleformat_config_impl::compile(service_ptr_t<titleformat_object> & p_out)
+{
+ insync(m_sync);
+ if (m_instance.is_empty())
+ {
+ if (m_compilation_failed) return false;
+ if (!static_api_ptr_t<titleformat_compiler>()->compile(m_instance,m_value))
+ {
+ m_compilation_failed = true;
+ return false;
+ }
+ }
+ p_out = m_instance;
+ return true;
+}
+
+void titleformat_config_impl::reset()
+{
+ set_data(m_value_default,infinite);
+}
+
+
+void titleformat_config_impl::get_data_raw(stream_writer * p_stream,abort_callback & p_abort)
+{
+ p_stream->write_string_raw(m_value,p_abort);
+}
+
+void titleformat_config_impl::set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort)
+{
+ pfc::string8_fastalloc temp;
+ p_stream->read_string_raw(temp,p_abort);
+ m_instance.release();
+ m_compilation_failed = false;
+ m_value = temp;
+}
+
+titleformat_config_impl::titleformat_config_impl(const GUID & p_guid,const char * p_name,const char * p_initvalue,double p_order) :
+cfg_var(p_guid), m_guid(p_guid), m_name(p_name), m_value(p_initvalue), m_value_default(p_initvalue), m_compilation_failed(false), m_order(p_order) {}
+
+
+GUID titleformat_config_impl::get_guid() {return m_guid;}
+
+
+bool titleformat_config::g_find(const GUID & p_guid,service_ptr_t<titleformat_config> & p_out)
+{
+ service_ptr_t<titleformat_config> ptr;
+ service_enum_t<titleformat_config> e;
+ while(e.next(ptr))
+ {
+ if (ptr->get_guid() == p_guid)
+ {
+ p_out = ptr;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool titleformat_config::g_compile(const GUID & p_guid,service_ptr_t<titleformat_object> & p_out)
+{
+ service_ptr_t<titleformat_config> ptr;
+ if (!g_find(p_guid,ptr)) return false;
+ return ptr->compile(p_out);
+}
+
+bool titleformat_config::g_get_data(const GUID & p_guid,pfc::string_base & p_out)
+{
+ service_ptr_t<titleformat_config> ptr;
+ if (!g_find(p_guid,ptr)) return false;
+ ptr->get_data(p_out);
+ return true;
+}
+
+double titleformat_config_impl::get_order_priority() {return m_order;} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat_config.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat_config.h
new file mode 100644
index 0000000..6ce0c14
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/titleformat_config.h
@@ -0,0 +1,67 @@
+#ifndef _TITLEFORMAT_CONFIG_H_
+#define _TITLEFORMAT_CONFIG_H_
+
+
+class NOVTABLE titleformat_config : public service_base
+{
+public:
+ virtual GUID get_guid() = 0;
+ virtual const char * get_name() = 0;
+ virtual void get_data(pfc::string_base & p_out) = 0;
+ virtual void set_data(const char * p_string,unsigned p_string_length) = 0;
+ virtual void reset() = 0;
+ virtual bool compile(service_ptr_t<titleformat_object> & p_out) = 0;
+ virtual double get_order_priority() = 0;
+
+
+
+ static bool g_find(const GUID & p_guid,service_ptr_t<titleformat_config> & p_out);
+ static bool g_get_data(const GUID & p_guid,pfc::string_base & p_out);
+ static bool g_compile(const GUID & p_guid,service_ptr_t<titleformat_object> & p_out);
+
+
+ static const GUID config_playlist,config_copy,config_statusbar,config_systray,config_windowtitle;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(titleformat_config);
+};
+
+class titleformat_config_callback : public service_base
+{
+public:
+ virtual void on_change(const GUID & p_guid,const char * p_name,const char * p_value,t_size p_value_length) = 0;
+
+ static void g_on_change(const GUID & p_guid,const char * p_name,const char * p_value,t_size p_value_length);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(titleformat_config_callback);
+};
+
+class titleformat_config_impl : public titleformat_config, private cfg_var
+{
+public:
+ GUID get_guid();
+ const char * get_name();
+ void get_data(pfc::string_base & p_out);
+ void set_data(const char * p_string,unsigned p_string_length);
+ void reset();
+ bool compile(service_ptr_t<titleformat_object> & p_out);
+ double get_order_priority();
+ titleformat_config_impl(const GUID &,const char * p_name,const char * p_initvalue,double p_order);
+private:
+
+ void get_data_raw(stream_writer * p_stream,abort_callback & p_abort);
+ void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort);
+
+ pfc::string8 m_name,m_value,m_value_default;
+ service_ptr_t<titleformat_object> m_instance;
+ bool m_compilation_failed;
+ GUID m_guid;
+ double m_order;
+ critical_section m_sync;
+};
+
+typedef service_factory_single_transparent_t<titleformat_config_impl> titleformat_config_factory;
+
+//usage:
+//static titleformat_config_factory g_mytitleformatconfig("this will show up in titleformat config page","%blah%");
+
+#endif //_TITLEFORMAT_CONFIG_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/track_property.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/track_property.h
new file mode 100644
index 0000000..8b11d61
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/track_property.h
@@ -0,0 +1,30 @@
+//! Callback interface for track_property_provider::enumerate_properties().
+class NOVTABLE track_property_callback {
+public:
+ //! Sets a property list entry to display. Called by track_property_provider::enumerate_properties() implementation.
+ //! @param p_group Name of group to put the entry in, case-sensitive. Note that non-standard groups are sorted alphabetically.
+ //! @param p_sortpriority Sort priority of the property inside its group (smaller value means earlier in the list), pass 0 if you don't care (alphabetic order by name used when more than one item has same priority).
+ //! @param p_name Name of the property.
+ //! @param p_value Value of the property.
+ virtual void set_property(const char * p_group,double p_sortpriority,const char * p_name,const char * p_value) = 0;
+protected:
+ ~track_property_callback() {}
+};
+
+//! Service for adding custom entries in "General Properties" section of the properties dialog.
+class NOVTABLE track_property_provider : public service_base {
+public:
+ //! Enumerates properties of specified track list.
+ //! @param p_tracks List of tracks to enumerate properties on.
+ //! @param p_out Callback interface receiving enumerated properties.
+ virtual void enumerate_properties(pfc::list_base_const_t<metadb_handle_ptr> const & p_tracks, track_property_callback & p_out) = 0;
+ //! Returns whether specified tech info filed is processed by our service and should not be displayed among unknown fields.
+ //! @param p_name Name of tech info field being queried.
+ //! @returns True if the field is among fields processed by this track_property_provider implementation and should not be displayed among unknown fields, false otherwise.
+ virtual bool is_our_tech_info(const char * p_name) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(track_property_provider);
+};
+
+template<typename T>
+class track_property_provider_factory_t : public service_factory_single_t<T> {};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/ui.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/ui.cpp
new file mode 100644
index 0000000..7417e65
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/ui.cpp
@@ -0,0 +1,35 @@
+#include "foobar2000.h"
+
+bool ui_drop_item_callback::g_on_drop(interface IDataObject * pDataObject)
+{
+ service_enum_t<ui_drop_item_callback> e;
+ service_ptr_t<ui_drop_item_callback> ptr;
+ if (e.first(ptr)) do {
+ if (ptr->on_drop(pDataObject)) return true;
+ } while(e.next(ptr));
+ return false;
+}
+
+bool ui_drop_item_callback::g_is_accepted_type(interface IDataObject * pDataObject, DWORD * p_effect)
+{
+ service_enum_t<ui_drop_item_callback> e;
+ service_ptr_t<ui_drop_item_callback> ptr;
+ if (e.first(ptr)) do {
+ if (ptr->is_accepted_type(pDataObject,p_effect)) return true;
+ } while(e.next(ptr));
+ return false;
+}
+
+bool user_interface::g_find(service_ptr_t<user_interface> & p_out,const GUID & p_guid)
+{
+ service_enum_t<user_interface> e;
+ service_ptr_t<user_interface> ptr;
+ if (e.first(ptr)) do {
+ if (ptr->get_guid() == p_guid)
+ {
+ p_out = ptr;
+ return true;
+ }
+ } while(e.next(ptr));
+ return false;
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/ui.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/ui.h
new file mode 100644
index 0000000..d960190
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/ui.h
@@ -0,0 +1,110 @@
+#ifndef _FOOBAR2000_UI_H_
+#define _FOOBAR2000_UI_H_
+
+#include "service.h"
+
+#ifndef _WINDOWS
+#error PORTME
+#endif
+
+//! Entrypoint service for user interface modules. Implement when registering an UI module. Do not call existing implementations; only core enumerates / dispatches calls. To control UI behaviors from other components, use ui_control API. \n
+//! Use user_interface_factory_t<> to register, e.g static user_interface_factory_t<myclass> g_myclass_factory;
+class NOVTABLE user_interface : public service_base {
+public:
+ //!HookProc usage: \n
+ //! in your windowproc, call HookProc first, and if it returns true, return LRESULT value it passed to you
+ typedef BOOL (WINAPI * HookProc_t)(HWND wnd,UINT msg,WPARAM wp,LPARAM lp,LRESULT * ret);
+
+ //! Retrieves name (UTF-8 null-terminated string) of the UI module.
+ virtual const char * get_name()=0;
+ //! Initializes the UI module - creates the main app window, etc. Failure should be signaled by appropriate exception (std::exception or a derivative).
+ virtual HWND init(HookProc_t hook)=0;
+ //! Deinitializes the UI module - destroys the main app window, etc.
+ virtual void shutdown()=0;
+ //! Activates main app window.
+ virtual void activate()=0;
+ //! Minimizes/hides main app window.
+ virtual void hide()=0;
+ //! Returns whether main window is visible / not minimized. Used for activate/hide command.
+ virtual bool is_visible() = 0;
+ //! Retrieves GUID of your implementation, to be stored in configuration file etc.
+ virtual GUID get_guid() = 0;
+
+ //! Overrides statusbar text with specified string. The parameter is a null terminated UTF-8 string. The override is valid until another override_statusbar_text() call or revert_statusbar_text() call.
+ virtual void override_statusbar_text(const char * p_text) = 0;
+ //! Disables statusbar text override.
+ virtual void revert_statusbar_text() = 0;
+
+ //! Shows now-playing item somehow (e.g. system notification area popup).
+ virtual void show_now_playing() = 0;
+
+ static bool g_find(service_ptr_t<user_interface> & p_out,const GUID & p_guid);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(user_interface);
+};
+
+template<typename T>
+class user_interface_factory : public service_factory_single_t<T> {};
+
+//! Interface class allowing you to override UI statusbar text. There may be multiple callers trying to override statusbar text; backend decides which one succeeds so you will not always get what you want. Statusbar text override is automatically cancelled when the object is released.\n
+//! Use ui_control::override_status_text_create() to instantiate.
+//! Implemented by core. Do not reimplement.
+class NOVTABLE ui_status_text_override : public service_base
+{
+public:
+ //! Sets statusbar text to specified UTF-8 null-terminated string.
+ virtual void override_text(const char * p_message) = 0;
+ //! Cancels statusbar text override.
+ virtual void revert_text() = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE(ui_status_text_override,service_base);
+};
+
+//! Serivce providing various UI-related commands. Implemented by core; do not reimplement.
+//! Instantiation: use static_api_ptr_t<ui_control>.
+class NOVTABLE ui_control : public service_base {
+public:
+ //! Returns whether primary UI is visible/unminimized.
+ virtual bool is_visible()=0;
+ //! Activates/unminimizes main UI.
+ virtual void activate()=0;
+ //! Hides/minimizese main UI.
+ virtual void hide()=0;
+ //! Retrieves main GUI icon, to use as window icon etc. Returned handle does not need to be freed.
+ virtual HICON get_main_icon()=0;
+ //! Loads main GUI icon, version with specified width/height. Returned handle needs to be freed with DestroyIcon when you are done using it.
+ virtual HICON load_main_icon(unsigned width,unsigned height) = 0;
+
+ //! Activates preferences dialog and navigates to specified page. See also: preference_page API.
+ virtual void show_preferences(const GUID & p_page) = 0;
+
+ //! Instantiates ui_status_text_override service, that can be used to display status messages.
+ //! @param p_out receives new ui_status_text_override instance.
+ //! @returns true on success, false on failure (out of memory / no GUI loaded / etc)
+ virtual bool override_status_text_create(service_ptr_t<ui_status_text_override> & p_out) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(ui_control);
+};
+
+//! Service called from the UI when some object is dropped into the UI. Usable for modifying drag&drop behaviors such as adding custom handlers for object types other than supported media files.\n
+//! Implement where needed; use ui_drop_item_callback_factory_t<> template to register, e.g. static ui_drop_item_callback_factory_t<myclass> g_myclass_factory.
+class NOVTABLE ui_drop_item_callback : public service_base {
+public:
+ //! Called when an object was dropped; returns true if the object was processed and false if not.
+ virtual bool on_drop(interface IDataObject * pDataObject) = 0;
+ //! Tests whether specified object type is supported by this ui_drop_item_callback implementation. Returns true and sets p_effect when it's supported; returns false otherwise. \n
+ //! See IDropTarget::DragEnter() documentation for more information about p_effect values.
+ virtual bool is_accepted_type(interface IDataObject * pDataObject, DWORD * p_effect)=0;
+
+ //! Static helper, calls all existing implementations appropriately. See on_drop().
+ static bool g_on_drop(interface IDataObject * pDataObject);
+ //! Static helper, calls all existing implementations appropriately. See is_accepted_type().
+ static bool g_is_accepted_type(interface IDataObject * pDataObject, DWORD * p_effect);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(ui_drop_item_callback);
+};
+
+template<class T>
+class ui_drop_item_callback_factory_t : public service_factory_single_t<T> {};
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/unpack.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/unpack.h
new file mode 100644
index 0000000..2671fed
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/unpack.h
@@ -0,0 +1,27 @@
+#ifndef _UNPACK_H_
+#define _UNPACK_H_
+
+//! Service providing "unpacker" functionality - processes "packed" file (such as a zip file containing a single media file inside) to allow its contents to be accessed transparently.\n
+//! To access existing unpacker implementations, use unpacker::g_open helper function.\n
+//! To register your own implementation, use unpacker_factory_t template.
+class NOVTABLE unpacker : public service_base {
+public:
+ //! Attempts to open specified file for unpacking, creates interface to virtual file with uncompressed data on success. When examined file doesn't appear to be one of formats supported by this unpacker implementation, throws exception_io_data.
+ //! @param p_out Receives interface to virtual file with uncompressed data on success.
+ //! @param p_source Source file to process.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ virtual void open(service_ptr_t<file> & p_out,const service_ptr_t<file> & p_source,abort_callback & p_abort) = 0;
+
+ //! Static helper querying existing unpacker implementations until one that successfully opens specified file is found. Attempts to open specified file for unpacking, creates interface to virtual file with uncompressed data on success. When examined file doesn't appear to be one of formats supported by registered unpacker implementations, throws exception_io_data.
+ //! @param p_out Receives interface to virtual file with uncompressed data on success.
+ //! @param p_source Source file to process.
+ //! @param p_abort abort_callback object signaling user aborting the operation.
+ static void g_open(service_ptr_t<file> & p_out,const service_ptr_t<file> & p_source,abort_callback & p_abort);
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(unpacker);
+};
+
+template<typename t_myclass>
+class unpacker_factory_t : public service_factory_single_t<t_myclass> {};
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/utf8api.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/utf8api.cpp
new file mode 100644
index 0000000..914710e
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/utf8api.cpp
@@ -0,0 +1,11 @@
+#include "foobar2000.h"
+
+HWND uCreateDialog(UINT id,HWND parent,DLGPROC proc,LPARAM param)
+{
+ return CreateDialogParam(core_api::get_my_instance(),MAKEINTRESOURCE(id),parent,proc,param);
+}
+
+int uDialogBox(UINT id,HWND parent,DLGPROC proc,LPARAM param)
+{
+ return (int)DialogBoxParam(core_api::get_my_instance(),MAKEINTRESOURCE(id),parent,proc,param);
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/vis.h b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/vis.h
new file mode 100644
index 0000000..e91f257
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/SDK/vis.h
@@ -0,0 +1,46 @@
+#ifndef _FOOBAR2000_VIS_H_
+#define _FOOBAR2000_VIS_H_
+
+//! This class provides abstraction for receiving visualisation data. Instances of visualisation_stream being created/released serve as an indication for visualisation backend to process currently played audio data or shut down when there are no visualisation clients active.\n
+//! Use visualisation_manager::create_stream to instantiate.
+class NOVTABLE visualisation_stream : public service_base {
+public:
+ //! Retrieves absolute playback time since last playback start or seek. You typically pass value retrieved by this function - optionally with offset added - to other visualisation_stream methods.
+ virtual bool get_absolute_time(double & p_value) = 0;
+
+ //! Retrieves an audio chunk starting at specified offset (see get_absolute_time()), of specified length.
+ //! @returns False when requested timestamp is out of available range, true on success.
+ virtual bool get_chunk_absolute(audio_chunk & p_chunk,double p_offset,double p_requested_length) = 0;
+ //! Retrieves spectrum for audio data at specified offset (see get_absolute_time()), with specified FFT size.
+ //! @param p_chunk Receives spectrum data. audio_chunk type is used for consistency (since required functionality is identical to provided by audio_chunk), the data is *not* PCM. Returned sample count is equal to half of FFT size; channels and sample rate are as in audio stream the spectrum was generated from.
+ //! @param p_offset Timestamp of spectrum to retrieve. See get_absolute_time().
+ //! @param p_fft_size FFT size to use for spectrum generation. Must be a power of 2.
+ //! @returns False when requested timestamp is out of available range, true on success.
+ virtual bool get_spectrum_absolute(audio_chunk & p_chunk,double p_offset,unsigned p_fft_size) = 0;
+
+ //! Generates fake audio chunk to display when get_chunk_absolute() fails - e.g. shortly after visualisation_stream creation data for currently played audio might not be available yet.
+ //! Throws std::exception derivatives on failure.
+ virtual void make_fake_chunk_absolute(audio_chunk & p_chunk,double p_offset,double p_requested_length) = 0;
+ //! Generates fake spectrum to display when get_spectrum_absolute() fails - e.g. shortly after visualisation_stream creation data for currently played audio might not be available yet.
+ //! Throws std::exception derivatives on failure.
+ virtual void make_fake_spectrum_absolute(audio_chunk & p_chunk,double p_offset,unsigned p_fft_size) = 0;
+
+
+ FB2K_MAKE_SERVICE_INTERFACE(visualisation_stream,service_base);
+};
+
+//! Entrypoint service for visualisation processing; use this to create visualisation_stream objects that can be used to retrieve properties of currently played audio. \n
+//! Implemented by core; do not reimplement.\n
+//! Use static_api_ptr_t to access it, e.g. static_api_ptr_t<visualisation_manager>()->create_stream(mystream,0);
+class NOVTABLE visualisation_manager : public service_base {
+public:
+ //! Creates a visualisation_stream object. See visualisation_stream for more info.
+ //! @param p_out Receives newly created visualisation_stream instance.
+ //! @param p_flags Reserved for future use. Must be set to zero.
+ virtual void create_stream(service_ptr_t<visualisation_stream> & p_out,unsigned p_flags) = 0;
+
+ FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(visualisation_manager);
+};
+
+
+#endif //_FOOBAR2000_VIS_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/foobar2000_component_client/component_client.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/foobar2000_component_client/component_client.cpp
new file mode 100644
index 0000000..1b1c919
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/foobar2000_component_client/component_client.cpp
@@ -0,0 +1,132 @@
+#include "../SDK/foobar2000.h"
+#include "../SDK/component.h"
+
+static HINSTANCE g_hIns;
+
+static pfc::string_simple g_name,g_full_path;
+
+static bool g_services_available = false, g_initialized = false;
+
+
+
+namespace core_api
+{
+
+ HINSTANCE get_my_instance()
+ {
+ return g_hIns;
+ }
+
+ HWND get_main_window()
+ {
+ return g_api->get_main_window();
+ }
+ pcchar get_my_file_name()
+ {
+ return g_name;
+ }
+
+ pcchar get_my_full_path()
+ {
+ return g_full_path;
+ }
+
+ bool are_services_available()
+ {
+ return g_services_available;
+ }
+ bool assert_main_thread()
+ {
+ return (g_services_available && g_api) ? g_api->assert_main_thread() : true;
+ }
+
+ void ensure_main_thread() {
+ if (!assert_main_thread()) throw exception_wrong_thread();
+ }
+
+ bool is_main_thread()
+ {
+ return (g_services_available && g_api) ? g_api->is_main_thread() : true;
+ }
+ pcchar get_profile_path()
+ {
+ return (g_services_available && g_api) ? g_api->get_profile_path() : 0;
+ }
+
+ bool is_shutting_down()
+ {
+ return (g_services_available && g_api) ? g_api->is_shutting_down() : g_initialized;
+ }
+ bool is_initializing()
+ {
+ return (g_services_available && g_api) ? g_api->is_initializing() : !g_initialized;
+ }
+}
+
+namespace {
+ class foobar2000_client_impl : public foobar2000_client
+ {
+ public:
+ t_uint32 get_version() {return FOOBAR2000_CLIENT_VERSION;}
+ pservice_factory_base get_service_list() {return service_factory_base::__internal__list;}
+
+ void get_config(stream_writer * p_stream,abort_callback & p_abort) {
+ cfg_var::config_write_file(p_stream,p_abort);
+ }
+
+ void set_config(stream_reader * p_stream,abort_callback & p_abort) {
+ cfg_var::config_read_file(p_stream,p_abort);
+ }
+
+ void set_library_path(const char * path,const char * name) {
+ g_full_path = path;
+ g_name = name;
+ }
+
+ void services_init(bool val) {
+ if (val) g_initialized = true;
+ g_services_available = val;
+ }
+
+ bool is_debug() {
+#ifdef _DEBUG
+ return true;
+#else
+ return false;
+#endif
+ }
+ };
+}
+
+static foobar2000_client_impl g_client;
+
+extern "C"
+{
+ __declspec(dllexport) foobar2000_client * _cdecl foobar2000_get_interface(foobar2000_api * p_api,HINSTANCE hIns)
+ {
+ g_hIns = hIns;
+ g_api = p_api;
+
+ return &g_client;
+ }
+}
+
+#if 0
+BOOLEAN WINAPI DllMain(IN HINSTANCE hDllHandle, IN DWORD nReason, IN LPVOID Reserved )
+{
+ BOOLEAN bSuccess = TRUE;
+
+ switch ( nReason ) {
+ case DLL_PROCESS_ATTACH:
+
+ DisableThreadLibraryCalls( hDllHandle );
+
+ break;
+
+ case DLL_PROCESS_DETACH:
+
+ break;
+ }
+ return TRUE;
+}
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/foobar2000_component_client/foobar2000_component_client.vcproj b/Plugins/listeningto/players/foo_mlt/foobar2000/foobar2000_component_client/foobar2000_component_client.vcproj
new file mode 100644
index 0000000..15a2af8
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/foobar2000_component_client/foobar2000_component_client.vcproj
@@ -0,0 +1,332 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="foobar2000_component_client"
+ ProjectGUID="{71AD2674-065B-48F5-B8B0-E1F9D3892081}"
+ RootNamespace="foobar2000_component_client"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ EnableFiberSafeOptimizations="false"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="true"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ EnableFiberSafeOptimizations="false"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="true"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath="component_client.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ />
+ </FileConfiguration>
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/StdAfx.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/StdAfx.cpp
new file mode 100644
index 0000000..9dc5b54
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/StdAfx.cpp
@@ -0,0 +1,6 @@
+// stdafx.cpp : source file that includes just the standard includes
+// foobar2000_sdk_helpers.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/StdAfx.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/StdAfx.h
new file mode 100644
index 0000000..50a4e7b
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/StdAfx.h
@@ -0,0 +1,22 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__6356EC2B_6DD1_4BE8_935C_87ECBA8697E4__INCLUDED_)
+#define AFX_STDAFX_H__6356EC2B_6DD1_4BE8_935C_87ECBA8697E4__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+#include "../SDK/foobar2000.h"
+#include "helpers.h"
+
+// TODO: reference additional headers your program requires here
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__6356EC2B_6DD1_4BE8_935C_87ECBA8697E4__INCLUDED_)
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/bitreader_helper.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/bitreader_helper.h
new file mode 100644
index 0000000..4af87ef
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/bitreader_helper.h
@@ -0,0 +1,122 @@
+namespace bitreader_helper {
+
+ inline static size_t extract_bit(const t_uint8 * p_stream,size_t p_offset) {
+ return (p_stream[p_offset>>3] >> (7-(p_offset&7)))&1;
+ }
+
+ static size_t extract_int(const t_uint8 * p_stream,size_t p_base,size_t p_width) {
+ size_t ret = 0;
+ size_t offset = p_base;
+ for(size_t bit=0;bit<p_width;bit++) {
+ ret <<= 1;
+ ret |= extract_bit(p_stream,offset++);
+ }
+ return ret;
+ }
+
+class bitreader
+{
+public:
+ inline bitreader(const t_uint8 * p_ptr,t_size p_base)
+ : m_ptr(p_ptr), m_bitptr(p_base)
+ {
+ }
+
+ inline void skip(t_size p_bits)
+ {
+ m_bitptr += p_bits;
+ }
+
+ template<typename t_ret>
+ t_ret read_t(t_size p_bits) {
+ t_ret ret = 0;
+ for(t_size bit=0;bit<p_bits;bit++)
+ {
+ ret <<= 1;
+ ret |= (m_ptr[m_bitptr>>3] >> (7-(m_bitptr&7)))&1;
+ m_bitptr++;
+ }
+ return ret;
+ }
+
+ t_size read(t_size p_bits) {return read_t<t_size>(p_bits);}
+
+ inline t_size get_bitptr() const {return m_bitptr;}
+
+ inline bool read_bit() {
+ bool state = ( (m_ptr[m_bitptr>>3] >> (7-(m_bitptr&7)))&1 ) != 0;
+ m_bitptr++;
+ return state;
+ }
+
+private:
+
+ const t_uint8 * m_ptr;
+ t_size m_bitptr;
+};
+
+class bitreader_fromfile
+{
+public:
+ inline bitreader_fromfile(service_ptr_t<file> const& p_file) : m_file(p_file), m_buffer_ptr(0) {}
+
+ t_size read(t_size p_bits,abort_callback & p_abort) {
+ t_size ret = 0;
+ for(t_size bit=0;bit<p_bits;bit++) {
+ if (m_buffer_ptr == 0)
+ m_file->read_object(&m_buffer,1,p_abort);
+
+ ret <<= 1;
+ ret |= (m_buffer >> (7-m_buffer_ptr))&1;
+ m_buffer_ptr = (m_buffer_ptr+1) & 7;
+ }
+ return ret;
+ }
+
+ void skip(t_size p_bits,abort_callback & p_abort) {
+ for(t_size bit=0;bit<p_bits;bit++) {
+ if (m_buffer_ptr == 0) m_file->read_object(&m_buffer,1,p_abort);
+ m_buffer_ptr = (m_buffer_ptr+1) & 7;
+ }
+ }
+
+ inline void byte_align() {m_buffer_ptr = 0;}
+
+private:
+ service_ptr_t<file> m_file;
+ t_size m_buffer_ptr;
+ t_uint8 m_buffer;
+};
+
+class bitreader_limited
+{
+public:
+ inline bitreader_limited(const t_uint8 * p_ptr,t_size p_base,t_size p_remaining) : m_reader(p_ptr,p_base), m_remaining(p_remaining) {}
+
+ inline t_size get_bitptr() const {return m_reader.get_bitptr();}
+
+ inline t_size get_remaining() const {return m_remaining;}
+
+ inline void skip(t_size p_bits) {
+ if (p_bits > m_remaining) throw exception_io_data_truncation();
+ m_remaining -= p_bits;
+ m_reader.skip(p_bits);
+ }
+
+ t_size read(t_size p_bits)
+ {
+ if (p_bits > m_remaining) throw exception_io_data_truncation();
+ m_remaining -= p_bits;
+ return m_reader.read(p_bits);
+ }
+
+private:
+ bitreader m_reader;
+ t_size m_remaining;
+};
+
+inline static t_size extract_bits(const t_uint8 * p_buffer,t_size p_base,t_size p_count) {
+ return bitreader(p_buffer,p_base).read(p_count);
+}
+
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cfg_guidlist.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cfg_guidlist.h
new file mode 100644
index 0000000..dfdbae1
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cfg_guidlist.h
@@ -0,0 +1,29 @@
+class cfg_guidlist : public cfg_var, public pfc::list_t<GUID>
+{
+public:
+ void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {
+ t_uint32 n, m = pfc::downcast_guarded<t_uint32>(get_count());
+ p_stream->write_lendian_t(m,p_abort);
+ for(n=0;n<m;n++) p_stream->write_lendian_t(get_item(n),p_abort);
+ }
+ void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
+ t_uint32 n,count;
+ p_stream->read_lendian_t(count,p_abort);
+ m_buffer.set_size(count);
+ for(n=0;n<count;n++) {
+ try {
+ p_stream->read_lendian_t(m_buffer[n],p_abort);
+ } catch(...) {m_buffer.set_size(0); throw;}
+ }
+ }
+
+ void sort() {sort_t(pfc::guid_compare);}
+
+ bool have_item_bsearch(const GUID & p_item) {
+ t_size dummy;
+ return bsearch_t(pfc::guid_compare,p_item,dummy);
+ }
+
+public:
+ cfg_guidlist(const GUID & p_guid) : cfg_var(p_guid) {}
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cfg_structlist.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cfg_structlist.h
new file mode 100644
index 0000000..b06a31c
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cfg_structlist.h
@@ -0,0 +1,25 @@
+template<typename T>
+class cfg_structlist_t : public cfg_var, public pfc::list_t<T>
+{
+public:
+ void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {
+ t_uint32 n, m = get_count();
+ p_stream->write_lendian_t(m,p_abort);
+ for(n=0;n<m;n++) {
+ p_stream->write_object(&m_buffer[n],sizeof(T),p_abort);
+ }
+ }
+
+ void set_data_raw(stream_reader * p_stream,t_size,abort_callback & p_abort) {
+ t_uint32 n,count;
+ p_stream->read_lendian_t(count,p_abort);
+ m_buffer.set_size_e(count);
+ for(n=0;n<count;n++) {
+ try {
+ p_stream->read_object(&m_buffer[n],sizeof(T),p_abort);
+ } catch(...) {m_buffer.set_size(0); throw;}
+ }
+ }
+public:
+ cfg_structlist_t(const GUID & p_guid) : cfg_var(p_guid) {}
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/create_directory_helper.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/create_directory_helper.cpp
new file mode 100644
index 0000000..e8734df
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/create_directory_helper.cpp
@@ -0,0 +1,151 @@
+#include "stdafx.h"
+#include "create_directory_helper.h"
+
+namespace create_directory_helper
+{
+ static void create_path_internal(const char * p_path,t_size p_base,abort_callback & p_abort) {
+ pfc::string8_fastalloc temp;
+ for(t_size walk = p_base; p_path[walk]; walk++) {
+ if (p_path[walk] == '\\') {
+ temp.set_string(p_path,walk);
+ try {filesystem::g_create_directory(temp.get_ptr(),p_abort);} catch(exception_io_already_exists) {}
+ }
+ }
+ }
+
+ static bool is_valid_netpath_char(char p_char) {
+ return pfc::char_is_ascii_alphanumeric(p_char) || p_char == '_' || p_char == '-';
+ }
+
+ static bool test_localpath(const char * p_path) {
+ if (pfc::strcmp_partial(p_path,"file://") == 0) p_path += strlen("file://");
+ return pfc::char_is_ascii_alpha(p_path[0]) &&
+ p_path[1] == ':' &&
+ p_path[2] == '\\';
+ }
+ static bool test_netpath(const char * p_path) {
+ if (pfc::strcmp_partial(p_path,"file://") == 0) p_path += strlen("file://");
+ if (*p_path != '\\') return false;
+ p_path++;
+ if (*p_path != '\\') return false;
+ p_path++;
+ if (!is_valid_netpath_char(*p_path)) return false;
+ p_path++;
+ while(is_valid_netpath_char(*p_path)) p_path++;
+ if (*p_path != '\\') return false;
+ return true;
+ }
+
+ void create_path(const char * p_path,abort_callback & p_abort) {
+ if (test_localpath(p_path)) {
+ t_size walk = 0;
+ if (pfc::strcmp_partial(p_path,"file://") == 0) walk += strlen("file://");
+ create_path_internal(p_path,walk + 3,p_abort);
+ } else if (test_netpath(p_path)) {
+ t_size walk = 0;
+ if (pfc::strcmp_partial(p_path,"file://") == 0) walk += strlen("file://");
+ while(p_path[walk] == '\\') walk++;
+ while(p_path[walk] != 0 && p_path[walk] != '\\') walk++;
+ while(p_path[walk] == '\\') walk++;
+ create_path_internal(p_path,walk,p_abort);
+ } else {
+ throw exception_io("Could not create directory structure; unknown path format");
+ }
+ }
+
+ static bool is_bad_dirchar(char c)
+ {
+ return c==' ' || c=='.';
+ }
+
+ void make_path(const char * parent,const char * filename,const char * extension,bool allow_new_dirs,pfc::string8 & out,bool really_create_dirs,abort_callback & p_abort)
+ {
+ out.reset();
+ if (parent && *parent)
+ {
+ out = parent;
+ out.fix_dir_separator('\\');
+ }
+ bool last_char_is_dir_sep = true;
+ while(*filename)
+ {
+#ifdef WIN32
+ if (allow_new_dirs && is_bad_dirchar(*filename))
+ {
+ const char * ptr = filename+1;
+ while(is_bad_dirchar(*ptr)) ptr++;
+ if (*ptr!='\\' && *ptr!='/') out.add_string(filename,ptr-filename);
+ filename = ptr;
+ if (*filename==0) break;
+ }
+#endif
+ if (pfc::is_path_bad_char(*filename))
+ {
+ if (allow_new_dirs && (*filename=='\\' || *filename=='/'))
+ {
+ if (!last_char_is_dir_sep)
+ {
+ if (really_create_dirs) try{filesystem::g_create_directory(out,p_abort);}catch(exception_io_already_exists){}
+ out.add_char('\\');
+ last_char_is_dir_sep = true;
+ }
+ }
+ else
+ out.add_char('_');
+ }
+ else
+ {
+ out.add_byte(*filename);
+ last_char_is_dir_sep = false;
+ }
+ filename++;
+ }
+ if (out.length()>0 && out[out.length()-1]=='\\')
+ {
+ out.add_string("noname");
+ }
+ if (extension && *extension)
+ {
+ out.add_char('.');
+ out.add_string(extension);
+ }
+ }
+}
+
+namespace {
+
+ class titleformat_text_filter_impl_createdir : public titleformat_text_filter
+ {
+ public:
+ void on_new_field() {}
+ void write(const GUID & p_inputtype,pfc::string_receiver & p_out,const char * p_data,t_size p_data_length)
+ {//not "UTF-8 aware" but coded not to clash with UTF-8, since only filtered chars are lower ASCII
+ if (p_inputtype == titleformat_inputtypes::meta) {
+ t_size index = 0;
+ t_size good_bytes = 0;
+ while(index < p_data_length && p_data[index] != 0) {
+ unsigned char c = (unsigned char)p_data[index];
+ if (c < ' ' || c == '\\' || c=='/' || c=='|' || c==':')
+ {
+ if (good_bytes > 0) {p_out.add_string(p_data+index-good_bytes,good_bytes);good_bytes=0;}
+ p_out.add_string("_",1);
+ }
+ else good_bytes++;
+ index++;
+ }
+ if (good_bytes > 0) {p_out.add_string(p_data+index-good_bytes,good_bytes);good_bytes=0;}
+ } else {
+ p_out.add_string(p_data,p_data_length);
+ }
+ }
+ };
+}
+
+void create_directory_helper::format_filename(const metadb_handle_ptr & handle,titleformat_hook * p_hook,const char * spec,pfc::string8 & out)
+{
+ pfc::string8 temp;
+ handle->format_title_legacy(p_hook,temp,spec,&titleformat_text_filter_impl_createdir());
+ temp.replace_char('/','\\');
+ temp.fix_filename_chars('_','\\');
+ out = temp;
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/create_directory_helper.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/create_directory_helper.h
new file mode 100644
index 0000000..b156241
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/create_directory_helper.h
@@ -0,0 +1,10 @@
+#ifndef _CREATE_DIRECTORY_HELPER_H_
+#define _CREATE_DIRECTORY_HELPER_H_
+
+namespace create_directory_helper {
+ void create_path(const char * p_path,abort_callback & p_abort);
+ void make_path(const char * parent,const char * filename,const char * extension,bool allow_new_dirs,pfc::string8 & out,bool b_really_create_dirs,abort_callback & p_dir_create_abort);
+ void format_filename(const metadb_handle_ptr & handle,titleformat_hook * p_hook,const char * spec,pfc::string8 & out);
+};
+
+#endif//_CREATE_DIRECTORY_HELPER_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_creator.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_creator.cpp
new file mode 100644
index 0000000..6b261ce
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_creator.cpp
@@ -0,0 +1,171 @@
+#include "stdafx.h"
+
+
+namespace {
+
+ class format_meta
+ {
+ public:
+ format_meta(const file_info & p_source,const char * p_name,bool p_allow_space = true)
+ {
+ p_source.meta_format(p_name,m_buffer);
+ m_buffer.replace_byte('\"','\'');
+ uReplaceString(m_buffer,pfc::string8(m_buffer),infinite,"\x0d\x0a",2,"\\",1,false);
+ if (!p_allow_space) m_buffer.replace_byte(' ','_');
+ m_buffer.replace_nontext_chars();
+ }
+ inline operator const char*() const {return m_buffer;}
+ private:
+ pfc::string8_fastalloc m_buffer;
+ };
+}
+
+static bool is_meta_same_everywhere(const cue_creator::t_entry_list & p_list,const char * p_meta)
+{
+ pfc::string8_fastalloc reference,temp;
+
+ cue_creator::t_entry_list::const_iterator iter;
+ iter = p_list.first();
+ if (!iter.is_valid()) return false;
+ if (!iter->m_infos.meta_format(p_meta,reference)) return false;
+ for(;iter.is_valid();++iter)
+ {
+ if (!iter->m_infos.meta_format(p_meta,temp)) return false;
+ if (strcmp(temp,reference)!=0) return false;
+ }
+ return true;
+}
+
+static const char g_eol[] = "\r\n";
+
+
+namespace cue_creator
+{
+ void create(pfc::string_formatter & p_out,const t_entry_list & p_data)
+ {
+ if (p_data.get_count() == 0) return;
+ bool album_artist_global = is_meta_same_everywhere(p_data,"album artist"),
+ artist_global = is_meta_same_everywhere(p_data,"artist"),
+ album_global = is_meta_same_everywhere(p_data,"album"),
+ genre_global = is_meta_same_everywhere(p_data,"genre"),
+ date_global = is_meta_same_everywhere(p_data,"date"),
+ discid_global = is_meta_same_everywhere(p_data,"discid"),
+ comment_global = is_meta_same_everywhere(p_data,"comment"),
+ catalog_global = is_meta_same_everywhere(p_data,"catalog"),
+ songwriter_global = is_meta_same_everywhere(p_data,"songwriter");
+
+ if (genre_global) {
+ p_out << "REM GENRE " << format_meta(p_data.first()->m_infos,"genre") << g_eol;
+ }
+ if (date_global) {
+ p_out << "REM DATE " << format_meta(p_data.first()->m_infos,"date") << g_eol;
+ }
+ if (discid_global) {
+ p_out << "REM DISCID " << format_meta(p_data.first()->m_infos,"discid") << g_eol;
+ }
+ if (comment_global) {
+ p_out << "REM COMMENT " << format_meta(p_data.first()->m_infos,"comment") << g_eol;
+ }
+ if (catalog_global) {
+ p_out << "CATALOG " << format_meta(p_data.first()->m_infos,"catalog") << g_eol;
+ }
+ if (songwriter_global) {
+ p_out << "SONGWRITER \"" << format_meta(p_data.first()->m_infos,"songwriter") << "\"" << g_eol;
+ }
+
+ if (album_artist_global)
+ {
+ p_out << "PERFORMER \"" << format_meta(p_data.first()->m_infos,"album artist") << "\"" << g_eol;
+ artist_global = false;
+ }
+ else if (artist_global)
+ {
+ p_out << "PERFORMER \"" << format_meta(p_data.first()->m_infos,"artist") << "\"" << g_eol;
+ }
+ if (album_global)
+ {
+ p_out << "TITLE \"" << format_meta(p_data.first()->m_infos,"album") << "\"" << g_eol;
+ }
+
+ {
+ replaygain_info::t_text_buffer rgbuffer;
+ replaygain_info rg = p_data.first()->m_infos.get_replaygain();
+ if (rg.format_album_gain(rgbuffer))
+ p_out << "REM REPLAYGAIN_ALBUM_GAIN " << rgbuffer << g_eol;
+ if (rg.format_album_peak(rgbuffer))
+ p_out << "REM REPLAYGAIN_ALBUM_PEAK " << rgbuffer << g_eol;
+ }
+
+ pfc::string8 last_file;
+
+ for(t_entry_list::const_iterator iter = p_data.first();iter.is_valid();++iter)
+ {
+ if (strcmp(last_file,iter->m_file) != 0)
+ {
+ p_out << "FILE \"" << iter->m_file << "\" WAVE" << g_eol;
+ last_file = iter->m_file;
+ }
+
+ p_out << " TRACK " << pfc::format_int(iter->m_track_number,2) << " AUDIO" << g_eol;
+
+ if (iter->m_infos.meta_find("title") != infinite)
+ p_out << " TITLE \"" << format_meta(iter->m_infos,"title") << "\"" << g_eol;
+
+ if (!artist_global && iter->m_infos.meta_find("artist") != infinite)
+ p_out << " PERFORMER \"" << format_meta(iter->m_infos,"artist") << "\"" << g_eol;
+
+ if (!songwriter_global && iter->m_infos.meta_find("songwriter") != infinite) {
+ p_out << " SONGWRITER \"" << format_meta(iter->m_infos,"songwriter") << "\"" << g_eol;
+ }
+
+ if (iter->m_infos.meta_find("isrc") != infinite) {
+ p_out << " ISRC " << format_meta(iter->m_infos,"isrc") << g_eol;
+ }
+
+ if (!date_global && iter->m_infos.meta_find("date") != infinite) {
+ p_out << " REM DATE " << format_meta(iter->m_infos,"date") << g_eol;
+ }
+
+
+
+ {
+ replaygain_info::t_text_buffer rgbuffer;
+ replaygain_info rg = iter->m_infos.get_replaygain();
+ if (rg.format_track_gain(rgbuffer))
+ p_out << " REM REPLAYGAIN_TRACK_GAIN " << rgbuffer << g_eol;
+ if (rg.format_track_peak(rgbuffer))
+ p_out << " REM REPLAYGAIN_TRACK_PEAK " << rgbuffer << g_eol;
+ }
+
+ if (!iter->m_flags.is_empty()) {
+ p_out << " FLAGS " << iter->m_flags << g_eol;
+ }
+
+ if (iter->m_index_list.m_positions[0] < iter->m_index_list.m_positions[1])
+ {
+ if (iter->m_index_list.m_positions[0] < 0)
+ p_out << " PREGAP " << cuesheet_format_index_time(iter->m_index_list.m_positions[1] - iter->m_index_list.m_positions[0]) << g_eol;
+ else
+ p_out << " INDEX 00 " << cuesheet_format_index_time(iter->m_index_list.m_positions[0]) << g_eol;
+ }
+
+ p_out << " INDEX 01 " << cuesheet_format_index_time(iter->m_index_list.m_positions[1]) << g_eol;
+
+ for(unsigned n=2;n<t_cuesheet_index_list::count && iter->m_index_list.m_positions[n] > 0;n++)
+ {
+ p_out << " INDEX " << pfc::format_uint(n,2) << " " << cuesheet_format_index_time(iter->m_index_list.m_positions[n]) << g_eol;
+ }
+
+ // p_out << " INDEX 01 " << cuesheet_format_index_time(iter->m_offset) << g_eol;
+ }
+ }
+
+
+ void t_entry::set_simple_index(double p_time)
+ {
+ m_index_list.reset();
+ m_index_list.m_positions[0] = m_index_list.m_positions[1] = p_time;
+ }
+
+}
+
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_creator.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_creator.h
new file mode 100644
index 0000000..e05f415
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_creator.h
@@ -0,0 +1,17 @@
+namespace cue_creator
+{
+ struct t_entry
+ {
+ file_info_impl m_infos;
+ pfc::string8 m_file,m_flags;
+ unsigned m_track_number;
+
+ t_cuesheet_index_list m_index_list;
+
+ void set_simple_index(double p_time);
+ };
+
+ typedef pfc::chain_list_t<t_entry> t_entry_list;
+
+ void create(pfc::string_formatter & p_out,const pfc::chain_list_t<t_entry> & p_list);
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_parser.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_parser.cpp
new file mode 100644
index 0000000..128df91
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_parser.cpp
@@ -0,0 +1,764 @@
+#include "stdafx.h"
+
+namespace {
+ PFC_DECLARE_EXCEPTION(exception_cue,pfc::exception,"Invalid cuesheet");
+}
+
+static bool is_numeric(char c) {return c>='0' && c<='9';}
+
+
+static bool is_spacing(char c)
+{
+ return c == ' ' || c == '\t';
+}
+
+static bool is_linebreak(char c)
+{
+ return c == '\n' || c == '\r';
+}
+
+static void validate_file_type(const char * p_type,t_size p_type_length) {
+ if (
+ //standard types
+ stricmp_utf8_ex(p_type,p_type_length,"WAVE",infinite) != 0 &&
+ stricmp_utf8_ex(p_type,p_type_length,"MP3",infinite) != 0 &&
+ stricmp_utf8_ex(p_type,p_type_length,"AIFF",infinite) != 0 &&
+ //common user-entered types
+ stricmp_utf8_ex(p_type,p_type_length,"APE",infinite) != 0 &&
+ stricmp_utf8_ex(p_type,p_type_length,"FLAC",infinite) != 0 &&
+ stricmp_utf8_ex(p_type,p_type_length,"WV",infinite) != 0 &&
+ stricmp_utf8_ex(p_type,p_type_length,"WAVPACK",infinite) != 0
+ )
+ throw exception_cue(pfc::string_formatter() << "expected WAVE, MP3 or AIFF, got : \"" << pfc::string8(p_type,p_type_length) << "\"");
+}
+
+namespace {
+
+ class NOVTABLE cue_parser_callback
+ {
+ public:
+ virtual void on_file(const char * p_file,t_size p_file_length,const char * p_type,t_size p_type_length) = 0;
+ virtual void on_track(unsigned p_index,const char * p_type,t_size p_type_length) = 0;
+ virtual void on_pregap(unsigned p_value) = 0;
+ virtual void on_index(unsigned p_index,unsigned p_value) = 0;
+ virtual void on_title(const char * p_title,t_size p_title_length) = 0;
+ virtual void on_performer(const char * p_performer,t_size p_performer_length) = 0;
+ virtual void on_songwriter(const char * p_songwriter,t_size p_songwriter_length) = 0;
+ virtual void on_isrc(const char * p_isrc,t_size p_isrc_length) = 0;
+ virtual void on_catalog(const char * p_catalog,t_size p_catalog_length) = 0;
+ virtual void on_comment(const char * p_comment,t_size p_comment_length) = 0;
+ virtual void on_flags(const char * p_flags,t_size p_flags_length) = 0;
+ };
+
+ class NOVTABLE cue_parser_callback_meta : public cue_parser_callback
+ {
+ public:
+ virtual void on_file(const char * p_file,t_size p_file_length,const char * p_type,t_size p_type_length) = 0;
+ virtual void on_track(unsigned p_index,const char * p_type,t_size p_type_length) = 0;
+ virtual void on_pregap(unsigned p_value) = 0;
+ virtual void on_index(unsigned p_index,unsigned p_value) = 0;
+ virtual void on_meta(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length) = 0;
+ protected:
+ static bool is_known_meta(const char * p_name,t_size p_length)
+ {
+ static const char * metas[] = {"genre","date","discid","comment","replaygain_track_gain","replaygain_track_peak","replaygain_album_gain","replaygain_album_peak"};
+ for(t_size n=0;n<tabsize(metas);n++) {
+ if (!stricmp_utf8_ex(p_name,p_length,metas[n],infinite)) return true;
+ }
+ return false;
+ }
+
+ void on_comment(const char * p_comment,t_size p_comment_length)
+ {
+ unsigned ptr = 0;
+ while(ptr < p_comment_length && !is_spacing(p_comment[ptr])) ptr++;
+ if (is_known_meta(p_comment, ptr))
+ {
+ unsigned name_length = ptr;
+ while(ptr < p_comment_length && is_spacing(p_comment[ptr])) ptr++;
+ if (ptr < p_comment_length)
+ {
+ if (p_comment[ptr] == '\"')
+ {
+ ptr++;
+ unsigned value_base = ptr;
+ while(ptr < p_comment_length && p_comment[ptr] != '\"') ptr++;
+ if (ptr == p_comment_length) throw exception_cue("invalid REM syntax",0);
+ if (ptr > value_base) on_meta(p_comment,name_length,p_comment + value_base,ptr - value_base);
+ }
+ else
+ {
+ unsigned value_base = ptr;
+ while(ptr < p_comment_length /*&& !is_spacing(p_comment[ptr])*/) ptr++;
+ if (ptr > value_base) on_meta(p_comment,name_length,p_comment + value_base,ptr - value_base);
+ }
+ }
+ }
+ }
+ void on_title(const char * p_title,t_size p_title_length)
+ {
+ on_meta("title",infinite,p_title,p_title_length);
+ }
+ void on_songwriter(const char * p_songwriter,t_size p_songwriter_length) {
+ on_meta("songwriter",infinite,p_songwriter,p_songwriter_length);
+ }
+ void on_performer(const char * p_performer,t_size p_performer_length)
+ {
+ on_meta("artist",infinite,p_performer,p_performer_length);
+ }
+
+ void on_isrc(const char * p_isrc,t_size p_isrc_length)
+ {
+ on_meta("isrc",infinite,p_isrc,p_isrc_length);
+ }
+ void on_catalog(const char * p_catalog,t_size p_catalog_length)
+ {
+ on_meta("catalog",infinite,p_catalog,p_catalog_length);
+ }
+ void on_flags(const char * p_flags,t_size p_flags_length) {}
+ };
+
+
+ class cue_parser_callback_retrievelist : public cue_parser_callback
+ {
+ public:
+ cue_parser_callback_retrievelist(pfc::chain_list_t<cue_parser::cue_entry> & p_out) : m_out(p_out), m_track(0), m_pregap(0), m_index0_set(false), m_index1_set(false)
+ {
+ }
+
+ void on_file(const char * p_file,t_size p_file_length,const char * p_type,t_size p_type_length)
+ {
+ validate_file_type(p_type,p_type_length);
+ m_file.set_string(p_file,p_file_length);
+ }
+
+ void on_track(unsigned p_index,const char * p_type,t_size p_type_length)
+ {
+ if (stricmp_utf8_ex(p_type,p_type_length,"audio",infinite)) throw exception_cue("only tracks of type AUDIO supported",0);
+ //if (p_index != m_track + 1) throw exception_cue("cuesheet tracks out of order");
+ if (m_track != 0) finalize_track();
+ if (m_file.is_empty()) throw exception_cue("declaring a track with no file set",0);
+ m_trackfile = m_file;
+ m_track = p_index;
+ }
+
+ void on_pregap(unsigned p_value) {m_pregap = (double) p_value / 75.0;}
+
+ void on_index(unsigned p_index,unsigned p_value)
+ {
+ if (p_index < t_cuesheet_index_list::count)
+ {
+ switch(p_index)
+ {
+ case 0: m_index0_set = true; break;
+ case 1: m_index1_set = true; break;
+ }
+ m_index_list.m_positions[p_index] = (double) p_value / 75.0;
+ }
+ }
+
+ void on_title(const char * p_title,t_size p_title_length) {}
+ void on_performer(const char * p_performer,t_size p_performer_length) {}
+ void on_songwriter(const char * p_songwriter,t_size p_songwriter_length) {}
+ void on_isrc(const char * p_isrc,t_size p_isrc_length) {}
+ void on_catalog(const char * p_catalog,t_size p_catalog_length) {}
+ void on_comment(const char * p_comment,t_size p_comment_length) {}
+ void on_flags(const char * p_flags,t_size p_flags_length) {}
+
+ void finalize()
+ {
+ if (m_track != 0)
+ {
+ finalize_track();
+ m_track = 0;
+ }
+ }
+
+ private:
+ void finalize_track()
+ {
+ if (!m_index1_set) throw exception_cue("INDEX 01 not set",0);
+ if (!m_index0_set) m_index_list.m_positions[0] = m_index_list.m_positions[1] - m_pregap;
+ if (!m_index_list.is_valid()) throw exception_cue("invalid index list");
+
+ pfc::chain_list_t<cue_parser::cue_entry>::iterator iter;
+ iter = m_out.insert_last();
+ if (m_trackfile.is_empty()) throw exception_cue("track has no file assigned",0);
+ iter->m_file = m_trackfile;
+ iter->m_track_number = m_track;
+ iter->m_indexes = m_index_list;
+
+ m_index_list.reset();
+ m_index0_set = false;
+ m_index1_set = false;
+ m_pregap = 0;
+ }
+
+ bool m_index0_set,m_index1_set;
+ t_cuesheet_index_list m_index_list;
+ double m_pregap;
+ unsigned m_track;
+ pfc::string8 m_file,m_trackfile;
+ pfc::chain_list_t<cue_parser::cue_entry> & m_out;
+ };
+
+ class cue_parser_callback_retrieveinfo : public cue_parser_callback_meta
+ {
+ public:
+ cue_parser_callback_retrieveinfo(file_info & p_out,unsigned p_wanted_track) : m_out(p_out), m_wanted_track(p_wanted_track), m_track(0), m_is_va(false), m_index0_set(false), m_index1_set(false), m_pregap(0), m_totaltracks(0) {}
+
+ void on_file(const char * p_file,t_size p_file_length,const char * p_type,t_size p_type_length) {}
+
+ void on_track(unsigned p_index,const char * p_type,t_size p_type_length)
+ {
+ if (p_index == 0) throw exception_cue("invalid TRACK index",0);
+ if (p_index == m_wanted_track)
+ {
+ if (stricmp_utf8_ex(p_type,p_type_length,"audio",infinite)) throw exception_cue("only tracks of type AUDIO supported",0);
+ }
+ m_track = p_index;
+ m_totaltracks++;
+ }
+
+ void on_pregap(unsigned p_value) {if (m_track == m_wanted_track) m_pregap = (double) p_value / 75.0;}
+
+ void on_index(unsigned p_index,unsigned p_value)
+ {
+ if (m_track == m_wanted_track && p_index < t_cuesheet_index_list::count)
+ {
+ switch(p_index)
+ {
+ case 0: m_index0_set = true; break;
+ case 1: m_index1_set = true; break;
+ }
+ m_indexes.m_positions[p_index] = (double) p_value / 75.0;
+ }
+ }
+
+
+ void on_meta(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length)
+ {
+ t_meta_list::iterator iter;
+ if (m_track == 0) //globals
+ {
+ //convert global title to album
+ if (!stricmp_utf8_ex(p_name,p_name_length,"title",infinite))
+ {
+ p_name = "album";
+ p_name_length = 5;
+ }
+ else if (!stricmp_utf8_ex(p_name,p_name_length,"artist",infinite))
+ {
+ m_album_artist.set_string(p_value,p_value_length);
+ }
+
+ iter = m_globals.insert_last();
+ }
+ else
+ {
+ if (!m_is_va)
+ {
+ if (!stricmp_utf8_ex(p_name,p_name_length,"artist",infinite))
+ {
+ if (!m_album_artist.is_empty())
+ {
+ if (stricmp_utf8_ex(p_value,p_value_length,m_album_artist,m_album_artist.length())) m_is_va = true;
+ }
+ }
+ }
+
+ if (m_track == m_wanted_track) //locals
+ {
+ iter = m_locals.insert_last();
+ }
+ }
+ if (iter.is_valid())
+ {
+ iter->m_name.set_string(p_name,p_name_length);
+ iter->m_value.set_string(p_value,p_value_length);
+ }
+ }
+
+ void finalize()
+ {
+ if (!m_index1_set) throw exception_cue("INDEX 01 not set",0);
+ if (!m_index0_set) m_indexes.m_positions[0] = m_indexes.m_positions[1] - m_pregap;
+ m_indexes.to_infos(m_out);
+
+ replaygain_info rg;
+ rg.reset();
+ t_meta_list::const_iterator iter;
+
+ if (m_is_va)
+ {
+ //clean up VA mess
+
+ t_meta_list::const_iterator iter_global,iter_local;
+
+ iter_global = find_first_field(m_globals,"artist");
+ iter_local = find_first_field(m_locals,"artist");
+ if (iter_global.is_valid())
+ {
+ m_out.meta_set("album artist",iter_global->m_value);
+ if (iter_local.is_valid()) m_out.meta_set("artist",iter_local->m_value);
+ else m_out.meta_set("artist",iter_global->m_value);
+ }
+ else
+ {
+ if (iter_local.is_valid()) m_out.meta_set("artist",iter_local->m_value);
+ }
+
+
+ wipe_field(m_globals,"artist");
+ wipe_field(m_locals,"artist");
+
+ }
+
+ for(iter=m_globals.first();iter.is_valid();iter++)
+ {
+ if (!rg.set_from_meta(iter->m_name,iter->m_value))
+ m_out.meta_set(iter->m_name,iter->m_value);
+ }
+ for(iter=m_locals.first();iter.is_valid();iter++)
+ {
+ if (!rg.set_from_meta(iter->m_name,iter->m_value))
+ m_out.meta_set(iter->m_name,iter->m_value);
+ }
+ m_out.meta_set("tracknumber",pfc::string_formatter() << m_wanted_track);
+ m_out.meta_set("totaltracks", pfc::string_formatter() << m_totaltracks);
+ m_out.set_replaygain(rg);
+
+ }
+ private:
+ struct t_meta_entry {
+ pfc::string8 m_name,m_value;
+ };
+ typedef pfc::chain_list_t<t_meta_entry> t_meta_list;
+
+ static t_meta_list::const_iterator find_first_field(t_meta_list const & p_list,const char * p_field)
+ {
+ t_meta_list::const_iterator iter;
+ for(iter=p_list.first();iter.is_valid();++iter)
+ {
+ if (!stricmp_utf8(p_field,iter->m_name)) return iter;
+ }
+ return t_meta_list::const_iterator();//null iterator
+ }
+
+ static void wipe_field(t_meta_list & p_list,const char * p_field)
+ {
+ t_meta_list::iterator iter;
+ for(iter=p_list.first();iter.is_valid();)
+ {
+ if (!stricmp_utf8(p_field,iter->m_name))
+ {
+ t_meta_list::iterator temp = iter;
+ ++temp;
+ p_list.remove_single(iter);
+ iter = temp;
+ }
+ else
+ {
+ ++iter;
+ }
+ }
+ }
+
+ t_meta_list m_globals,m_locals;
+ file_info & m_out;
+ unsigned m_wanted_track, m_track,m_totaltracks;
+ pfc::string8 m_album_artist;
+ bool m_is_va;
+ t_cuesheet_index_list m_indexes;
+ bool m_index0_set,m_index1_set;
+ double m_pregap;
+ };
+
+};
+
+
+static void g_parse_cue_line(const char * p_line,t_size p_line_length,cue_parser_callback & p_callback)
+{
+ t_size ptr = 0;
+ while(ptr < p_line_length && !is_spacing(p_line[ptr])) ptr++;
+ if (!stricmp_utf8_ex(p_line,ptr,"file",infinite))
+ {
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ t_size file_base,file_length, type_base,type_length;
+
+ if (p_line[ptr] == '\"')
+ {
+ ptr++;
+ file_base = ptr;
+ while(ptr < p_line_length && p_line[ptr] != '\"') ptr++;
+ if (ptr == p_line_length) throw exception_cue("invalid FILE syntax",0);
+ file_length = ptr - file_base;
+ ptr++;
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ }
+ else
+ {
+ file_base = ptr;
+ while(ptr < p_line_length && !is_spacing(p_line[ptr])) ptr++;
+ file_length = ptr - file_base;
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ }
+
+ type_base = ptr;
+ while(ptr < p_line_length && !is_spacing(p_line[ptr])) ptr++;
+ type_length = ptr - type_base;
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+
+ if (ptr != p_line_length || file_length == 0 || type_length == 0) throw exception_cue("invalid FILE syntax",0);
+
+ p_callback.on_file(p_line + file_base, file_length, p_line + type_base, type_length);
+ }
+ else if (!stricmp_utf8_ex(p_line,ptr,"track",infinite))
+ {
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+
+ t_size track_base = ptr, track_length;
+ while(ptr < p_line_length && !is_spacing(p_line[ptr]))
+ {
+ if (!is_numeric(p_line[ptr])) throw exception_cue("invalid TRACK syntax",0);
+ ptr++;
+ }
+ track_length = ptr - track_base;
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+
+ t_size type_base = ptr, type_length;
+ while(ptr < p_line_length && !is_spacing(p_line[ptr])) ptr++;
+ type_length = ptr - type_base;
+
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ if (ptr != p_line_length || type_length == 0) throw exception_cue("invalid TRACK syntax",0);
+ unsigned track = pfc::atoui_ex(p_line+track_base,track_length);
+ if (track < 1 || track > 99) throw exception_cue("invalid track number",0);
+
+ p_callback.on_track(track,p_line + type_base, type_length);
+ }
+ else if (!stricmp_utf8_ex(p_line,ptr,"index",infinite))
+ {
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+
+ t_size index_base,index_length, time_base,time_length;
+ index_base = ptr;
+ while(ptr < p_line_length && !is_spacing(p_line[ptr]))
+ {
+ if (!is_numeric(p_line[ptr])) throw exception_cue("invalid INDEX syntax",0);
+ ptr++;
+ }
+ index_length = ptr - index_base;
+
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ time_base = ptr;
+ while(ptr < p_line_length && !is_spacing(p_line[ptr]))
+ {
+ if (!is_numeric(p_line[ptr]) && p_line[ptr] != ':')
+ throw exception_cue("invalid INDEX syntax",0);
+ ptr++;
+ }
+ time_length = ptr - time_base;
+
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+
+ if (ptr != p_line_length || index_length == 0 || time_length == 0)
+ throw exception_cue("invalid INDEX syntax",0);
+
+ unsigned index = pfc::atoui_ex(p_line+index_base,index_length);
+ if (index > 99) throw exception_cue("invalid INDEX syntax",0);
+ unsigned time = cuesheet_parse_index_time_ticks_e(p_line + time_base,time_length);
+
+ p_callback.on_index(index,time);
+ }
+ else if (!stricmp_utf8_ex(p_line,ptr,"pregap",infinite))
+ {
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+
+ t_size time_base, time_length;
+ time_base = ptr;
+ while(ptr < p_line_length && !is_spacing(p_line[ptr]))
+ {
+ if (!is_numeric(p_line[ptr]) && p_line[ptr] != ':')
+ throw exception_cue("invalid PREGAP syntax",0);
+ ptr++;
+ }
+ time_length = ptr - time_base;
+
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+
+ if (ptr != p_line_length || time_length == 0)
+ throw exception_cue("invalid PREGAP syntax",0);
+
+ unsigned time = cuesheet_parse_index_time_ticks_e(p_line + time_base,time_length);
+
+ p_callback.on_pregap(time);
+ }
+ else if (!stricmp_utf8_ex(p_line,ptr,"title",infinite))
+ {
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ if (ptr == p_line_length) throw exception_cue("invalid TITLE syntax",0);
+ if (p_line[ptr] == '\"')
+ {
+ ptr++;
+ t_size base = ptr;
+ while(ptr < p_line_length && p_line[ptr] != '\"') ptr++;
+ if (ptr == p_line_length) throw exception_cue("invalid TITLE syntax",0);
+ t_size length = ptr-base;
+ ptr++;
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ if (ptr != p_line_length) throw exception_cue("invalid TITLE syntax",0);
+ p_callback.on_title(p_line+base,length);
+ }
+ else
+ {
+ p_callback.on_title(p_line+ptr,p_line_length-ptr);
+ }
+ }
+ else if (!stricmp_utf8_ex(p_line,ptr,"performer",infinite))
+ {
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ if (ptr == p_line_length) throw exception_cue("invalid PERFORMER syntax",0);
+ if (p_line[ptr] == '\"')
+ {
+ ptr++;
+ t_size base = ptr;
+ while(ptr < p_line_length && p_line[ptr] != '\"') ptr++;
+ if (ptr == p_line_length) throw exception_cue("invalid PERFORMER syntax",0);
+ t_size length = ptr-base;
+ ptr++;
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ if (ptr != p_line_length) throw exception_cue("invalid PERFORMER syntax",0);
+ p_callback.on_performer(p_line+base,length);
+ }
+ else
+ {
+ p_callback.on_performer(p_line+ptr,p_line_length-ptr);
+ }
+ }
+ else if (!stricmp_utf8_ex(p_line,ptr,"songwriter",infinite))
+ {
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ if (ptr == p_line_length) throw exception_cue("invalid SONGWRITER syntax",0);
+ if (p_line[ptr] == '\"')
+ {
+ ptr++;
+ t_size base = ptr;
+ while(ptr < p_line_length && p_line[ptr] != '\"') ptr++;
+ if (ptr == p_line_length) throw exception_cue("invalid SONGWRITER syntax",0);
+ t_size length = ptr-base;
+ ptr++;
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ if (ptr != p_line_length) throw exception_cue("invalid SONGWRITER syntax",0);
+ p_callback.on_songwriter(p_line+base,length);
+ }
+ else
+ {
+ p_callback.on_songwriter(p_line+ptr,p_line_length-ptr);
+ }
+ }
+ else if (!stricmp_utf8_ex(p_line,ptr,"isrc",infinite))
+ {
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ t_size length = p_line_length - ptr;
+ if (length == 0) throw exception_cue("invalid ISRC syntax",0);
+ p_callback.on_isrc(p_line+ptr,length);
+ }
+ else if (!stricmp_utf8_ex(p_line,ptr,"catalog",infinite))
+ {
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ t_size length = p_line_length - ptr;
+ if (length == 0) throw exception_cue("invalid CATALOG syntax",0);
+ p_callback.on_catalog(p_line+ptr,length);
+ }
+ else if (!stricmp_utf8_ex(p_line,ptr,"flags",infinite))
+ {
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ if (ptr < p_line_length)
+ p_callback.on_flags(p_line + ptr, p_line_length - ptr);
+ }
+ else if (!stricmp_utf8_ex(p_line,ptr,"rem",infinite))
+ {
+ while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
+ if (ptr < p_line_length)
+ p_callback.on_comment(p_line + ptr, p_line_length - ptr);
+ }
+ else if (!stricmp_utf8_ex(p_line,ptr,"postgap",infinite)) {
+ throw exception_cue("POSTGAP is not supported",0);
+ } else if (!stricmp_utf8_ex(p_line,ptr,"cdtextfile",infinite)) {
+ //do nothing
+ }
+ else throw exception_cue("unknown cuesheet item",0);
+}
+
+static void g_parse_cue(const char * p_cuesheet,cue_parser_callback & p_callback)
+{
+ const char * parseptr = p_cuesheet;
+ t_size lineidx = 1;
+ while(*parseptr)
+ {
+ while(is_spacing(*parseptr)) *parseptr++;
+ if (*parseptr)
+ {
+ t_size length = 0;
+ while(parseptr[length] && !is_linebreak(parseptr[length])) length++;
+ if (length > 0) {
+ try {
+ g_parse_cue_line(parseptr,length,p_callback);
+ } catch(exception_cue const & e) {//rethrow with line info
+ throw exception_cue(pfc::string_formatter() << e.what() << " (line " << lineidx << ")");
+ }
+ }
+ parseptr += length;
+ while(is_linebreak(*parseptr)) {
+ if (*parseptr == '\n') lineidx++;
+ parseptr++;
+ }
+ }
+ }
+}
+
+void cue_parser::parse(const char *p_cuesheet,pfc::chain_list_t<cue_entry> & p_out) {
+ try {
+ cue_parser_callback_retrievelist callback(p_out);
+ g_parse_cue(p_cuesheet,callback);
+ callback.finalize();
+ } catch(exception_cue const & e) {
+ throw exception_bad_cuesheet(pfc::string_formatter() << "Error parsing cuesheet: " << e.what());
+ }
+}
+void cue_parser::parse_info(const char * p_cuesheet,file_info & p_info,unsigned p_index) {
+ try {
+ cue_parser_callback_retrieveinfo callback(p_info,p_index);
+ g_parse_cue(p_cuesheet,callback);
+ callback.finalize();
+ } catch(exception_cue const & e) {
+ throw exception_bad_cuesheet(pfc::string_formatter() << "Error parsing cuesheet: " << e.what());
+ }
+}
+
+namespace {
+
+ class cue_parser_callback_retrievecount : public cue_parser_callback
+ {
+ public:
+ cue_parser_callback_retrievecount() : m_count(0) {}
+ unsigned get_count() const {return m_count;}
+ void on_file(const char * p_file,t_size p_file_length,const char * p_type,t_size p_type_length) {}
+ void on_track(unsigned p_index,const char * p_type,t_size p_type_length) {m_count++;}
+ void on_pregap(unsigned p_value) {}
+ void on_index(unsigned p_index,unsigned p_value) {}
+ void on_title(const char * p_title,t_size p_title_length) {}
+ void on_performer(const char * p_performer,t_size p_performer_length) {}
+ void on_isrc(const char * p_isrc,t_size p_isrc_length) {}
+ void on_catalog(const char * p_catalog,t_size p_catalog_length) {}
+ void on_comment(const char * p_comment,t_size p_comment_length) {}
+ void on_flags(const char * p_flags,t_size p_flags_length) {}
+ private:
+ unsigned m_count;
+ };
+
+ class cue_parser_callback_retrievecreatorentries : public cue_parser_callback
+ {
+ public:
+ cue_parser_callback_retrievecreatorentries(cue_creator::t_entry_list & p_out) : m_out(p_out), m_track(0), m_pregap(0), m_index0_set(false), m_index1_set(false) {}
+
+ void on_file(const char * p_file,t_size p_file_length,const char * p_type,t_size p_type_length) {
+ validate_file_type(p_type,p_type_length);
+ m_file.set_string(p_file,p_file_length);
+ }
+
+ void on_track(unsigned p_index,const char * p_type,t_size p_type_length)
+ {
+ if (stricmp_utf8_ex(p_type,p_type_length,"audio",infinite)) throw exception_cue("only tracks of type AUDIO supported",0);
+ //if (p_index != m_track + 1) throw exception_cue("cuesheet tracks out of order",0);
+ if (m_track != 0) finalize_track();
+ if (m_file.is_empty()) throw exception_cue("declaring a track with no file set",0);
+ m_trackfile = m_file;
+ m_track = p_index;
+ }
+
+ void on_pregap(unsigned p_value)
+ {
+ m_pregap = (double) p_value / 75.0;
+ }
+
+ void on_index(unsigned p_index,unsigned p_value)
+ {
+ if (p_index < t_cuesheet_index_list::count)
+ {
+ switch(p_index)
+ {
+ case 0: m_index0_set = true; break;
+ case 1: m_index1_set = true; break;
+ }
+ m_indexes.m_positions[p_index] = (double) p_value / 75.0;
+ }
+ }
+ void on_title(const char * p_title,t_size p_title_length) {}
+ void on_performer(const char * p_performer,t_size p_performer_length) {}
+ void on_songwriter(const char * p_performer,t_size p_performer_length) {}
+ void on_isrc(const char * p_isrc,t_size p_isrc_length) {}
+ void on_catalog(const char * p_catalog,t_size p_catalog_length) {}
+ void on_comment(const char * p_comment,t_size p_comment_length) {}
+ void finalize()
+ {
+ if (m_track != 0)
+ {
+ finalize_track();
+ m_track = 0;
+ }
+ }
+ void on_flags(const char * p_flags,t_size p_flags_length) {
+ m_flags.set_string(p_flags,p_flags_length);
+ }
+ private:
+ void finalize_track()
+ {
+ if (m_track < 1 || m_track > 99) throw exception_cue("track number out of range",0);
+ if (!m_index1_set) throw exception_cue("INDEX 01 not set",0);
+ if (!m_index0_set) m_indexes.m_positions[0] = m_indexes.m_positions[1] - m_pregap;
+ if (!m_indexes.is_valid()) throw exception_cue("invalid index list");
+
+ cue_creator::t_entry_list::iterator iter;
+ iter = m_out.insert_last();
+ iter->m_track_number = m_track;
+ iter->m_file = m_trackfile;
+ iter->m_index_list = m_indexes;
+ iter->m_flags = m_flags;
+ m_pregap = 0;
+ m_indexes.reset();
+ m_index0_set = m_index1_set = false;
+ m_flags.reset();
+ }
+
+ bool m_index0_set,m_index1_set;
+ double m_pregap;
+ unsigned m_track;
+ cue_creator::t_entry_list & m_out;
+ pfc::string8 m_file,m_trackfile,m_flags;
+ t_cuesheet_index_list m_indexes;
+ };
+}
+
+void cue_parser::parse_full(const char * p_cuesheet,cue_creator::t_entry_list & p_out) {
+ try {
+ {
+ cue_parser_callback_retrievecreatorentries callback(p_out);
+ g_parse_cue(p_cuesheet,callback);
+ callback.finalize();
+ }
+
+ {
+ cue_creator::t_entry_list::iterator iter;
+ for(iter=p_out.first();iter.is_valid();++iter)
+ {
+ cue_parser_callback_retrieveinfo callback(iter->m_infos,iter->m_track_number);
+ g_parse_cue(p_cuesheet,callback);
+ callback.finalize();
+ }
+ }
+ } catch(exception_cue const & e) {
+ throw exception_bad_cuesheet(pfc::string_formatter() << "Error parsing cuesheet: " << e.what());
+ }
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_parser.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_parser.h
new file mode 100644
index 0000000..b8121fe
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_parser.h
@@ -0,0 +1,428 @@
+//HINT: for info on how to generate an embedded cuesheet enabled input, see the end of this header.
+
+//to be moved somewhere else later
+namespace file_info_record_helper {
+
+ class __file_info_record__info__enumerator {
+ public:
+ __file_info_record__info__enumerator(file_info & p_out) : m_out(p_out) {}
+ void operator() (const char * p_name,const char * p_value) {m_out.__info_add_unsafe(p_name,p_value);}
+ private:
+ file_info & m_out;
+ };
+
+ class __file_info_record__meta__enumerator {
+ public:
+ __file_info_record__meta__enumerator(file_info & p_out) : m_out(p_out) {}
+ template<typename t_value> void operator() (const char * p_name,const t_value & p_value) {
+ t_size index = infinite;
+ for(typename t_value::const_iterator iter = p_value.first(); iter.is_valid(); ++iter) {
+ if (index == infinite) index = m_out.__meta_add_unsafe(p_name,*iter);
+ else m_out.meta_add_value(index,*iter);
+ }
+ }
+ private:
+ file_info & m_out;
+ };
+
+ class file_info_record {
+ public:
+ typedef pfc::chain_list_t<pfc::string8> t_meta_value;
+ typedef pfc::map_t<pfc::string8,t_meta_value,file_info::field_name_comparator> t_meta_map;
+ typedef pfc::map_t<pfc::string8,pfc::string8,file_info::field_name_comparator> t_info_map;
+
+ file_info_record() : m_replaygain(replaygain_info_invalid), m_length(0) {}
+
+ replaygain_info get_replaygain() const {return m_replaygain;}
+ void set_replaygain(const replaygain_info & p_replaygain) {m_replaygain = p_replaygain;}
+ double get_length() const {return m_length;}
+ void set_length(double p_length) {m_length = p_length;}
+
+ void reset() {
+ m_meta.remove_all(); m_info.remove_all();
+ m_length = 0;
+ m_replaygain = replaygain_info_invalid;
+ }
+
+ void from_info_overwrite_info(const file_info & p_info) {
+ for(t_size infowalk = 0, infocount = p_info.info_get_count(); infowalk < infocount; ++infowalk) {
+ m_info.set(p_info.info_enum_name(infowalk),p_info.info_enum_value(infowalk));
+ }
+ }
+ void from_info_overwrite_meta(const file_info & p_info) {
+ for(t_size metawalk = 0, metacount = p_info.meta_get_count(); metawalk < metacount; ++metawalk) {
+ const t_size valuecount = p_info.meta_enum_value_count(metawalk);
+ if (valuecount > 0) {
+ t_meta_value & entry = m_meta.find_or_add(p_info.meta_enum_name(metawalk));
+ entry.remove_all();
+ for(t_size valuewalk = 0; valuewalk < valuecount; ++valuewalk) {
+ entry.insert_last(p_info.meta_enum_value(metawalk,valuewalk));
+ }
+ }
+ }
+ }
+
+ void from_info_overwrite_rg(const file_info & p_info) {
+ m_replaygain = replaygain_info::g_merge(m_replaygain,p_info.get_replaygain());
+ }
+
+ template<typename t_source>
+ void overwrite_meta(const t_source & p_meta) {
+ m_meta.overwrite(p_meta);
+ }
+ template<typename t_source>
+ void overwrite_info(const t_source & p_info) {
+ m_info.overwrite(p_info);
+ }
+
+ void merge_overwrite(const file_info & p_info) {
+ from_info_overwrite_info(p_info);
+ from_info_overwrite_meta(p_info);
+ from_info_overwrite_rg(p_info);
+ }
+
+ void transfer_meta_entry(const char * p_name,const file_info & p_info,t_size p_index) {
+ const t_size count = p_info.meta_enum_value_count(p_index);
+ if (count == 0) {
+ m_meta.remove(p_name);
+ } else {
+ t_meta_value & val = m_meta.find_or_add(p_name);
+ val.remove_all();
+ for(t_size walk = 0; walk < count; ++walk) {
+ val.insert_last(p_info.meta_enum_value(p_index,walk));
+ }
+ }
+ }
+
+ void meta_set(const char * p_name,const char * p_value) {
+ m_meta.find_or_add(p_name).set_single(p_value);
+ }
+
+ const t_meta_value * meta_query_ptr(const char * p_name) const {
+ return m_meta.query_ptr(p_name);
+ }
+
+
+ void from_info_set_meta(const file_info & p_info) {
+ m_meta.remove_all();
+ from_info_overwrite_meta(p_info);
+ }
+
+ void from_info(const file_info & p_info) {
+ reset();
+ m_length = p_info.get_length();
+ m_replaygain = p_info.get_replaygain();
+ from_info_overwrite_meta(p_info);
+ from_info_overwrite_info(p_info);
+ }
+ void to_info(file_info & p_info) const {
+ p_info.reset();
+ p_info.set_length(m_length);
+ p_info.set_replaygain(m_replaygain);
+ m_info.enumerate(__file_info_record__info__enumerator(p_info));
+ m_meta.enumerate(__file_info_record__meta__enumerator(p_info));
+ }
+
+ template<typename t_callback> void enumerate_meta(t_callback & p_callback) const {m_meta.enumerate(p_callback);}
+ template<typename t_callback> void enumerate_meta(t_callback & p_callback) {m_meta.enumerate(p_callback);}
+
+ //private:
+ t_meta_map m_meta;
+ t_info_map m_info;
+ replaygain_info m_replaygain;
+ double m_length;
+ };
+
+}//namespace file_info_record_helper
+
+
+namespace cue_parser
+{
+ struct cue_entry {
+ pfc::string8 m_file;
+ unsigned m_track_number;
+ t_cuesheet_index_list m_indexes;
+ };
+
+
+ PFC_DECLARE_EXCEPTION(exception_bad_cuesheet,exception_io_data,"Invalid cuesheet");
+
+ //! Throws exception_bad_cuesheet on failure.
+ void parse(const char *p_cuesheet,pfc::chain_list_t<cue_entry> & p_out);
+ //! Throws exception_bad_cuesheet on failure.
+ void parse_info(const char *p_cuesheet,file_info & p_info,unsigned p_index);
+ //! Throws exception_bad_cuesheet on failure.
+ void parse_full(const char * p_cuesheet,cue_creator::t_entry_list & p_out);
+
+
+
+ struct track_record {
+ file_info_record_helper::file_info_record m_info;
+ pfc::string8 m_file,m_flags;
+ t_cuesheet_index_list m_index_list;
+ };
+
+ typedef pfc::map_t<unsigned,track_record> track_record_list;
+
+ class embeddedcue_metadata_manager {
+ public:
+ void get_tag(file_info & p_info) const;
+ void set_tag(file_info const & p_info);
+
+ void get_track_info(unsigned p_track,file_info & p_info) const;
+ void set_track_info(unsigned p_track,file_info const & p_info);
+ void query_track_offsets(unsigned p_track,double & p_begin,double & p_length) const;
+ bool have_cuesheet() const;
+ unsigned remap_trackno(unsigned p_index) const;
+ t_size get_cue_track_count() const;
+ private:
+ track_record_list m_content;
+ };
+
+
+
+
+
+
+ class __decoder_wrapper {
+ public:
+ virtual bool run(audio_chunk & p_chunk,abort_callback & p_abort) = 0;
+ virtual void seek(double p_seconds,abort_callback & p_abort) = 0;
+ virtual bool get_dynamic_info(file_info & p_out, double & p_timestamp_delta) = 0;
+ virtual bool get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta) = 0;
+ virtual void on_idle(abort_callback & p_abort) = 0;
+ virtual ~__decoder_wrapper() {}
+ };
+
+ template<typename t_input>
+ class __decoder_wrapper_simple : public __decoder_wrapper {
+ public:
+ void initialize(service_ptr_t<file> p_filehint,const char * p_path,unsigned p_flags,abort_callback & p_abort) {
+ m_input.open(p_filehint,p_path,input_open_decode,p_abort);
+ m_input.decode_initialize(p_flags,p_abort);
+ }
+ bool run(audio_chunk & p_chunk,abort_callback & p_abort) {return m_input.decode_run(p_chunk,p_abort);}
+ void seek(double p_seconds,abort_callback & p_abort) {m_input.decode_seek(p_seconds,p_abort);}
+ bool get_dynamic_info(file_info & p_out, double & p_timestamp_delta) {return m_input.decode_get_dynamic_info(p_out,p_timestamp_delta);}
+ bool get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta) {return m_input.decode_get_dynamic_info_track(p_out,p_timestamp_delta);}
+ void on_idle(abort_callback & p_abort) {m_input.decode_on_idle(p_abort);}
+ private:
+ t_input m_input;
+ };
+
+ class __decoder_wrapper_cue : public __decoder_wrapper {
+ public:
+ void open(service_ptr_t<file> p_filehint,const playable_location & p_location,unsigned p_flags,abort_callback & p_abort,double p_start,double p_length) {
+ m_input.open(p_filehint,p_location,p_flags,p_abort,p_start,p_length);
+ }
+ bool run(audio_chunk & p_chunk,abort_callback & p_abort) {return m_input.run(p_chunk,p_abort);}
+ void seek(double p_seconds,abort_callback & p_abort) {m_input.seek(p_seconds,p_abort);}
+ bool get_dynamic_info(file_info & p_out, double & p_timestamp_delta) {return m_input.get_dynamic_info(p_out,p_timestamp_delta);}
+ bool get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta) {return m_input.get_dynamic_info_track(p_out,p_timestamp_delta);}
+ void on_idle(abort_callback & p_abort) {m_input.on_idle(p_abort);}
+
+ private:
+ input_helper_cue m_input;
+ };
+
+ template<typename t_base>
+ class input_wrapper_cue_t {
+ public:
+ input_wrapper_cue_t() {}
+ ~input_wrapper_cue_t() {}
+
+ void open(service_ptr_t<file> p_filehint,const char * p_path,t_input_open_reason p_reason,abort_callback & p_abort) {
+ m_path = p_path;
+
+ m_file = p_filehint;
+ input_open_file_helper(m_file,p_path,p_reason,p_abort);
+
+ {
+ file_info_impl info;
+ t_base instance;
+ instance.open(m_file,p_path,p_reason,p_abort);
+ instance.get_info(info,p_abort);
+ m_meta.set_tag(info);
+ }
+ }
+
+ t_uint32 get_subsong_count() {
+ return m_meta.have_cuesheet() ? m_meta.get_cue_track_count() : 1;
+ }
+
+ t_uint32 get_subsong(t_uint32 p_index) {
+ return m_meta.have_cuesheet() ? m_meta.remap_trackno(p_index) : 0;
+ }
+
+ void get_info(t_uint32 p_subsong,file_info & p_info,abort_callback & p_abort) {
+ if (p_subsong == 0) {
+ m_meta.get_tag(p_info);
+ } else {
+ m_meta.get_track_info(p_subsong,p_info);
+ }
+ }
+
+ t_filestats get_file_stats(abort_callback & p_abort) {return m_file->get_stats(p_abort);}
+
+ void decode_initialize(t_uint32 p_subsong,unsigned p_flags,abort_callback & p_abort) {
+ m_decoder.release();
+ if (p_subsong == 0) {
+ pfc::rcptr_t<__decoder_wrapper_simple<t_base> > temp;
+ temp.new_t();
+ m_file->reopen(p_abort);
+ temp->initialize(m_file,m_path,p_flags,p_abort);
+ m_decoder = temp;
+ } else {
+ double start,length;
+ m_meta.query_track_offsets(p_subsong,start,length);
+
+ pfc::rcptr_t<__decoder_wrapper_cue> temp;
+ temp.new_t();
+ m_file->reopen(p_abort);
+ temp->open(m_file,make_playable_location(m_path,0),p_flags & ~input_flag_no_seeking,p_abort,start,length);
+ m_decoder = temp;
+ }
+ }
+
+ bool decode_run(audio_chunk & p_chunk,abort_callback & p_abort) {
+ return m_decoder->run(p_chunk,p_abort);
+ }
+
+ void decode_seek(double p_seconds,abort_callback & p_abort) {
+ m_decoder->seek(p_seconds,p_abort);
+ }
+
+ bool decode_can_seek() {return true;}
+
+ bool decode_get_dynamic_info(file_info & p_out, double & p_timestamp_delta) {
+ return m_decoder->get_dynamic_info(p_out,p_timestamp_delta);
+ }
+
+ bool decode_get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta) {
+ return m_decoder->get_dynamic_info_track(p_out,p_timestamp_delta);
+ }
+
+ void decode_on_idle(abort_callback & p_abort) {
+ m_decoder->on_idle(p_abort);
+ }
+
+ void retag_set_info(t_uint32 p_subsong,const file_info & p_info,abort_callback & p_abort) {
+ pfc::dynamic_assert(m_decoder.is_empty());
+ if (p_subsong == 0) {
+ m_meta.set_tag(p_info);
+ } else {
+ m_meta.set_track_info(p_subsong,p_info);
+ }
+ }
+
+ void retag_commit(abort_callback & p_abort) {
+ pfc::dynamic_assert(m_decoder.is_empty());
+
+ file_info_impl info;
+ m_meta.get_tag(info);
+
+ {
+ t_base instance;
+ m_file->reopen(p_abort);
+ instance.open(m_file,m_path,input_open_info_write,p_abort);
+ instance.retag(pfc::safe_cast<const file_info&>(info),p_abort);
+ info.reset();
+ instance.get_info(info,p_abort);
+ m_meta.set_tag(info);
+ }
+ }
+
+ inline static bool g_is_our_content_type(const char * p_content_type) {return t_base::g_is_our_content_type(p_content_type);}
+ inline static bool g_is_our_path(const char * p_path,const char * p_extension) {return t_base::g_is_our_path(p_path,p_extension);}
+
+ private:
+ pfc::rcptr_t<__decoder_wrapper> m_decoder;
+
+ file_info_impl m_info;
+ pfc::string8 m_path;
+ service_ptr_t<file> m_file;
+
+ embeddedcue_metadata_manager m_meta;
+ };
+
+ template<typename I>
+ class chapterizer_impl_t : public chapterizer
+ {
+ public:
+ bool is_our_file(const char * p_path,abort_callback & p_abort)
+ {
+ return I::g_is_our_path(p_path,pfc::string_extension(p_path));
+ }
+
+ void set_chapters(const char * p_path,chapter_list const & p_list,abort_callback & p_abort) {
+
+
+ input_wrapper_cue_t<I> instance;
+ instance.open(0,p_path,input_open_info_write,p_abort);
+
+ //stamp the cuesheet first
+ {
+ file_info_impl info;
+ instance.get_info(0,info,p_abort);
+
+ pfc::string_formatter cuesheet;
+
+ {
+ cue_creator::t_entry_list entries;
+ t_size n, m = p_list.get_chapter_count();
+
+ double offset_acc = 0;
+ for(n=0;n<m;n++)
+ {
+ cue_creator::t_entry_list::iterator entry;
+ entry = entries.insert_last();
+ entry->m_infos = p_list.get_info(n);
+ entry->m_file = "CDImage.wav";
+ entry->m_track_number = (unsigned)(n+1);
+ entry->m_index_list.from_infos(entry->m_infos,offset_acc);
+ offset_acc += entry->m_infos.get_length();
+ }
+ cue_creator::create(cuesheet,entries);
+ }
+
+ info.meta_set("cuesheet",cuesheet);
+
+ instance.retag_set_info(0,info,p_abort);
+ }
+ //stamp per-chapter infos
+ for(t_size walk = 0, total = p_list.get_chapter_count(); walk < total; ++walk) {
+ instance.retag_set_info(walk + 1, p_list.get_info(walk),p_abort);
+ }
+
+ instance.retag_commit(p_abort);
+ }
+
+ void get_chapters(const char * p_path,chapter_list & p_list,abort_callback & p_abort) {
+
+ input_wrapper_cue_t<I> instance;
+
+
+ instance.open(0,p_path,input_open_info_read,p_abort);
+
+ const t_uint32 total = instance.get_subsong_count();
+
+ p_list.set_chapter_count(total);
+ for(t_uint32 walk = 0; walk < total; ++walk) {
+ file_info_impl info;
+ instance.get_info(instance.get_subsong(walk),info,p_abort);
+ p_list.set_info(walk,info);
+ }
+ }
+ };
+
+};
+
+//! Wrapper template for generating embedded cuesheet enabled inputs.
+//! t_input_impl is a singletrack input implementation (see input_singletrack_impl for method declarations).
+//! To declare an embedded cuesheet enabled input, change your input declaration from input_singletrack_factory_t<myinput> to input_cuesheet_factory_t<myinput>.
+template<typename t_input_impl>
+class input_cuesheet_factory_t {
+public:
+ input_factory_t<cue_parser::input_wrapper_cue_t<t_input_impl> > m_input_factory;
+ service_factory_single_t<cue_parser::chapterizer_impl_t<t_input_impl> > m_chapterizer_factory;
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_parser_embedding.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_parser_embedding.cpp
new file mode 100644
index 0000000..6af2eb0
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cue_parser_embedding.cpp
@@ -0,0 +1,358 @@
+#include "stdafx.h"
+
+using namespace cue_parser;
+using namespace file_info_record_helper;
+static void build_cue_meta_name(const char * p_name,unsigned p_tracknumber,pfc::string_base & p_out) {
+ p_out.reset();
+ p_out << "cue_track" << pfc::format_uint(p_tracknumber % 100,2) << "_" << p_name;
+}
+
+static bool is_reserved_meta_entry(const char * p_name) {
+ return file_info::field_name_comparator::compare(p_name,"cuesheet") == 0;
+}
+
+static bool is_global_meta_entry(const char * p_name) {
+ static const char header[] = "cue_track";
+ return pfc::stricmp_ascii_ex(p_name,strlen(header),header,infinite) != 0;
+}
+static bool is_allowed_field(const char * p_name) {
+ return !is_reserved_meta_entry(p_name) && is_global_meta_entry(p_name);
+}
+namespace {
+ class __get_tag_cue_track_list_builder {
+ public:
+ __get_tag_cue_track_list_builder(cue_creator::t_entry_list & p_entries) : m_entries(p_entries) {}
+ void operator() (unsigned p_trackno,const track_record & p_record) {
+ if (p_trackno > 0) {
+ cue_creator::t_entry_list::iterator iter = m_entries.insert_last();
+ iter->m_file = p_record.m_file;
+ iter->m_flags = p_record.m_flags;
+ iter->m_index_list = p_record.m_index_list;
+ iter->m_track_number = p_trackno;
+ p_record.m_info.to_info(iter->m_infos);
+ }
+ }
+ private:
+ cue_creator::t_entry_list & m_entries;
+ };
+
+ typedef pfc::avltree_t<pfc::string8,file_info::field_name_comparator> field_name_list;
+
+ class __get_tag__enum_fields_enumerator {
+ public:
+ __get_tag__enum_fields_enumerator(field_name_list & p_out) : m_out(p_out) {}
+ void operator() (unsigned p_trackno,const track_record & p_record) {
+ if (p_trackno > 0) p_record.m_info.enumerate_meta(*this);
+ }
+ template<typename t_value> void operator() (const char * p_name,const t_value & p_value) {
+ m_out.add(p_name);
+ }
+ private:
+ field_name_list & m_out;
+ };
+
+
+ class __get_tag__is_field_global_check {
+ private:
+ typedef file_info_record::t_meta_value t_value;
+ public:
+ __get_tag__is_field_global_check(const char * p_field) : m_field(p_field), m_value(NULL), m_state(true) {}
+
+ void operator() (unsigned p_trackno,const track_record & p_record) {
+ if (p_trackno > 0 && m_state) {
+ const t_value * val = p_record.m_info.meta_query_ptr(m_field);
+ if (val == NULL) {m_state = false; return;}
+ if (m_value == NULL) {
+ m_value = val;
+ } else {
+ if (pfc::comparator_chainlist<pfc::comparator_strcmp>::compare(*m_value,*val) != 0) {
+ m_state = false; return;
+ }
+ }
+ }
+ }
+ void finalize(file_info_record::t_meta_map & p_globals) {
+ if (m_state && m_value != NULL) {
+ p_globals.set(m_field,*m_value);
+ }
+ }
+ private:
+ const char * const m_field;
+ const t_value * m_value;
+ bool m_state;
+ };
+
+ class __get_tag__filter_globals {
+ public:
+ __get_tag__filter_globals(track_record_list const & p_tracks,file_info_record::t_meta_map & p_globals) : m_tracks(p_tracks), m_globals(p_globals) {}
+
+ void operator() (const char * p_field) {
+ if (is_allowed_field(p_field)) {
+ __get_tag__is_field_global_check wrapper(p_field);
+ m_tracks.enumerate(wrapper);
+ wrapper.finalize(m_globals);
+ }
+ }
+ private:
+ const track_record_list & m_tracks;
+ file_info_record::t_meta_map & m_globals;
+ };
+
+ class __get_tag__local_field_filter {
+ public:
+ __get_tag__local_field_filter(const file_info_record::t_meta_map & p_globals,file_info_record::t_meta_map & p_output) : m_globals(p_globals), m_output(p_output), m_currenttrack(0) {}
+ void operator() (unsigned p_trackno,const track_record & p_track) {
+ if (p_trackno > 0) {
+ m_currenttrack = p_trackno;
+ p_track.m_info.enumerate_meta(*this);
+ }
+ }
+ void operator() (const char * p_name,const file_info_record::t_meta_value & p_value) {
+ PFC_ASSERT(m_currenttrack > 0);
+ if (!m_globals.have_item(p_name)) {
+ build_cue_meta_name(p_name,m_currenttrack,m_buffer);
+ m_output.set(m_buffer,p_value);
+ }
+ }
+ private:
+ unsigned m_currenttrack;
+ pfc::string8_fastalloc m_buffer;
+ const file_info_record::t_meta_map & m_globals;
+ file_info_record::t_meta_map & m_output;
+ };
+};
+
+static void strip_redundant_track_meta(unsigned p_tracknumber,const file_info & p_cueinfo,file_info_record::t_meta_map & p_meta,const char * p_metaname) {
+ t_size metaindex = p_cueinfo.meta_find(p_metaname);
+ if (metaindex == infinite) return;
+ pfc::string_formatter namelocal;
+ build_cue_meta_name(p_metaname,p_tracknumber,namelocal);
+ {
+ const file_info_record::t_meta_value * val = p_meta.query_ptr(namelocal);
+ if (val == NULL) return;
+ file_info_record::t_meta_value::const_iterator iter = val->first();
+ for(t_size valwalk = 0, valcount = p_cueinfo.meta_enum_value_count(metaindex); valwalk < valcount; ++valwalk) {
+ if (iter.is_empty()) return;
+ if (strcmp(*iter,p_cueinfo.meta_enum_value(metaindex,valwalk)) != 0) return;
+ ++iter;
+ }
+ if (!iter.is_empty()) return;
+ }
+ //success
+ p_meta.remove(namelocal);
+}
+
+void embeddedcue_metadata_manager::get_tag(file_info & p_info) const {
+ if (!have_cuesheet()) {
+ m_content.query_ptr((unsigned)0)->m_info.to_info(p_info);
+ p_info.meta_remove_field("cuesheet");
+ } else {
+ cue_creator::t_entry_list entries;
+ m_content.enumerate(__get_tag_cue_track_list_builder(entries));
+ pfc::string_formatter cuesheet;
+ cue_creator::create(cuesheet,entries);
+ entries.remove_all();
+ //parse it back to see what info got stored in the cuesheet and what needs to be stored outside cuesheet in the tags
+ cue_parser::parse_full(cuesheet,entries);
+ file_info_record output;
+
+
+
+
+ {
+ file_info_record::t_meta_map globals;
+ //1. find global infos and forward them
+ {
+ field_name_list fields;
+ m_content.enumerate(__get_tag__enum_fields_enumerator(fields));
+ fields.enumerate(__get_tag__filter_globals(m_content,globals));
+ }
+
+ output.overwrite_meta(globals);
+
+ //2. find local infos
+ m_content.enumerate(__get_tag__local_field_filter(globals,output.m_meta));
+ }
+
+
+ //strip redundant titles and tracknumbers that the cuesheet already contains
+ for(cue_creator::t_entry_list::const_iterator iter = entries.first(); iter.is_valid(); ++iter) {
+ strip_redundant_track_meta(iter->m_track_number,iter->m_infos,output.m_meta,"tracknumber");
+ strip_redundant_track_meta(iter->m_track_number,iter->m_infos,output.m_meta,"title");
+ }
+
+
+ //add tech infos etc
+
+ {
+ const track_record * rec = m_content.query_ptr((unsigned)0);
+ if (rec != NULL) {
+ output.set_length(rec->m_info.get_length());
+ output.set_replaygain(rec->m_info.get_replaygain());
+ output.overwrite_info(rec->m_info.m_info);
+ }
+ }
+ output.meta_set("cuesheet",cuesheet);
+ output.to_info(p_info);
+ }
+}
+
+static bool resolve_cue_meta_name(const char * p_name,pfc::string_base & p_outname,unsigned & p_tracknumber) {
+ //"cue_trackNN_fieldname"
+ static const char header[] = "cue_track";
+ if (pfc::stricmp_ascii_ex(p_name,strlen(header),header,infinite) != 0) return false;
+ p_name += strlen(header);
+ if (!pfc::char_is_numeric(p_name[0]) || !pfc::char_is_numeric(p_name[1]) || p_name[2] != '_') return false;
+ unsigned tracknumber = pfc::atoui_ex(p_name,2);
+ if (tracknumber == 0) return false;
+ p_name += 3;
+ p_tracknumber = tracknumber;
+ p_outname = p_name;
+ return true;
+}
+
+
+namespace {
+ class __set_tag_global_field_relay {
+ public:
+ __set_tag_global_field_relay(const file_info & p_info,t_size p_index) : m_info(p_info), m_index(p_index) {}
+ void operator() (unsigned p_trackno,track_record & p_record) {
+ if (p_trackno > 0) {
+ p_record.m_info.transfer_meta_entry(m_info.meta_enum_name(m_index),m_info,m_index);
+ }
+ }
+ private:
+ const file_info & m_info;
+ const t_size m_index;
+ };
+}
+
+void embeddedcue_metadata_manager::set_tag(file_info const & p_info) {
+ m_content.remove_all();
+
+ {
+ track_record & track0 = m_content.find_or_add((unsigned)0);
+ track0.m_info.from_info(p_info);
+ track0.m_info.m_info.set("cue_embedded","no");
+ }
+
+
+
+ const char * cuesheet = p_info.meta_get("cuesheet",0);
+ if (cuesheet == NULL) {
+ return;
+ }
+
+ //processing order
+ //1. cuesheet content
+ //2. overwrite with global metadata from the tag
+ //2. overwrite with local metadata from the tag
+
+ {
+ cue_creator::t_entry_list entries;
+ try {
+ cue_parser::parse_full(cuesheet,entries);
+ } catch(exception_io_data const & e) {
+ console::formatter() << e;
+ return;
+ }
+
+ for(cue_creator::t_entry_list::const_iterator iter = entries.first(); iter.is_valid(); ) {
+ cue_creator::t_entry_list::const_iterator next = iter;
+ ++next;
+ track_record & entry = m_content.find_or_add(iter->m_track_number);
+ entry.m_file = iter->m_file;
+ entry.m_flags = iter->m_flags;
+ entry.m_index_list = iter->m_index_list;
+ entry.m_info.from_info(iter->m_infos);
+ entry.m_info.from_info_overwrite_info(p_info);
+ entry.m_info.m_info.set("cue_embedded","yes");
+ double begin = entry.m_index_list.start(), end = next.is_valid() ? next->m_index_list.start() : p_info.get_length();
+ if (end <= begin) throw exception_io_data();
+ entry.m_info.set_length(end - begin);
+ iter = next;
+ }
+ }
+
+ for(t_size metawalk = 0, metacount = p_info.meta_get_count(); metawalk < metacount; ++metawalk) {
+ const char * name = p_info.meta_enum_name(metawalk);
+ const t_size valuecount = p_info.meta_enum_value_count(metawalk);
+ if (valuecount > 0 && !is_reserved_meta_entry(name) && is_global_meta_entry(name)) {
+ __set_tag_global_field_relay relay(p_info,metawalk);
+ m_content.enumerate(relay);
+ }
+ }
+
+ {
+ pfc::string8_fastalloc namebuffer;
+ for(t_size metawalk = 0, metacount = p_info.meta_get_count(); metawalk < metacount; ++metawalk) {
+ const char * name = p_info.meta_enum_name(metawalk);
+ const t_size valuecount = p_info.meta_enum_value_count(metawalk);
+ unsigned trackno;
+ if (valuecount > 0 && !is_reserved_meta_entry(name) && resolve_cue_meta_name(name,namebuffer,trackno)) {
+ track_record * rec = m_content.query_ptr(trackno);
+ if (rec != NULL) {
+ rec->m_info.transfer_meta_entry(namebuffer,p_info,metawalk);
+ }
+ }
+ }
+ }
+}
+
+void embeddedcue_metadata_manager::get_track_info(unsigned p_track,file_info & p_info) const {
+ const track_record * rec = m_content.query_ptr(p_track);
+ if (rec == NULL) throw exception_io_data();
+ rec->m_info.to_info(p_info);
+}
+
+void embeddedcue_metadata_manager::set_track_info(unsigned p_track,file_info const & p_info) {
+ track_record * rec = m_content.query_ptr(p_track);
+ if (rec == NULL) throw exception_io_data();
+ rec->m_info.from_info_set_meta(p_info);
+ rec->m_info.set_replaygain(p_info.get_replaygain());
+}
+
+void embeddedcue_metadata_manager::query_track_offsets(unsigned p_track,double & p_begin,double & p_length) const {
+ const track_record * rec = m_content.query_ptr(p_track);
+ if (rec == NULL) throw exception_io_data();
+ p_begin = rec->m_index_list.start();
+ p_length = rec->m_info.get_length();
+}
+
+bool embeddedcue_metadata_manager::have_cuesheet() const {
+ return m_content.get_count() > 1;
+}
+
+namespace {
+ class __remap_trackno_enumerator {
+ public:
+ __remap_trackno_enumerator(unsigned p_index) : m_countdown(p_index), m_result(0) {}
+ template<typename t_blah> void operator() (unsigned p_trackno,const t_blah&) {
+ if (p_trackno > 0 && m_result == 0) {
+ if (m_countdown == 0) {
+ m_result = p_trackno;
+ } else {
+ --m_countdown;
+ }
+ }
+ }
+ unsigned result() const {return m_result;}
+ private:
+ unsigned m_countdown;
+ unsigned m_result;
+ };
+};
+
+unsigned embeddedcue_metadata_manager::remap_trackno(unsigned p_index) const {
+ if (have_cuesheet()) {
+ __remap_trackno_enumerator wrapper(p_index);
+ m_content.enumerate(wrapper);
+ return wrapper.result();
+ } else {
+ return 0;
+ }
+}
+
+t_size embeddedcue_metadata_manager::get_cue_track_count() const {
+ return m_content.get_count() - 1;
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cuesheet_index_list.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cuesheet_index_list.cpp
new file mode 100644
index 0000000..1b8b9b0
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cuesheet_index_list.cpp
@@ -0,0 +1,139 @@
+#include "stdafx.h"
+
+static bool is_numeric(char c) {return c>='0' && c<='9';}
+
+
+bool t_cuesheet_index_list::is_valid() const {
+ if (m_positions[1] < m_positions[0]) return false;
+ for(t_size n = 2; n < count && m_positions[n] > 0; n++) {
+ if (m_positions[n] < m_positions[n-1]) return false;
+ }
+ return true;
+}
+
+void t_cuesheet_index_list::to_infos(file_info & p_out) const
+{
+ double base = m_positions[1];
+
+ if (base > 0) {
+ p_out.info_set("referenced_offset",cuesheet_format_index_time(base));
+ }
+
+ if (m_positions[0] < base)
+ p_out.info_set("pregap",cuesheet_format_index_time(base - m_positions[0]));
+ else
+ p_out.info_remove("pregap");
+
+ p_out.info_remove("index 00");
+ p_out.info_remove("index 01");
+
+ for(unsigned n=2;n<count;n++)
+ {
+ char namebuffer[16];
+ sprintf(namebuffer,"index %02u",n);
+ double position = m_positions[n] - base;
+ if (position > 0)
+ p_out.info_set(namebuffer,cuesheet_format_index_time(position));
+ else
+ p_out.info_remove(namebuffer);
+ }
+}
+
+static bool parse_value(const char * p_name,double & p_out)
+{
+ if (p_name == NULL) return false;
+ try {
+ p_out = cuesheet_parse_index_time_e(p_name,strlen(p_name));
+ } catch(std::exception const &) {return false;}
+ return true;
+}
+
+bool t_cuesheet_index_list::from_infos(file_info const & p_in,double p_base)
+{
+ double pregap;
+ bool found = false;
+ if (!parse_value(p_in.info_get("pregap"),pregap)) pregap = 0;
+ else found = true;
+ m_positions[0] = p_base - pregap;
+ m_positions[1] = p_base;
+ for(unsigned n=2;n<count;n++)
+ {
+ char namebuffer[16];
+ sprintf(namebuffer,"index %02u",n);
+ double temp;
+ if (parse_value(p_in.info_get(namebuffer),temp)) {
+ m_positions[n] = temp + p_base; found = true;
+ } else {
+ m_positions[n] = 0;
+ }
+ }
+ return found;
+}
+
+cuesheet_format_index_time::cuesheet_format_index_time(double p_time)
+{
+ t_uint64 ticks = audio_math::time_to_samples(p_time,75);
+ t_uint64 seconds = ticks / 75; ticks %= 75;
+ t_uint64 minutes = seconds / 60; seconds %= 60;
+ m_buffer << pfc::format_uint(minutes,2) << ":" << pfc::format_uint(seconds,2) << ":" << pfc::format_uint(ticks,2);
+}
+
+double cuesheet_parse_index_time_e(const char * p_string,t_size p_length)
+{
+ return (double) cuesheet_parse_index_time_ticks_e(p_string,p_length) / 75.0;
+}
+
+unsigned cuesheet_parse_index_time_ticks_e(const char * p_string,t_size p_length)
+{
+ p_length = pfc::strlen_max(p_string,p_length);
+ t_size ptr = 0;
+ t_size splitmarks[2];
+ t_size splitptr = 0;
+ for(ptr=0;ptr<p_length;ptr++)
+ {
+ if (p_string[ptr] == ':')
+ {
+ if (splitptr >= 2) throw std::exception("invalid INDEX time syntax",0);
+ splitmarks[splitptr++] = ptr;
+ }
+ else if (!is_numeric(p_string[ptr])) throw std::exception("invalid INDEX time syntax",0);
+ }
+
+ t_size minutes_base = 0, minutes_length = 0, seconds_base = 0, seconds_length = 0, frames_base = 0, frames_length = 0;
+
+ switch(splitptr)
+ {
+ case 0:
+ frames_base = 0;
+ frames_length = p_length;
+ break;
+ case 1:
+ seconds_base = 0;
+ seconds_length = splitmarks[0];
+ frames_base = splitmarks[0] + 1;
+ frames_length = p_length - frames_base;
+ break;
+ case 2:
+ minutes_base = 0;
+ minutes_length = splitmarks[0];
+ seconds_base = splitmarks[0] + 1;
+ seconds_length = splitmarks[1] - seconds_base;
+ frames_base = splitmarks[1] + 1;
+ frames_length = p_length - frames_base;
+ break;
+ }
+
+ unsigned ret = 0;
+
+ if (frames_length > 0) ret += pfc::atoui_ex(p_string + frames_base,frames_length);
+ if (seconds_length > 0) ret += 75 * pfc::atoui_ex(p_string + seconds_base,seconds_length);
+ if (minutes_length > 0) ret += 60 * 75 * pfc::atoui_ex(p_string + minutes_base,minutes_length);
+
+ return ret;
+}
+
+
+bool t_cuesheet_index_list::is_empty() const {
+ for(unsigned n=0;n<count;n++) if (m_positions[n] != m_positions[1]) return false;
+ return true;
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cuesheet_index_list.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cuesheet_index_list.h
new file mode 100644
index 0000000..06512a6
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/cuesheet_index_list.h
@@ -0,0 +1,31 @@
+struct t_cuesheet_index_list
+{
+ enum {count = 100};
+ inline t_cuesheet_index_list() {reset();}
+ inline t_cuesheet_index_list(const t_cuesheet_index_list & p_source) {*this=p_source;}
+ void reset() {for(unsigned n=0;n<count;n++) m_positions[n]=0;}
+
+ void to_infos(file_info & p_out) const;
+
+ //returns false when there was nothing relevant in infos
+ bool from_infos(file_info const & p_in,double p_base);
+
+ double m_positions[count];
+
+ inline double start() const {return m_positions[1];}
+ bool is_empty() const;
+
+ bool is_valid() const;
+};
+
+unsigned cuesheet_parse_index_time_ticks_e(const char * p_string,t_size p_length);
+double cuesheet_parse_index_time_e(const char * p_string,t_size p_length);
+
+class cuesheet_format_index_time
+{
+public:
+ cuesheet_format_index_time(double p_time);
+ inline operator const char*() const {return m_buffer;}
+private:
+ pfc::string_formatter m_buffer;
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dialog_resize_helper.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dialog_resize_helper.cpp
new file mode 100644
index 0000000..7fad82e
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dialog_resize_helper.cpp
@@ -0,0 +1,230 @@
+#include "stdafx.h"
+#include "dialog_resize_helper.h"
+
+void resize::calc_xy(HWND wnd,UINT id,RECT &r,RECT & o)
+{
+ RECT c;
+ GetClientRect(wnd,&c);
+ SetWindowPos(GetDlgItem(wnd,id),0,0,0,
+ r.right-r.left+c.right-o.right,
+ r.bottom-r.top+c.bottom-o.bottom,
+ SWP_NOMOVE|SWP_NOZORDER);
+}
+
+void resize::calc_move_xy(HWND wnd,UINT id,RECT &r,RECT & o)
+{
+ RECT c;
+ GetClientRect(wnd,&c);
+ SetWindowPos(GetDlgItem(wnd,id),0,
+ c.right-o.right+r.left,
+ c.bottom-o.bottom+r.top,
+ 0,0,SWP_NOSIZE|SWP_NOZORDER);
+}
+
+void resize::calc_move_x(HWND wnd,UINT id,RECT &r,RECT & o)
+{
+ RECT c;
+ GetClientRect(wnd,&c);
+ SetWindowPos(GetDlgItem(wnd,id),0,
+ c.right-o.right+r.left,
+ r.top,
+ 0,0,SWP_NOSIZE|SWP_NOZORDER);
+}
+
+void resize::calc_move_x_size_y(HWND wnd,UINT id,RECT &r,RECT & o)
+{
+ RECT c;
+ GetClientRect(wnd,&c);
+ SetWindowPos(GetDlgItem(wnd,id),0,
+ c.right-o.right+r.left,
+ r.top,
+ r.right-r.left,
+ r.bottom-r.top+c.bottom-o.bottom,
+ SWP_NOZORDER);
+}
+
+void resize::calc_move_y(HWND wnd,UINT id,RECT &r,RECT & o)
+{
+ RECT c;
+ GetClientRect(wnd,&c);
+ SetWindowPos(GetDlgItem(wnd,id),0,
+ r.left,
+ c.bottom-o.bottom+r.top,
+ 0,0,SWP_NOSIZE|SWP_NOZORDER);
+}
+
+void resize::calc_x(HWND wnd,UINT id,RECT &r,RECT & o)
+{
+ RECT c;
+ GetClientRect(wnd,&c);
+ SetWindowPos(GetDlgItem(wnd,id),0,0,0,
+ r.right-r.left+c.right-o.right,
+ r.bottom-r.top,
+ SWP_NOMOVE|SWP_NOZORDER);
+}
+
+void GetChildRect(HWND wnd,UINT id,RECT* child)
+{
+ RECT temp;
+ GetWindowRect(GetDlgItem(wnd,id),&temp);
+ MapWindowPoints(0,wnd,(POINT*)&temp,2);
+ *child = temp;
+}
+
+/*
+class dialog_resize_helper
+{
+ struct entry { RECT orig; UINT id; UINT flags };
+ mem_block_list<entry> data;
+ RECT orig_client;
+ HWND parent;
+public:
+ enum {
+ X_MOVE = 1, X_SIZE = 2, Y_MOVE = 4, Y_SIZE = 8
+ };
+ void set_parent(HWND wnd);
+ void add_item(UINT id,UINT flags);
+ void reset();
+};
+*/
+
+void dialog_resize_helper::set_parent(HWND wnd)
+{
+ reset();
+ parent = wnd;
+ GetClientRect(parent,&orig_client);
+}
+
+void dialog_resize_helper::reset()
+{
+ parent = 0;
+ sizegrip = 0;
+}
+
+void dialog_resize_helper::on_wm_size()
+{
+ if (parent)
+ {
+ unsigned count = m_table.get_size();
+ if (sizegrip != 0) count++;
+ HDWP hWinPosInfo = BeginDeferWindowPos(count);
+ for(unsigned n=0;n<m_table.get_size();n++)
+ {
+ param & e = m_table[n];
+ const RECT & orig_rect = rects[n];
+ RECT cur_client;
+ GetClientRect(parent,&cur_client);
+ HWND wnd = GetDlgItem(parent,e.id);
+
+ unsigned dest_x = orig_rect.left, dest_y = orig_rect.top,
+ dest_cx = orig_rect.right - orig_rect.left, dest_cy = orig_rect.bottom - orig_rect.top;
+
+ int delta_x = cur_client.right - orig_client.right,
+ delta_y = cur_client.bottom - orig_client.bottom;
+
+ if (e.flags & X_MOVE)
+ dest_x += delta_x;
+ else if (e.flags & X_SIZE)
+ dest_cx += delta_x;
+
+ if (e.flags & Y_MOVE)
+ dest_y += delta_y;
+ else if (e.flags & Y_SIZE)
+ dest_cy += delta_y;
+
+ DeferWindowPos(hWinPosInfo, wnd,0,dest_x,dest_y,dest_cx,dest_cy,SWP_NOZORDER);
+ }
+ if (sizegrip != 0)
+ {
+ RECT rc, rc_grip;
+ GetClientRect(parent, &rc);
+ GetWindowRect(sizegrip, &rc_grip);
+ DeferWindowPos(hWinPosInfo, sizegrip, NULL, rc.right - (rc_grip.right - rc_grip.left), rc.bottom - (rc_grip.bottom - rc_grip.top), 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+ }
+ EndDeferWindowPos(hWinPosInfo);
+ RedrawWindow(parent,0,0,RDW_INVALIDATE);
+ }
+}
+
+
+bool dialog_resize_helper::process_message(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
+{
+ switch(msg)
+ {
+ case WM_SIZE:
+ on_wm_size();
+ return true;
+ case WM_GETMINMAXINFO:
+ {
+ RECT r;
+ LPMINMAXINFO info = (LPMINMAXINFO) lp;
+ DWORD dwStyle = GetWindowLong(wnd, GWL_STYLE);
+ DWORD dwExStyle = GetWindowLong(wnd, GWL_EXSTYLE);
+ if (max_x && max_y)
+ {
+ r.left = 0; r.right = max_x;
+ r.top = 0; r.bottom = max_y;
+ MapDialogRect(wnd,&r);
+ AdjustWindowRectEx(&r, dwStyle, FALSE, dwExStyle);
+ info->ptMaxTrackSize.x = r.right - r.left;
+ info->ptMaxTrackSize.y = r.bottom - r.top;
+ }
+ if (min_x && min_y)
+ {
+ r.left = 0; r.right = min_x;
+ r.top = 0; r.bottom = min_y;
+ MapDialogRect(wnd,&r);
+ AdjustWindowRectEx(&r, dwStyle, FALSE, dwExStyle);
+ info->ptMinTrackSize.x = r.right - r.left;
+ info->ptMinTrackSize.y = r.bottom - r.top;
+ }
+ }
+ return true;
+ case WM_INITDIALOG:
+ set_parent(wnd);
+ {
+ unsigned n;
+ for(n=0;n<m_table.get_size();n++)
+ {
+ GetChildRect(parent,m_table[n].id,&rects[n]);
+ }
+ }
+ break;
+ case WM_DESTROY:
+ reset();
+ break;
+ }
+ return false;
+}
+
+void dialog_resize_helper::add_sizegrip()
+{
+ if (parent != 0 && sizegrip == 0)
+ {
+ sizegrip = CreateWindowEx(0, WC_SCROLLBAR, _T(""), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SBS_SIZEGRIP | SBS_SIZEBOXBOTTOMRIGHTALIGN,
+ 0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
+ parent, (HMENU)0, NULL, NULL);
+ if (sizegrip != 0)
+ {
+ RECT rc, rc_grip;
+ GetClientRect(parent, &rc);
+ GetWindowRect(sizegrip, &rc_grip);
+ SetWindowPos(sizegrip, NULL, rc.right - (rc_grip.right - rc_grip.left), rc.bottom - (rc_grip.bottom - rc_grip.top), 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+ }
+ }
+}
+
+
+dialog_resize_helper::dialog_resize_helper(const param * src,unsigned count,unsigned p_min_x,unsigned p_min_y,unsigned p_max_x,unsigned p_max_y)
+ : min_x(p_min_x), min_y(p_min_y), max_x(p_max_x), max_y(p_max_y), parent(0), sizegrip(0)
+{
+ m_table.set_size(count);
+ unsigned n;
+ for(n=0;n<count;n++)
+ m_table[n] = src[n];
+ rects.set_size(count);
+}
+
+dialog_resize_helper::~dialog_resize_helper()
+{
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dialog_resize_helper.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dialog_resize_helper.h
new file mode 100644
index 0000000..cdd5c54
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dialog_resize_helper.h
@@ -0,0 +1,58 @@
+#ifndef _DIALOG_RESIZE_HELPER_H_
+#define _DIALOG_RESIZE_HELPER_H_
+
+
+//deprecated, use dialog_resize_helper class
+namespace resize
+{
+ void calc_xy(HWND wnd,UINT id,RECT &r,RECT & o);
+ void calc_move_xy(HWND wnd,UINT id,RECT &r,RECT & o);
+ void calc_move_x(HWND wnd,UINT id,RECT &r,RECT & o);
+ void calc_move_x_size_y(HWND wnd,UINT id,RECT &r,RECT & o);
+ void calc_move_y(HWND wnd,UINT id,RECT &r,RECT & o);
+ void calc_x(HWND wnd,UINT id,RECT &r,RECT & o);
+};
+
+void GetChildRect(HWND wnd,UINT id,RECT* child);
+
+
+class dialog_resize_helper
+{
+ pfc::array_t<RECT> rects;
+ RECT orig_client;
+ HWND parent;
+ HWND sizegrip;
+ unsigned min_x,min_y,max_x,max_y;
+
+public:
+ struct param {
+ unsigned short id;
+ unsigned short flags;
+ };
+private:
+ pfc::array_t<param> m_table;
+
+ void set_parent(HWND wnd);
+ void add_item(UINT id,UINT flags);
+ void reset();
+ void on_wm_size();
+ void add_items(const param* table,unsigned count);
+public:
+ inline void set_min_size(unsigned x,unsigned y) {min_x = x; min_y = y;}
+ inline void set_max_size(unsigned x,unsigned y) {max_x = x; max_y = y;}
+ void add_sizegrip();
+
+ enum {
+ X_MOVE = 1, X_SIZE = 2, Y_MOVE = 4, Y_SIZE = 8,
+ XY_MOVE = X_MOVE|Y_MOVE, XY_SIZE = X_SIZE|Y_SIZE,
+ X_MOVE_Y_SIZE = X_MOVE|Y_SIZE, X_SIZE_Y_MOVE = X_SIZE|Y_MOVE,
+ };
+ bool process_message(HWND wnd,UINT msg,WPARAM wp,LPARAM lp);
+
+
+
+ explicit dialog_resize_helper(const param * src,unsigned count,unsigned p_min_x,unsigned p_min_y,unsigned p_max_x,unsigned p_max_y);
+ ~dialog_resize_helper();
+};
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dropdown_helper.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dropdown_helper.cpp
new file mode 100644
index 0000000..70f51f2
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dropdown_helper.cpp
@@ -0,0 +1,152 @@
+#include "stdafx.h"
+#include "dropdown_helper.h"
+
+
+void cfg_dropdown_history::build_list(pfc::ptr_list_t<char> & out)
+{
+ const char * src = data;
+ while(*src)
+ {
+ int ptr = 0;
+ while(src[ptr] && src[ptr]!=separator) ptr++;
+ if (ptr>0)
+ {
+ out.add_item(pfc::strdup_n(src,ptr));
+ src += ptr;
+ }
+ while(*src==separator) src++;
+ }
+}
+
+void cfg_dropdown_history::parse_list(const pfc::ptr_list_t<char> & src)
+{
+ t_size n;
+ pfc::string8_fastalloc temp;
+ for(n=0;n<src.get_count();n++)
+ {
+ temp.add_string(src[n]);
+ temp.add_char(separator);
+ }
+ data = temp;
+}
+
+static void g_setup_dropdown_fromlist(HWND wnd,const pfc::ptr_list_t<char> & list)
+{
+ t_size n, m = list.get_count();
+ uSendMessage(wnd,CB_RESETCONTENT,0,0);
+ for(n=0;n<m;n++) {
+ uSendMessageText(wnd,CB_ADDSTRING,0,list[n]);
+ }
+}
+
+void cfg_dropdown_history::setup_dropdown(HWND wnd)
+{
+ pfc::ptr_list_t<char> list;
+ build_list(list);
+ g_setup_dropdown_fromlist(wnd,list);
+ list.free_all();
+}
+
+void cfg_dropdown_history::add_item(const char * item)
+{
+ if (!item || !*item) return;
+ pfc::string8 meh;
+ if (strchr(item,separator))
+ {
+ uReplaceChar(meh,item,-1,separator,'|',false);
+ item = meh;
+ }
+ pfc::ptr_list_t<char> list;
+ build_list(list);
+ unsigned n;
+ bool found = false;
+ for(n=0;n<list.get_count();n++)
+ {
+ if (!strcmp(list[n],item))
+ {
+ char* temp = list.remove_by_idx(n);
+ list.insert_item(temp,0);
+ found = true;
+ }
+ }
+
+ if (!found)
+ {
+ while(list.get_count() > max) list.delete_by_idx(list.get_count()-1);
+ list.insert_item(strdup(item),0);
+ }
+ parse_list(list);
+ list.free_all();
+}
+
+bool cfg_dropdown_history::is_empty()
+{
+ const char * src = data;
+ while(*src)
+ {
+ if (*src!=separator) return false;
+ src++;
+ }
+ return true;
+}
+
+void cfg_dropdown_history::on_context(HWND wnd,LPARAM coords)
+{
+ int coords_x = (short)LOWORD(coords), coords_y = (short)HIWORD(coords);
+ if (coords_x == -1 && coords_y == -1)
+ {
+ RECT asdf;
+ GetWindowRect(wnd,&asdf);
+ coords_x = (asdf.left + asdf.right) / 2;
+ coords_y = (asdf.top + asdf.bottom) / 2;
+ }
+ enum {ID_ERASE_ALL = 1, ID_ERASE_ONE };
+ HMENU menu = CreatePopupMenu();
+ uAppendMenu(menu,MF_STRING,ID_ERASE_ALL,"Wipe history");
+ {
+ pfc::string8 tempvalue;
+ uGetWindowText(wnd,tempvalue);
+ if (!tempvalue.is_empty())
+ uAppendMenu(menu,MF_STRING,ID_ERASE_ONE,"Remove this history item");
+ }
+ int cmd = TrackPopupMenu(menu,TPM_RIGHTBUTTON|TPM_NONOTIFY|TPM_RETURNCMD,coords_x,coords_y,0,wnd,0);
+ DestroyMenu(menu);
+ switch(cmd)
+ {
+ case ID_ERASE_ALL:
+ {
+ data = "";
+ pfc::string8 value;//preserve old value while wiping dropdown list
+ uGetWindowText(wnd,value);
+ uSendMessage(wnd,CB_RESETCONTENT,0,0);
+ uSetWindowText(wnd,value);
+ }
+ break;
+ case ID_ERASE_ONE:
+ {
+ pfc::string8 value;
+ uGetWindowText(wnd,value);
+
+ pfc::ptr_list_t<char> list;
+ t_size n,m;
+ bool found;
+ build_list(list);
+ m = list.get_count();
+ found = false;
+ for(n=0;n<m;n++)
+ {
+ if (!strcmp(value,list[n]))
+ {
+ free(list[n]);
+ list.remove_by_idx(n);
+ found = true;
+ break;
+ }
+ }
+ if (found) parse_list(list);
+ g_setup_dropdown_fromlist(wnd,list);
+ list.free_all();
+ }
+ break;
+ }
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dropdown_helper.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dropdown_helper.h
new file mode 100644
index 0000000..35b0dfa
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dropdown_helper.h
@@ -0,0 +1,22 @@
+#ifndef _DROPDOWN_HELPER_H_
+#define _DROPDOWN_HELPER_H_
+
+
+class cfg_dropdown_history
+{
+ enum {separator = '\n'};
+ cfg_string data;
+ unsigned max;
+ void build_list(pfc::ptr_list_t<char> & out);
+ void parse_list(const pfc::ptr_list_t<char> & src);
+public:
+ cfg_dropdown_history(const GUID & p_guid,unsigned p_max = 10,const char * init_vals = "") : data(p_guid,init_vals) {max = p_max;}
+ void setup_dropdown(HWND wnd);
+ void setup_dropdown(HWND wnd,UINT id) {setup_dropdown(GetDlgItem(wnd,id));}
+ void add_item(const char * item);
+ bool is_empty();
+ void on_context(HWND wnd,LPARAM coords);
+};
+
+
+#endif //_DROPDOWN_HELPER_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dynamic_bitrate_helper.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dynamic_bitrate_helper.cpp
new file mode 100644
index 0000000..2be9380
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dynamic_bitrate_helper.cpp
@@ -0,0 +1,74 @@
+#include "stdafx.h"
+
+static unsigned g_query_settings()
+{
+ t_int32 temp;
+ try {
+ config_object::g_get_data_int32(standard_config_objects::int32_dynamic_bitrate_display_rate,temp);
+ } catch(std::exception const &) {return 9;}
+ if (temp < 0) return 0;
+ return (unsigned) temp;
+}
+
+dynamic_bitrate_helper::dynamic_bitrate_helper()
+{
+ reset();
+}
+
+void dynamic_bitrate_helper::init()
+{
+ if (!m_inited)
+ {
+ m_inited = true;
+ unsigned temp = g_query_settings();
+ if (temp > 0) {m_enabled = true; m_update_interval = 1.0 / (double) temp; }
+ else {m_enabled = false; m_update_interval = 0; }
+ m_last_duration = 0;
+ m_update_bits = 0;
+ m_update_time = 0;
+
+ }
+}
+
+void dynamic_bitrate_helper::on_frame(double p_duration,t_size p_bits)
+{
+ init();
+ m_last_duration = p_duration;
+ m_update_time += p_duration;
+ m_update_bits += p_bits;
+}
+
+bool dynamic_bitrate_helper::on_update(file_info & p_out, double & p_timestamp_delta)
+{
+ init();
+
+ bool ret = false;
+ if (m_enabled)
+ {
+ if (m_update_time > m_update_interval)
+ {
+ int val = (int) ( ((double)m_update_bits / m_update_time + 500.0) / 1000.0 );
+ if (val != p_out.info_get_bitrate_vbr())
+ {
+ p_timestamp_delta = - (m_update_time - m_last_duration); //relative to last frame beginning;
+ p_out.info_set_bitrate_vbr(val);
+ ret = true;
+ }
+ m_update_bits = 0;
+ m_update_time = 0;
+ }
+ }
+ else
+ {
+ m_update_bits = 0;
+ m_update_time = 0;
+ }
+
+ return ret;
+
+}
+
+void dynamic_bitrate_helper::reset()
+{
+ m_inited = false;
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dynamic_bitrate_helper.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dynamic_bitrate_helper.h
new file mode 100644
index 0000000..6480c67
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/dynamic_bitrate_helper.h
@@ -0,0 +1,15 @@
+class dynamic_bitrate_helper
+{
+public:
+ dynamic_bitrate_helper();
+ void on_frame(double p_duration,t_size p_bits);
+ bool on_update(file_info & p_out, double & p_timestamp_delta);
+ void reset();
+private:
+ void init();
+ double m_last_duration;
+ t_size m_update_bits;
+ double m_update_time;
+ double m_update_interval;
+ bool m_inited, m_enabled;
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_cached.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_cached.h
new file mode 100644
index 0000000..75330fc
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_cached.h
@@ -0,0 +1,115 @@
+template<unsigned blocksize>
+class file_cached : public file {
+public:
+ static void g_create(service_ptr_t<file> & p_out,service_ptr_t<file> p_base,abort_callback & p_abort) {
+ service_ptr_t<file_cached<blocksize> > temp;
+ temp = new service_impl_t<file_cached<blocksize> >();
+ temp->initialize(p_base,p_abort);
+ p_out = temp.get_ptr();
+ }
+private:
+ void initialize(service_ptr_t<file> p_base,abort_callback & p_abort) {
+ m_base = p_base;
+ m_position = 0;
+ m_can_seek = m_base->can_seek();
+ if (m_can_seek) {
+ m_position_base = m_base->get_position(p_abort);
+ } else {
+ m_position_base = 0;
+ }
+
+ m_size = m_base->get_size(p_abort);
+
+ flush_buffer();
+ }
+public:
+
+ t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ t_uint8 * outptr = (t_uint8*)p_buffer;
+ t_size done = 0;
+ while(done < p_bytes && m_position < m_size) {
+ p_abort.check();
+
+ if (m_position >= m_buffer_position && m_position < m_buffer_position + m_buffer_status) {
+ t_size delta = pfc::min_t<t_size>((t_size)(m_buffer_position + m_buffer_status - m_position),p_bytes - done);
+ t_size bufptr = (t_size)(m_position - m_buffer_position);
+ memcpy(outptr+done,m_buffer+bufptr,delta);
+ done += delta;
+ m_position += delta;
+ if (m_buffer_status != sizeof(m_buffer) && done < p_bytes) break;//EOF before m_size is hit
+ } else {
+ m_buffer_position = m_position - m_position % blocksize;
+ adjust_position(m_buffer_position,p_abort);
+
+ m_buffer_status = m_base->read(m_buffer,sizeof(m_buffer),p_abort);
+ m_position_base += m_buffer_status;
+
+ if (m_buffer_status <= (t_size)(m_position - m_buffer_position)) break;
+ }
+ }
+
+ return done;
+ }
+
+ void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ p_abort.check();
+ adjust_position(m_position,p_abort);
+ m_base->write(p_buffer,p_bytes,p_abort);
+ m_position_base = m_position = m_position + p_bytes;
+ if (m_size < m_position) m_size = m_position;
+ flush_buffer();
+ }
+
+ t_filesize get_size(abort_callback & p_abort) {
+ p_abort.check();
+ return m_size;
+ }
+ t_filesize get_position(abort_callback & p_abort) {
+ p_abort.check();
+ return m_position;
+ }
+ void set_eof(abort_callback & p_abort) {
+ p_abort.check();
+ adjust_position(m_position,p_abort);
+ m_base->set_eof(p_abort);
+ flush_buffer();
+ }
+ void seek(t_filesize p_position,abort_callback & p_abort) {
+ p_abort.check();
+ if (!m_can_seek) throw exception_io_object_not_seekable();
+ if (p_position > m_size) throw exception_io_seek_out_of_range();
+ m_position = p_position;
+ }
+ void reopen(abort_callback & p_abort) {seek(0,p_abort);}
+ bool can_seek() {return m_can_seek;}
+ bool get_content_type(pfc::string_base & out) {return m_base->get_content_type(out);}
+ void on_idle(abort_callback & p_abort) {p_abort.check();m_base->on_idle(p_abort);}
+ t_filetimestamp get_timestamp(abort_callback & p_abort) {p_abort.check(); return m_base->get_timestamp(p_abort);}
+ bool is_remote() {return m_base->is_remote();}
+ void resize(t_filesize p_size,abort_callback & p_abort) {
+ flush_buffer();
+ m_base->resize(p_size,p_abort);
+ m_size = p_size;
+ if (m_position > m_size) m_position = m_size;
+ if (m_position_base > m_size) m_position_base = m_size;
+ }
+private:
+ void adjust_position(t_filesize p_target,abort_callback & p_abort) {
+ if (p_target != m_position_base) {
+ m_base->seek(p_target,p_abort);
+ m_position_base = p_target;
+ }
+ }
+
+ void flush_buffer() {
+ m_buffer_status = 0;
+ m_buffer_position = 0;
+ }
+
+ service_ptr_t<file> m_base;
+ t_filesize m_position,m_position_base,m_size;
+ bool m_can_seek;
+ t_filesize m_buffer_position;
+ t_size m_buffer_status;
+ t_uint8 m_buffer[blocksize];
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_info_const_impl.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_info_const_impl.cpp
new file mode 100644
index 0000000..5ae4386
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_info_const_impl.cpp
@@ -0,0 +1,287 @@
+#include "stdafx.h"
+
+static const char * const standard_fieldnames[] =
+{
+ "artist","ARTIST","Artist",
+ "album","ALBUM","Album",
+ "tracknumber","TRACKNUMBER","Tracknumber",
+ "totaltracks","TOTALTRACKS","Totaltracks",
+ "genre","GENRE","Genre",
+ "title","TITLE","Title",
+ "comment","COMMENT","Comment",
+ "date","DATE","Date",
+ "discnumber","DISCNUMBER","Discnumber"
+};
+
+static const char * const standard_infonames[] =
+{
+ "bitspersample", "channels", "bitrate", "codec", "codec_profile","tool","tagtype", "samplerate"
+};
+
+static const char * optimize_fieldname(const char * p_string)
+{
+ for(t_size n=0;n<tabsize(standard_fieldnames);n++)
+ {
+ const char * stdstring = standard_fieldnames[n];
+ if (/*p_string[0] == stdstring[0] && */strcmp(p_string,stdstring) == 0) {
+ return stdstring;
+ }
+ }
+ return NULL;
+}
+
+static const char * optimize_infoname(const char * p_string)
+{
+ for(t_size n=0;n<tabsize(standard_infonames);n++)
+ {
+ const char * stdstring = standard_infonames[n];
+ if (/*p_string[0] == stdstring[0] && */strcmp(p_string,stdstring) == 0) {
+ return stdstring;
+ }
+ }
+ return NULL;
+}
+
+/*
+order of things
+
+ meta entries
+ meta value map
+ info entries
+ string buffer
+
+*/
+
+inline static char* stringbuffer_append(char * & buffer,const char * value)
+{
+ char * ret = buffer;
+ while(*value) *(buffer++) = *(value++);
+ *(buffer++) = 0;
+ return ret;
+}
+
+#ifdef __file_info_const_impl_have_hintmap__
+
+namespace {
+ class sort_callback_hintmap_impl : public pfc::sort_callback
+ {
+ public:
+ sort_callback_hintmap_impl(const file_info_const_impl::meta_entry * p_meta,file_info_const_impl::t_index * p_hintmap)
+ : m_meta(p_meta), m_hintmap(p_hintmap)
+ {
+ }
+
+ int compare(t_size p_index1, t_size p_index2) const
+ {
+// profiler(sort_callback_hintmap_impl_compare);
+ return pfc::stricmp_ascii(m_meta[m_hintmap[p_index1]].m_name,m_meta[m_hintmap[p_index2]].m_name);
+ }
+
+ void swap(t_size p_index1, t_size p_index2)
+ {
+ pfc::swap_t<file_info_const_impl::t_index>(m_hintmap[p_index1],m_hintmap[p_index2]);
+ }
+ private:
+ const file_info_const_impl::meta_entry * m_meta;
+ file_info_const_impl::t_index * m_hintmap;
+ };
+
+ class bsearch_callback_hintmap_impl : public pfc::bsearch_callback
+ {
+ public:
+ bsearch_callback_hintmap_impl(
+ const file_info_const_impl::meta_entry * p_meta,
+ const file_info_const_impl::t_index * p_hintmap,
+ const char * p_name,
+ t_size p_name_length)
+ : m_meta(p_meta), m_hintmap(p_hintmap), m_name(p_name), m_name_length(p_name_length)
+ {
+ }
+
+ int test(t_size p_index) const
+ {
+ return pfc::stricmp_ascii_ex(m_meta[m_hintmap[p_index]].m_name,infinite,m_name,m_name_length);
+ }
+
+ private:
+ const file_info_const_impl::meta_entry * m_meta;
+ const file_info_const_impl::t_index * m_hintmap;
+ const char * m_name;
+ t_size m_name_length;
+ };
+}
+
+#endif//__file_info_const_impl_have_hintmap__
+
+void file_info_const_impl::copy(const file_info & p_source)
+{
+// profiler(file_info_const_impl__copy);
+ t_size meta_size = 0;
+ t_size info_size = 0;
+ t_size valuemap_size = 0;
+ t_size stringbuffer_size = 0;
+#ifdef __file_info_const_impl_have_hintmap__
+ t_size hintmap_size = 0;
+#endif
+
+ {
+// profiler(file_info_const_impl__copy__pass1);
+ t_size index;
+ m_meta_count = pfc::downcast_guarded<t_index>(p_source.meta_get_count());
+ meta_size = m_meta_count * sizeof(meta_entry);
+#ifdef __file_info_const_impl_have_hintmap__
+ hintmap_size = (m_meta_count > hintmap_cutoff) ? m_meta_count * sizeof(t_index) : 0;
+#endif//__file_info_const_impl_have_hintmap__
+ for(index = 0; index < m_meta_count; index++ )
+ {
+ {
+ const char * name = p_source.meta_enum_name(index);
+ if (optimize_fieldname(name) == 0)
+ stringbuffer_size += strlen(name) + 1;
+ }
+
+ t_size val; const t_size val_max = p_source.meta_enum_value_count(index);
+
+ if (val_max == 1)
+ {
+ stringbuffer_size += strlen(p_source.meta_enum_value(index,0)) + 1;
+ }
+ else
+ {
+ valuemap_size += val_max * sizeof(char*);
+
+ for(val = 0; val < val_max; val++ )
+ {
+ stringbuffer_size += strlen(p_source.meta_enum_value(index,val)) + 1;
+ }
+ }
+ }
+
+ m_info_count = pfc::downcast_guarded<t_index>(p_source.info_get_count());
+ info_size = m_info_count * sizeof(info_entry);
+ for(index = 0; index < m_info_count; index++ )
+ {
+ const char * name = p_source.info_enum_name(index);
+ if (optimize_infoname(name) == NULL) stringbuffer_size += strlen(name) + 1;
+ stringbuffer_size += strlen(p_source.info_enum_value(index)) + 1;
+ }
+ }
+
+
+ {
+// profiler(file_info_const_impl__copy__alloc);
+ m_buffer.set_size(
+#ifdef __file_info_const_impl_have_hintmap__
+ hintmap_size +
+#endif
+ meta_size + info_size + valuemap_size + stringbuffer_size);
+ }
+
+ char * walk = m_buffer.get_ptr();
+
+#ifdef __file_info_const_impl_have_hintmap__
+ t_index* hintmap = (hintmap_size > 0) ? (t_index*) walk : NULL;
+ walk += hintmap_size;
+#endif
+ meta_entry * meta = (meta_entry*) walk;
+ walk += meta_size;
+ char ** valuemap = (char**) walk;
+ walk += valuemap_size;
+ info_entry * info = (info_entry*) walk;
+ walk += info_size;
+ char * stringbuffer = walk;
+
+ m_meta = meta;
+ m_info = info;
+#ifdef __file_info_const_impl_have_hintmap__
+ m_hintmap = hintmap;
+#endif
+
+ {
+// profiler(file_info_const_impl__copy__pass2);
+ t_size index;
+ for( index = 0; index < m_meta_count; index ++ )
+ {
+ t_size val; const t_size val_max = p_source.meta_enum_value_count(index);
+
+ {
+ const char * name = p_source.meta_enum_name(index);
+ const char * name_opt = optimize_fieldname(name);
+ if (name_opt == NULL)
+ meta[index].m_name = stringbuffer_append(stringbuffer, name );
+ else
+ meta[index].m_name = name_opt;
+ }
+
+ meta[index].m_valuecount = val_max;
+
+ if (val_max == 1)
+ {
+ meta[index].m_valuemap = reinterpret_cast<const char * const *>(stringbuffer_append(stringbuffer, p_source.meta_enum_value(index,0) ));
+ }
+ else
+ {
+ meta[index].m_valuemap = valuemap;
+ for( val = 0; val < val_max ; val ++ )
+ *(valuemap ++ ) = stringbuffer_append(stringbuffer, p_source.meta_enum_value(index,val) );
+ }
+ }
+
+ for( index = 0; index < m_info_count; index ++ )
+ {
+ const char * name = p_source.info_enum_name(index);
+ const char * name_opt = optimize_infoname(name);
+ if (name_opt == NULL)
+ info[index].m_name = stringbuffer_append(stringbuffer, name );
+ else
+ info[index].m_name = name_opt;
+ info[index].m_value = stringbuffer_append(stringbuffer, p_source.info_enum_value(index) );
+ }
+ }
+
+ m_length = p_source.get_length();
+ m_replaygain = p_source.get_replaygain();
+#ifdef __file_info_const_impl_have_hintmap__
+ if (hintmap != NULL) {
+// profiler(file_info_const_impl__copy__hintmap);
+ for(t_size n=0;n<m_meta_count;n++) hintmap[n]=n;
+ pfc::sort(sort_callback_hintmap_impl(meta,hintmap),m_meta_count);
+ }
+#endif//__file_info_const_impl_have_hintmap__
+}
+
+
+void file_info_const_impl::reset()
+{
+ m_meta_count = m_info_count = 0; m_length = 0; m_replaygain.reset();
+}
+
+t_size file_info_const_impl::meta_find_ex(const char * p_name,t_size p_name_length) const
+{
+#ifdef __file_info_const_impl_have_hintmap__
+ if (m_hintmap != NULL) {
+ t_size result = infinite;
+ if (!pfc::bsearch(m_meta_count,bsearch_callback_hintmap_impl(m_meta,m_hintmap,p_name,p_name_length),result)) return infinite;
+ else return m_hintmap[result];
+ } else {
+ return file_info::meta_find_ex(p_name,p_name_length);
+ }
+#else
+ return file_info::meta_find_ex(p_name,p_name_length);
+#endif
+}
+
+
+t_size file_info_const_impl::meta_enum_value_count(t_size p_index) const
+{
+ return m_meta[p_index].m_valuecount;
+}
+
+const char* file_info_const_impl::meta_enum_value(t_size p_index,t_size p_value_number) const
+{
+ const meta_entry & entry = m_meta[p_index];
+ if (entry.m_valuecount == 1)
+ return reinterpret_cast<const char*>(entry.m_valuemap);
+ else
+ return entry.m_valuemap[p_value_number];
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_info_const_impl.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_info_const_impl.h
new file mode 100644
index 0000000..a267aeb
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_info_const_impl.h
@@ -0,0 +1,78 @@
+#define __file_info_const_impl_have_hintmap__
+
+//! Special implementation of file_info that implements only const and copy methods. The difference between this and regular file_info_impl is amount of resources used and speed of the copy operation.
+class file_info_const_impl : public file_info
+{
+public:
+ file_info_const_impl(const file_info & p_source) {copy(p_source);}
+ file_info_const_impl(const file_info_const_impl & p_source) {copy(p_source);}
+ file_info_const_impl() {m_meta_count = m_info_count = 0; m_length = 0; m_replaygain.reset();}
+
+ double get_length() const {return m_length;}
+
+ t_size meta_get_count() const {return m_meta_count;}
+ const char* meta_enum_name(t_size p_index) const {return m_meta[p_index].m_name;}
+ t_size meta_enum_value_count(t_size p_index) const;
+ const char* meta_enum_value(t_size p_index,t_size p_value_number) const;
+ t_size meta_find_ex(const char * p_name,t_size p_name_length) const;
+
+ t_size info_get_count() const {return m_info_count;}
+ const char* info_enum_name(t_size p_index) const {return m_info[p_index].m_name;}
+ const char* info_enum_value(t_size p_index) const {return m_info[p_index].m_value;}
+
+
+ const file_info_const_impl & operator=(const file_info & p_source) {copy(p_source); return *this;}
+ const file_info_const_impl & operator=(const file_info_const_impl & p_source) {copy(p_source); return *this;}
+ void copy(const file_info & p_source);
+ void reset();
+
+ replaygain_info get_replaygain() const {return m_replaygain;}
+
+private:
+ void set_length(double p_length) {throw pfc::exception_bug_check();}
+
+ t_size meta_set_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length) {throw pfc::exception_bug_check();}
+ void meta_insert_value_ex(t_size p_index,t_size p_value_index,const char * p_value,t_size p_value_length) {throw pfc::exception_bug_check();}
+ void meta_remove_mask(const bit_array & p_mask) {throw pfc::exception_bug_check();}
+ void meta_reorder(const t_size * p_order) {throw pfc::exception_bug_check();}
+ void meta_remove_values(t_size p_index,const bit_array & p_mask) {throw pfc::exception_bug_check();}
+ void meta_modify_value_ex(t_size p_index,t_size p_value_index,const char * p_value,t_size p_value_length) {throw pfc::exception_bug_check();}
+
+ t_size info_set_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length) {throw pfc::exception_bug_check();}
+ void info_remove_mask(const bit_array & p_mask) {throw pfc::exception_bug_check();}
+
+ void set_replaygain(const replaygain_info & p_info) {throw pfc::exception_bug_check();}
+
+ t_size meta_set_nocheck_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length) {throw pfc::exception_bug_check();}
+ t_size info_set_nocheck_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length) {throw pfc::exception_bug_check();}
+public:
+ struct meta_entry {
+ const char * m_name;
+ t_size m_valuecount;
+ const char * const * m_valuemap;
+ };
+
+ struct info_entry {
+ const char * m_name;
+ const char * m_value;
+ };
+
+#ifdef __file_info_const_impl_have_hintmap__
+ typedef t_uint32 t_index;
+ enum {hintmap_cutoff = 20};
+#endif//__file_info_const_impl_have_hintmap__
+private:
+ pfc::array_t<char> m_buffer;
+ t_index m_meta_count;
+ t_index m_info_count;
+
+ const meta_entry * m_meta;
+ const info_entry * m_info;
+
+#ifdef __file_info_const_impl_have_hintmap__
+ const t_index * m_hintmap;
+#endif
+
+ double m_length;
+ replaygain_info m_replaygain;
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_list_helper.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_list_helper.cpp
new file mode 100644
index 0000000..3dacfea
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_list_helper.cpp
@@ -0,0 +1,63 @@
+#include "stdafx.h"
+
+static void file_list_remove_duplicates(pfc::ptr_list_t<char> & out)
+{
+ t_size n, m = out.get_count();
+ out.sort_t(metadb::path_compare);
+ bit_array_bittable mask(m);
+ t_size duplicates = 0;
+ for(n=1;n<m;n++) {
+ if (!metadb::path_compare(out[n-1],out[n])) {duplicates++;mask.set(n,true);}
+ }
+ if (duplicates>0) {
+ out.free_mask(mask);
+ }
+}
+
+
+namespace file_list_helper
+{
+ void file_list_from_metadb_handle_list::__add(const char * p_what) {
+ char * temp = strdup(p_what);
+ if (temp == NULL) throw std::bad_alloc();
+ try {m_data.add_item(temp); } catch(...) {free(temp); throw;}
+ }
+
+ void file_list_from_metadb_handle_list::init_from_list(const list_base_const_t<metadb_handle_ptr> & p_list)
+ {
+ m_data.free_all();
+
+ t_size n, m = p_list.get_count();
+ for(n=0;n<m;n++) {
+ __add( p_list.get_item(n)->get_path() );
+ }
+ file_list_remove_duplicates(m_data);
+
+ }
+
+ void file_list_from_metadb_handle_list::init_from_list_display(const list_base_const_t<metadb_handle_ptr> & p_list)
+ {
+ m_data.free_all();
+
+ pfc::string8_fastalloc temp;
+
+ t_size n, m = p_list.get_count();
+ for(n=0;n<m;n++)
+ {
+ filesystem::g_get_display_path(p_list.get_item(n)->get_path(),temp);
+ __add(temp);
+ }
+ file_list_remove_duplicates(m_data);
+
+
+ }
+
+ t_size file_list_from_metadb_handle_list::get_count() const {return m_data.get_count();}
+ void file_list_from_metadb_handle_list::get_item_ex(const char * & p_out,t_size n) const {p_out = m_data.get_item(n);}
+
+ file_list_from_metadb_handle_list::~file_list_from_metadb_handle_list()
+ {
+ m_data.free_all();
+ }
+
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_list_helper.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_list_helper.h
new file mode 100644
index 0000000..e4b9fcd
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_list_helper.h
@@ -0,0 +1,28 @@
+#ifndef _foobar2000_helpers_file_list_helper_
+#define _foobar2000_helpers_file_list_helper_
+
+
+namespace file_list_helper
+{
+ //list guaranteed to be sorted by metadb::path_compare
+ class file_list_from_metadb_handle_list : public pfc::list_base_const_t<const char*> {
+ public:
+
+ void init_from_list(const list_base_const_t<metadb_handle_ptr> & p_list);
+ void init_from_list_display(const list_base_const_t<metadb_handle_ptr> & p_list);
+
+ t_size get_count() const;
+ void get_item_ex(const char * & p_out,t_size n) const;
+
+ ~file_list_from_metadb_handle_list();
+
+ private:
+ void __add(const char * p_what);
+ pfc::ptr_list_t<char> m_data;
+ };
+
+
+};
+
+
+#endif //_foobar2000_helpers_file_list_helper_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_move_helper.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_move_helper.cpp
new file mode 100644
index 0000000..b54c99e
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_move_helper.cpp
@@ -0,0 +1,278 @@
+#include "stdafx.h"
+
+static bool grab_items_by_path(pfc::list_base_t<metadb_handle_ptr> & p_out,const char * p_path,abort_callback & p_abort)
+{
+ try {
+ pfc::string8 path;
+ filesystem::g_get_canonical_path(p_path,path);
+ p_out.remove_all();
+ service_ptr_t<input_info_reader> reader;
+ input_entry::g_open_for_info_read(reader,0,path,p_abort);
+
+ static_api_ptr_t<metadb> l_metadb;
+
+ const t_uint32 count = reader->get_subsong_count();
+ for(t_uint32 n=0;n<count;n++) {
+ p_abort.check_e();
+ metadb_handle_ptr ptr;
+ l_metadb->handle_create(ptr,make_playable_location(path,reader->get_subsong(n)));
+ p_out.add_item(ptr);
+ }
+
+ return p_out.get_count() > 0;
+ } catch(std::exception const &) {return false;}
+}
+
+file_move_helper::file_move_helper() {}
+file_move_helper::~file_move_helper() {}
+file_move_helper::file_move_helper(const file_move_helper & p_src) {*this = p_src;}
+
+bool file_move_helper::take_snapshot(const char * p_path,abort_callback & p_abort)
+{
+ in_metadb_sync blah;
+
+ m_source_handles.remove_all();
+ m_data.set_size(0);
+ if (!grab_items_by_path(m_source_handles,p_path,p_abort)) return false;
+ t_size n, m = m_source_handles.get_count();
+ m_data.set_size(m);
+ for(n=0;n<m;n++)
+ {
+ m_data[n].m_location = m_source_handles[n]->get_location();
+ m_data[n].m_have_info = m_source_handles[n]->get_info(m_data[n].m_info);
+ m_data[n].m_stats = m_source_handles[n]->get_filestats();
+
+ }
+ return true;
+}
+
+bool file_move_helper::on_moved(const char * p_path,abort_callback & p_abort)
+{
+ bool ret;
+ file_move_callback_manager cb;
+ ret = on_moved(p_path,p_abort,cb);
+ cb.run_callback();
+ return ret;
+}
+
+bool file_move_helper::on_copied(const char * p_path,abort_callback & p_abort)
+{
+ bool ret;
+ file_move_callback_manager cb;
+ ret = on_copied(p_path,p_abort,cb);
+ cb.run_callback();
+ return ret;
+}
+
+bool file_move_helper::on_moved(const char * p_path,abort_callback & p_abort,file_move_callback_manager & p_cb)
+{
+ file_path_canonical path(p_path);
+ if (m_data.get_size() == 0) return false;
+ if (!metadb::path_compare(path,get_source_path())) return true;
+
+ metadb_handle_list items;
+ make_new_item_list(items,path,p_cb);
+
+
+ /*if (p_update_db)*/
+ p_cb.on_library_add_items(items);
+ p_cb.on_library_remove_items(m_source_handles);
+
+ p_cb.on_moved(pfc::list_single_ref_t<const char*>(get_source_path()),pfc::list_single_ref_t<const char*>(path));
+
+ return true;
+}
+
+bool file_move_helper::on_copied(const char * p_path,abort_callback & p_abort,file_move_callback_manager & p_cb)
+{
+ file_path_canonical path(p_path);
+ if (m_data.get_size() == 0) return false;
+ if (!metadb::path_compare(path,get_source_path())) return true;
+ metadb_handle_list items;
+ make_new_item_list(items,path,p_cb);
+ /*if (p_update_db)*/ p_cb.on_library_add_items(items);
+ p_cb.on_copied(pfc::list_single_ref_t<const char*>(get_source_path()),pfc::list_single_ref_t<const char*>(path));
+ return true;
+}
+
+bool file_move_helper::g_on_deleted(const pfc::list_base_const_t<const char *> & p_files)
+{
+ file_operation_callback::g_on_files_deleted(p_files);
+ return true;
+}
+
+void file_move_helper::make_new_item_list(pfc::list_base_t<metadb_handle_ptr> & p_out,const char * p_new_path,file_move_callback_manager & p_cb)
+{
+ pfc::string8 new_path;
+ filesystem::g_get_canonical_path(p_new_path,new_path);
+
+ t_size n; const t_size m = m_data.get_size();
+ static_api_ptr_t<metadb> api;
+ pfc::array_t<metadb_handle_ptr> hint_handles;
+ pfc::array_t<const file_info*> hint_infos;
+ pfc::array_t<t_filestats> hint_stats;
+ hint_handles.set_size(m); hint_infos.set_size(m); hint_stats.set_size(m);
+ t_size hintptr = 0;
+ for(n=0;n<m;n++)
+ {
+ metadb_handle_ptr temp;
+ api->handle_create(temp,make_playable_location(new_path,m_data[n].m_location.get_subsong()));
+ if (m_data[n].m_have_info)
+ {
+ hint_handles[hintptr] = temp;
+ hint_infos[hintptr] = &m_data[n].m_info;
+ hint_stats[hintptr] = m_data[n].m_stats;
+
+ hintptr++;
+ }
+ p_out.add_item(temp);
+ }
+
+ if (hintptr > 0)
+ {
+ p_cb.on_hint(
+ pfc::list_const_array_t<metadb_handle_ptr,const pfc::array_t<metadb_handle_ptr> &>(hint_handles,hintptr),
+ pfc::list_const_array_t<const file_info *,const pfc::array_t<const file_info *> &>(hint_infos,hintptr),
+ pfc::list_const_array_t<t_filestats,const pfc::array_t<t_filestats> &>(hint_stats,hintptr)
+ );
+/*
+ static_api_ptr_t<metadb_io>()->hint_multi(
+ list_const_array_t<metadb_handle_ptr,const array_t<metadb_handle_ptr> &>(hint_handles,hintptr),
+ list_const_array_t<const file_info *,const array_t<const file_info *> &>(hint_infos,hintptr),
+ list_const_array_t<t_filestats,const array_t<t_filestats> &>(hint_stats,hintptr),
+ bit_array_false());*/
+ }
+
+}
+
+const char * file_move_helper::get_source_path() const
+{
+ return m_data.get_size() > 0 ? m_data[0].m_location.get_path() : 0;
+}
+
+t_size file_move_helper::g_filter_dead_files_sorted_make_mask(pfc::list_base_t<metadb_handle_ptr> & p_data,const pfc::list_base_const_t<const char*> & p_dead,bit_array_var & p_mask)
+{
+ t_size n, m = p_data.get_count();
+ t_size found = 0;
+ for(n=0;n<m;n++)
+ {
+ t_size dummy;
+ bool dead = p_dead.bsearch_t(metadb::path_compare,p_data.get_item(n)->get_path(),dummy);
+ if (dead) found++;
+ p_mask.set(n,dead);
+ }
+ return found;
+}
+
+t_size file_move_helper::g_filter_dead_files_sorted(pfc::list_base_t<metadb_handle_ptr> & p_data,const pfc::list_base_const_t<const char*> & p_dead)
+{
+ bit_array_bittable mask(p_data.get_count());
+ t_size found = g_filter_dead_files_sorted_make_mask(p_data,p_dead,mask);
+ if (found > 0) p_data.remove_mask(mask);
+ return found;
+}
+
+t_size file_move_helper::g_filter_dead_files(pfc::list_base_t<metadb_handle_ptr> & p_data,const pfc::list_base_const_t<const char*> & p_dead)
+{
+ pfc::ptr_list_t<const char> temp;
+ temp.add_items(p_dead);
+ temp.sort_t(metadb::path_compare);
+ return g_filter_dead_files_sorted(p_data,temp);
+}
+
+
+void file_move_callback_manager::on_library_add_items(const pfc::list_base_const_t<metadb_handle_ptr> & p_data)
+{
+ m_added.add_items(p_data);
+}
+
+void file_move_callback_manager::on_library_remove_items(const pfc::list_base_const_t<metadb_handle_ptr> & p_data)
+{
+ m_removed.add_items(p_data);
+}
+
+void file_move_callback_manager::on_moved(const pfc::string_list_const & p_from,const pfc::string_list_const & p_to)
+{
+ assert(p_from.get_count() == p_to.get_count());
+ m_move_from += p_from;
+ m_move_to += p_to;
+}
+
+void file_move_callback_manager::on_copied(const pfc::string_list_const & p_from,const pfc::string_list_const & p_to)
+{
+ assert(p_from.get_count() == p_to.get_count());
+ m_copy_from += p_from;
+ m_copy_to += p_to;
+}
+
+void file_move_callback_manager::on_hint(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,const pfc::list_base_const_t<const file_info*> & p_infos,const pfc::list_base_const_t<t_filestats> & p_stats)
+{
+ m_hint_handles.add_items(p_list);
+ m_hint_stats.add_items(p_stats);
+
+ {
+ t_size old_count = m_hint_infos.get_count(), delta = p_infos.get_count();
+ m_hint_infos.set_count(old_count + delta);
+ for(t_size n=0;n<delta;n++)
+ m_hint_infos[old_count+n] = *p_infos[n];
+ }
+
+/* metadb_handle_list m_hint_handles;
+ list_t<file_info_impl_const> m_hint_infos;
+ list_t<t_filestats> m_hint_stats;*/
+
+}
+
+
+void file_move_callback_manager::run_callback()
+{
+ if (m_hint_handles.get_count() > 0)
+ {
+ static_api_ptr_t<metadb_io>()->hint_multi(
+ m_hint_handles,
+ pfc::ptr_list_const_array_t<const file_info,const pfc::list_t<file_info_const_impl> &>(m_hint_infos,m_hint_infos.get_count()),
+ m_hint_stats,
+ bit_array_false());
+
+ m_hint_infos.remove_all();
+ m_hint_stats.remove_all();
+
+ //trick to make sure values don't get wiped
+ //m_hint_handles.remove_all();
+
+ }
+
+ assert(m_copy_from.get_count() == m_copy_to.get_count());
+ assert(m_move_from.get_count() == m_move_to.get_count());
+
+ static_api_ptr_t<library_manager> api_library_manager;
+
+ if (m_added.get_count() > 0)
+ {
+ api_library_manager->add_items(m_added);
+ m_added.remove_all();
+ }
+
+ if (m_removed.get_count())
+ {
+ api_library_manager->remove_items(m_removed);
+ m_removed.remove_all();
+ }
+
+ if (m_copy_from.get_count() > 0)
+ {
+ file_operation_callback::g_on_files_copied(m_copy_from,m_copy_to);
+ m_copy_from.remove_all();
+ m_copy_to.remove_all();
+ }
+
+ if (m_move_from.get_count() > 0)
+ {
+ file_operation_callback::g_on_files_moved(m_move_from,m_move_to);
+ m_move_from.remove_all();
+ m_move_to.remove_all();
+ }
+
+ //trick to make sure values don't get wiped
+ m_hint_handles.remove_all();
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_move_helper.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_move_helper.h
new file mode 100644
index 0000000..7ce34ae
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_move_helper.h
@@ -0,0 +1,60 @@
+class file_move_callback_manager
+{
+public:
+ void on_library_add_items(const pfc::list_base_const_t<metadb_handle_ptr> & p_data);
+ void on_library_remove_items(const pfc::list_base_const_t<metadb_handle_ptr> & p_data);
+
+ void on_moved(const pfc::string_list_const & p_from,const pfc::string_list_const & p_to);
+ void on_copied(const pfc::string_list_const & p_from,const pfc::string_list_const & p_to);
+
+ void on_hint(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,const pfc::list_base_const_t<const file_info*> & p_infos,const pfc::list_base_const_t<t_filestats> & p_stats);
+
+ void run_callback();
+private:
+ metadb_handle_list m_removed;
+ metadb_handle_list m_added;
+
+ pfc::string_list_impl m_copy_from,m_copy_to;
+ pfc::string_list_impl m_move_from,m_move_to;
+
+ metadb_handle_list m_hint_handles;
+ pfc::list_t<file_info_const_impl> m_hint_infos;
+ pfc::list_t<t_filestats> m_hint_stats;
+};
+
+class file_move_helper
+{
+public:
+ file_move_helper();
+ ~file_move_helper();
+ file_move_helper(const file_move_helper & p_src);
+ bool take_snapshot(const char * p_path,abort_callback & p_abort);
+ bool on_moved(const char * p_path,abort_callback & p_abort);
+ bool on_copied(const char * p_path,abort_callback & p_abort);
+ bool on_moved(const char * p_path,abort_callback & p_abort,file_move_callback_manager & p_cb);
+ bool on_copied(const char * p_path,abort_callback & p_abort,file_move_callback_manager & p_cb);
+
+ static bool g_on_deleted(const pfc::list_base_const_t<const char *> & p_files);
+
+ static t_size g_filter_dead_files_sorted_make_mask(pfc::list_base_t<metadb_handle_ptr> & p_data,const pfc::list_base_const_t<const char*> & p_dead,bit_array_var & p_mask);
+ static t_size g_filter_dead_files_sorted(pfc::list_base_t<metadb_handle_ptr> & p_data,const pfc::list_base_const_t<const char*> & p_dead);
+ static t_size g_filter_dead_files(pfc::list_base_t<metadb_handle_ptr> & p_data,const pfc::list_base_const_t<const char*> & p_dead);
+
+private:
+
+ struct t_entry
+ {
+ playable_location_impl m_location;
+ file_info_i m_info;
+ t_filestats m_stats;
+ bool m_have_info;
+ };
+
+ metadb_handle_list m_source_handles;
+
+ pfc::array_t<t_entry> m_data;
+
+ const char * get_source_path() const;
+
+ void make_new_item_list(pfc::list_base_t<metadb_handle_ptr> & p_out,const char * p_path,file_move_callback_manager & p_cb);
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_win32_wrapper.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_win32_wrapper.h
new file mode 100644
index 0000000..5d11188
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_win32_wrapper.h
@@ -0,0 +1,183 @@
+namespace file_win32_helpers {
+ static t_filesize get_size(HANDLE p_handle) {
+ union {
+ t_uint64 val64;
+ t_uint32 val32[2];
+ } u;
+
+ u.val64 = 0;
+ SetLastError(NO_ERROR);
+ u.val32[0] = GetFileSize(p_handle,reinterpret_cast<DWORD*>(&u.val32[1]));
+ if (GetLastError()!=NO_ERROR) exception_io_from_win32(GetLastError());
+ return u.val64;
+ }
+ static void seek(HANDLE p_handle,t_sfilesize p_position,file::t_seek_mode p_mode) {
+ union {
+ t_int64 temp64;
+ struct {
+ DWORD temp_lo;
+ LONG temp_hi;
+ };
+ };
+
+ temp64 = p_position;
+ SetLastError(ERROR_SUCCESS);
+ temp_lo = SetFilePointer(p_handle,temp_lo,&temp_hi,(DWORD)p_mode);
+ if (GetLastError() != ERROR_SUCCESS) exception_io_from_win32(GetLastError());
+ }
+}
+
+template<bool p_seekable,bool p_writeable>
+class file_win32_wrapper_t : public file {
+public:
+ file_win32_wrapper_t(HANDLE p_handle) : m_handle(p_handle), m_position(0)
+ {
+ }
+
+ static service_ptr_t<file> g_CreateFile(const char * p_path,DWORD p_access,DWORD p_sharemode,LPSECURITY_ATTRIBUTES p_security_attributes,DWORD p_createmode,DWORD p_flags,HANDLE p_template) {
+ SetLastError(NO_ERROR);
+ HANDLE handle = uCreateFile(p_path,p_access,p_sharemode,p_security_attributes,p_createmode,p_flags,p_template);
+ if (handle == INVALID_HANDLE_VALUE) exception_io_from_win32(GetLastError());
+ try {
+ return g_create_from_handle(handle);
+ } catch(...) {CloseHandle(handle); throw;}
+ }
+
+ static service_ptr_t<file> g_create_from_handle(HANDLE p_handle) {
+ return new service_impl_t<file_win32_wrapper_t<p_seekable,p_writeable> >(p_handle);
+ }
+
+
+ void reopen(abort_callback & p_abort) {seek(0,p_abort);}
+
+ void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ if (!p_writeable) throw exception_io_denied();
+
+ pfc::static_assert_t< (sizeof(t_size) >= sizeof(DWORD)) >();
+
+ t_size bytes_written_total = 0;
+
+ if (sizeof(t_size) == sizeof(DWORD)) {
+ p_abort.check_e();
+ DWORD bytes_written = 0;
+ SetLastError(ERROR_SUCCESS);
+ if (!WriteFile(m_handle,p_buffer,(DWORD)p_bytes,&bytes_written,0)) exception_io_from_win32(GetLastError());
+ if (bytes_written != p_bytes) throw exception_io("Write failure");
+ bytes_written_total = bytes_written;
+ m_position += bytes_written;
+ } else {
+ while(bytes_written_total < p_bytes) {
+ p_abort.check_e();
+ DWORD bytes_written = 0;
+ DWORD delta = (DWORD) pfc::min_t<t_size>(p_bytes - bytes_written_total, 0x80000000);
+ SetLastError(ERROR_SUCCESS);
+ if (!WriteFile(m_handle,(const t_uint8*)p_buffer + bytes_written_total,delta,&bytes_written,0)) exception_io_from_win32(GetLastError());
+ if (bytes_written != delta) throw exception_io("Write failure");
+ bytes_written_total += bytes_written;
+ m_position += bytes_written;
+ }
+ }
+ }
+
+ t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ pfc::static_assert_t< (sizeof(t_size) >= sizeof(DWORD)) >();
+
+ t_size bytes_read_total = 0;
+ if (sizeof(t_size) == sizeof(DWORD)) {
+ p_abort.check_e();
+ DWORD bytes_read = 0;
+ SetLastError(ERROR_SUCCESS);
+ if (!ReadFile(m_handle,p_buffer,pfc::downcast_guarded<DWORD>(p_bytes),&bytes_read,0)) exception_io_from_win32(GetLastError());
+ bytes_read_total = bytes_read;
+ m_position += bytes_read;
+ } else {
+ while(bytes_read_total < p_bytes) {
+ p_abort.check_e();
+ DWORD bytes_read = 0;
+ DWORD delta = (DWORD) pfc::min_t<t_size>(p_bytes - bytes_read_total, 0x80000000);
+ SetLastError(ERROR_SUCCESS);
+ if (!ReadFile(m_handle,(t_uint8*)p_buffer + bytes_read_total,delta,&bytes_read,0)) exception_io_from_win32(GetLastError());
+ bytes_read_total += bytes_read;
+ m_position += bytes_read;
+ if (bytes_read != delta) break;
+ }
+ }
+ return bytes_read_total;
+ }
+
+
+ t_filesize get_size(abort_callback & p_abort) {
+ p_abort.check_e();
+ return file_win32_helpers::get_size(m_handle);
+ }
+
+ t_filesize get_position(abort_callback & p_abort) {
+ p_abort.check_e();
+ return m_position;
+ }
+
+ void resize(t_filesize p_size,abort_callback & p_abort) {
+ if (!p_writeable) throw exception_io_denied();
+ p_abort.check_e();
+ if (m_position != p_size) {
+ file_win32_helpers::seek(m_handle,p_size,file::seek_from_beginning);
+ }
+ SetLastError(ERROR_SUCCESS);
+ if (!SetEndOfFile(m_handle)) {
+ DWORD code = GetLastError();
+ if (m_position != p_size) try {file_win32_helpers::seek(m_handle,m_position,file::seek_from_beginning);} catch(...) {}
+ exception_io_from_win32(code);
+ }
+ if (m_position > p_size) m_position = p_size;
+ if (m_position != p_size) file_win32_helpers::seek(m_handle,m_position,file::seek_from_beginning);
+ }
+
+#if 0
+ void set_eof(abort_callback & p_abort) {
+ if (!p_writeable) throw exception_io_denied();
+ p_abort.check_e();
+
+ SetLastError(ERROR_SUCCESS);
+ if (!SetEndOfFile(m_handle)) exception_io_from_win32(GetLastError());
+ }
+#endif
+
+ void seek(t_filesize p_position,abort_callback & p_abort) {
+ if (!p_seekable) throw exception_io_object_not_seekable();
+ p_abort.check_e();
+ if (p_position > file_win32_helpers::get_size(m_handle)) throw exception_io_seek_out_of_range();
+ file_win32_helpers::seek(m_handle,p_position,file::seek_from_beginning);
+ m_position = p_position;
+ //return seek_ex((t_sfilesize)p_position,file::seek_from_beginning,p_abort);
+ }
+#if 0
+ void seek_ex(t_sfilesize p_position,file::t_seek_mode p_mode,abort_callback & p_abort) {
+ if (!p_seekable) throw exception_io_object_not_seekable();
+ p_abort.check_e();
+
+ file_win32_helpers::seek(m_handle,p_position,p_mode);
+
+ m_position = (t_filesize) temp64;
+ }
+#endif
+
+ bool can_seek() {return p_seekable;}
+ bool get_content_type(pfc::string_base & out) {return false;}
+ bool is_in_memory() {return false;}
+ void on_idle(abort_callback & p_abort) {p_abort.check_e();}
+
+ t_filetimestamp get_timestamp(abort_callback & p_abort) {
+ p_abort.check_e();
+ FlushFileBuffers(m_handle);
+ SetLastError(ERROR_SUCCESS);
+ t_filetimestamp temp;
+ if (!GetFileTime(m_handle,0,0,(FILETIME*)&temp)) exception_io_from_win32(GetLastError());
+ return temp;
+ }
+
+ bool is_remote() {return false;}
+ ~file_win32_wrapper_t() {CloseHandle(m_handle);}
+private:
+ HANDLE m_handle;
+ t_filesize m_position;
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_wrapper_simple.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_wrapper_simple.cpp
new file mode 100644
index 0000000..79b61b1
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_wrapper_simple.cpp
@@ -0,0 +1,75 @@
+#include "stdafx.h"
+
+t_size file_wrapper_simple::read(void * p_buffer,t_size p_bytes) {
+ if (m_has_failed) return 0;
+ try {
+ return m_file->read(p_buffer,p_bytes,m_abort);
+ } catch(std::exception const &) {
+ m_has_failed = true;
+ return 0;
+ }
+}
+
+t_size file_wrapper_simple::write(const void * p_buffer,t_size p_bytes) {
+ if (m_has_failed) return 0;
+ try {
+ m_file->write(p_buffer,p_bytes,m_abort);
+ return p_bytes;
+ } catch(std::exception const &) {
+ m_has_failed = true;
+ return 0;
+ }
+}
+
+bool file_wrapper_simple::seek(t_filesize p_offset) {
+ if (m_has_failed) return false;
+ try {
+ m_file->seek(p_offset,m_abort);
+ return true;
+ } catch(std::exception const &) {
+ m_has_failed = true;
+ return false;
+ }
+}
+
+t_filesize file_wrapper_simple::get_position() {
+ if (m_has_failed) return filesize_invalid;
+ try {
+ return m_file->get_position(m_abort);
+ } catch(std::exception const &) {
+ m_has_failed = true;
+ return filesize_invalid;
+ }
+}
+
+bool file_wrapper_simple::truncate() {
+ if (m_has_failed) return false;
+ try {
+ m_file->set_eof(m_abort);
+ return true;
+ } catch(std::exception) {
+ m_has_failed = true;
+ return true;
+ }
+}
+
+
+t_filesize file_wrapper_simple::get_size() {
+ if (m_has_failed) return filesize_invalid;
+ try {
+ return m_file->get_size(m_abort);
+ } catch(std::exception const &) {
+ m_has_failed = true;
+ return filesize_invalid;
+ }
+}
+
+bool file_wrapper_simple::can_seek() {
+ if (m_has_failed) return false;
+ try {
+ return m_file->can_seek();
+ } catch(std::exception const &) {
+ m_has_failed = true;
+ return false;
+ }
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_wrapper_simple.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_wrapper_simple.h
new file mode 100644
index 0000000..6819d0d
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/file_wrapper_simple.h
@@ -0,0 +1,21 @@
+class file_wrapper_simple
+{
+public:
+ explicit file_wrapper_simple(const service_ptr_t<file> & p_file,abort_callback & p_abort) : m_file(p_file), m_abort(p_abort), m_has_failed(false) {}
+
+ inline bool has_failed() const {return m_has_failed;}
+ inline void reset_status() {m_has_failed = false;}
+
+
+ t_size read(void * p_buffer,t_size p_bytes);
+ t_size write(const void * p_buffer,t_size p_bytes);
+ bool seek(t_filesize p_offset);
+ t_filesize get_position();
+ t_filesize get_size();
+ bool can_seek();
+ bool truncate();
+private:
+ service_ptr_t<file> m_file;
+ abort_callback & m_abort;
+ bool m_has_failed;
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/foobar2000_sdk_helpers.vcproj b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/foobar2000_sdk_helpers.vcproj
new file mode 100644
index 0000000..fc7c089
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/foobar2000_sdk_helpers.vcproj
@@ -0,0 +1,884 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="foobar2000_sdk_helpers"
+ ProjectGUID="{EE47764E-A202-4F85-A767-ABDAB4AFF35F}"
+ RootNamespace="foobar2000_sdk_helpers"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="true"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="true"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x500"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="create_directory_helper.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\cue_creator.cpp"
+ >
+ </File>
+ <File
+ RelativePath="cue_parser.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\cue_parser_embedding.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\cuesheet_index_list.cpp"
+ >
+ </File>
+ <File
+ RelativePath="dialog_resize_helper.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="dropdown_helper.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="dynamic_bitrate_helper.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="file_info_const_impl.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="file_list_helper.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\file_move_helper.cpp"
+ >
+ </File>
+ <File
+ RelativePath="file_wrapper_simple.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\format_title_group.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\inplace_edit.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\input_helpers.cpp"
+ >
+ </File>
+ <File
+ RelativePath="listview_helper.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\metadb_io_hintlist.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mp3_utils.cpp"
+ >
+ </File>
+ <File
+ RelativePath="preload_info_helper.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="search_filter.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\seekabilizer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="StdAfx.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="stream_buffer_helper.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="text_file_loader.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="wildcard.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="win32_dialog.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\win32_misc.cpp"
+ >
+ </File>
+ <File
+ RelativePath="window_placement_helper.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath=".\bitreader_helper.h"
+ >
+ </File>
+ <File
+ RelativePath=".\cfg_guidlist.h"
+ >
+ </File>
+ <File
+ RelativePath=".\cfg_structlist.h"
+ >
+ </File>
+ <File
+ RelativePath="create_directory_helper.h"
+ >
+ </File>
+ <File
+ RelativePath=".\cue_creator.h"
+ >
+ </File>
+ <File
+ RelativePath="cue_parser.h"
+ >
+ </File>
+ <File
+ RelativePath=".\cuesheet_index_list.h"
+ >
+ </File>
+ <File
+ RelativePath="dialog_resize_helper.h"
+ >
+ </File>
+ <File
+ RelativePath="dropdown_helper.h"
+ >
+ </File>
+ <File
+ RelativePath="dynamic_bitrate_helper.h"
+ >
+ </File>
+ <File
+ RelativePath=".\file_cached.h"
+ >
+ </File>
+ <File
+ RelativePath="file_info_const_impl.h"
+ >
+ </File>
+ <File
+ RelativePath="file_list_helper.h"
+ >
+ </File>
+ <File
+ RelativePath=".\file_move_helper.h"
+ >
+ </File>
+ <File
+ RelativePath=".\file_win32_wrapper.h"
+ >
+ </File>
+ <File
+ RelativePath="file_wrapper_simple.h"
+ >
+ </File>
+ <File
+ RelativePath=".\format_title_group.h"
+ >
+ </File>
+ <File
+ RelativePath="helpers.h"
+ >
+ </File>
+ <File
+ RelativePath=".\inplace_edit.h"
+ >
+ </File>
+ <File
+ RelativePath=".\input_helpers.h"
+ >
+ </File>
+ <File
+ RelativePath="listview_helper.h"
+ >
+ </File>
+ <File
+ RelativePath=".\meta_table_builder.h"
+ >
+ </File>
+ <File
+ RelativePath=".\metadb_io_hintlist.h"
+ >
+ </File>
+ <File
+ RelativePath=".\mp3_utils.h"
+ >
+ </File>
+ <File
+ RelativePath="preload_info_helper.h"
+ >
+ </File>
+ <File
+ RelativePath="search_filter.h"
+ >
+ </File>
+ <File
+ RelativePath=".\seekabilizer.h"
+ >
+ </File>
+ <File
+ RelativePath="StdAfx.h"
+ >
+ </File>
+ <File
+ RelativePath="stream_buffer_helper.h"
+ >
+ </File>
+ <File
+ RelativePath=".\string_filter.h"
+ >
+ </File>
+ <File
+ RelativePath="text_file_loader.h"
+ >
+ </File>
+ <File
+ RelativePath="wildcard.h"
+ >
+ </File>
+ <File
+ RelativePath="win32_dialog.h"
+ >
+ </File>
+ <File
+ RelativePath=".\win32_misc.h"
+ >
+ </File>
+ <File
+ RelativePath="window_placement_helper.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/format_title_group.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/format_title_group.cpp
new file mode 100644
index 0000000..10e26d0
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/format_title_group.cpp
@@ -0,0 +1,63 @@
+#include "stdafx.h"
+
+namespace {
+ class titleformat_hook_impl : public titleformat_hook {
+ public:
+ titleformat_hook_impl(pfc::list_base_const_t<metadb_handle_ptr> const & p_items,titleformat_hook * p_hook) : m_hook(p_hook) {
+ m_infos.set_size(p_items.get_count());
+ for(t_size n = 0; n < p_items.get_count(); n++) {
+ if (p_items[n]->get_info_locked(m_infos[n])) m_infos[n] = NULL;
+ }
+ }
+
+ bool process_field(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,bool & p_found_flag) {
+ if (m_hook != NULL) {
+ if (m_hook->process_field(p_out,p_name,p_name_length,p_found_flag)) return true;
+ }
+ if (process_own_field(p_out,p_name,p_name_length,p_found_flag)) return true;
+ for(t_size n = 0; n < m_infos.get_size(); n++) {
+ if (m_infos[n] != NULL) {
+ if (titleformat_hook_impl_file_info(make_playable_location("",0),m_infos[n]).process_field(p_out,p_name,p_name_length,p_found_flag))
+ return true;
+ }
+ }
+ return false;
+ }
+ bool process_function(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,titleformat_hook_function_params * p_params,bool & p_found_flag) {
+ if (m_hook != NULL) {
+ if (m_hook->process_function(p_out,p_name,p_name_length,p_params,p_found_flag)) return true;
+ }
+ for(t_size n = 0; n < m_infos.get_size(); n++) {
+ if (m_infos[n] != NULL) {
+ if (titleformat_hook_impl_file_info(make_playable_location("",0),m_infos[n]).process_function(p_out,p_name,p_name_length,p_params,p_found_flag))
+ return true;
+ }
+ }
+ return false;
+ }
+ private:
+ bool process_own_field(titleformat_text_out * p_out,const char * p_name,t_size p_name_length,bool & p_found_flag) {
+ if (stricmp_utf8_ex(p_name,p_name_length,"multiitem",infinite) == 0) {
+ if (m_infos.get_size() > 1) {
+ p_out->write_int(titleformat_inputtypes::unknown,1);
+ p_found_flag = true;
+ } else {
+ p_out->write_int(titleformat_inputtypes::unknown,0);
+ p_found_flag = false;
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ in_metadb_sync m_lock;
+ titleformat_hook * m_hook;
+ pfc::array_t<const file_info*> m_infos;
+ };
+
+}
+
+void format_title_group(pfc::list_base_const_t<metadb_handle_ptr> const & p_items,titleformat_hook * p_hook,pfc::string_base & p_out,service_ptr_t<titleformat_object> p_script,titleformat_text_filter * p_filter) {
+ p_script->run(&titleformat_hook_impl(p_items,p_hook),p_out,p_filter);
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/format_title_group.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/format_title_group.h
new file mode 100644
index 0000000..a41bdbf
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/format_title_group.h
@@ -0,0 +1 @@
+void format_title_group(pfc::list_base_const_t<metadb_handle_ptr> const & p_list,titleformat_hook * p_hook,pfc::string_base & p_out,service_ptr_t<titleformat_object> p_script,titleformat_text_filter * p_filter); \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/helpers.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/helpers.h
new file mode 100644
index 0000000..c0c527a
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/helpers.h
@@ -0,0 +1,38 @@
+#ifndef _FOOBAR2000_SDK_HELPERS_H_
+#define _FOOBAR2000_SDK_HELPERS_H_
+
+#include "input_helpers.h"
+#include "create_directory_helper.h"
+#include "dialog_resize_helper.h"
+#include "dropdown_helper.h"
+#include "window_placement_helper.h"
+#include "win32_dialog.h"
+#include "wildcard.h"
+#include "cuesheet_index_list.h"
+#include "cue_creator.h"
+#include "cue_parser.h"
+#include "search_filter.h"
+#include "text_file_loader.h"
+#include "file_list_helper.h"
+#include "preload_info_helper.h"
+#include "listview_helper.h"
+#include "stream_buffer_helper.h"
+#include "file_info_const_impl.h"
+#include "file_wrapper_simple.h"
+#include "dynamic_bitrate_helper.h"
+#include "cfg_guidlist.h"
+#include "cfg_structlist.h"
+#include "file_win32_wrapper.h"
+#include "file_move_helper.h"
+#include "file_cached.h"
+#include "seekabilizer.h"
+#include "string_filter.h"
+#include "bitreader_helper.h"
+#include "mp3_utils.h"
+#include "win32_misc.h"
+#include "metadb_io_hintlist.h"
+#include "format_title_group.h"
+#include "inplace_edit.h"
+#include "meta_table_builder.h"
+
+#endif //_FOOBAR2000_SDK_HELPERS_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/inplace_edit.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/inplace_edit.cpp
new file mode 100644
index 0000000..f98276d
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/inplace_edit.cpp
@@ -0,0 +1,340 @@
+#include "stdafx.h"
+
+
+using namespace InPlaceEdit;
+
+
+static const TCHAR g_prop_instance[] = _T("{91154665-2B6A-42da-BB2A-A132EC20927F}");
+
+
+namespace {
+
+ static pfc::avltree_t<HWND> g_editboxes;
+ static HHOOK g_hook = NULL;
+
+ static LRESULT CALLBACK GMouseProc(int nCode,WPARAM wParam,LPARAM lParam) {
+ if (nCode >= 0) {
+ const MOUSEHOOKSTRUCT * mhs = (const MOUSEHOOKSTRUCT *) lParam;
+ switch(wParam) {
+ case WM_NCLBUTTONDOWN:
+ case WM_NCRBUTTONDOWN:
+ case WM_NCMBUTTONDOWN:
+ case WM_NCXBUTTONDOWN:
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_XBUTTONDOWN:
+ if (!g_editboxes.have_item(mhs->hwnd)) {
+ SetFocus(mhs->hwnd);
+ }
+ break;
+ }
+ }
+ return CallNextHookEx(g_hook,nCode,wParam,lParam);
+ }
+
+ void on_editbox_creation(HWND p_editbox) {
+ g_editboxes.add(p_editbox);
+ if (g_hook == NULL) {
+ g_hook = SetWindowsHookEx(WH_MOUSE,GMouseProc,NULL,GetCurrentThreadId());
+ }
+ }
+ void on_editbox_destruction(HWND p_editbox) {
+ g_editboxes.remove(p_editbox);
+ if (g_editboxes.get_count() == 0 && g_hook != NULL) {
+ UnhookWindowsHookEx(pfc::replace_null_t(g_hook));
+ }
+ }
+
+ enum {
+ MSG_COMPLETION = WM_USER,
+ MSG_DISABLE_EDITING,
+ };
+
+class InPlaceEditHook {
+public:
+ InPlaceEditHook(HWND p_wnd) : m_oldproc(NULL)
+ {
+ SetProp(p_wnd,g_prop_instance,reinterpret_cast<HANDLE>(this));
+ m_oldproc = uHookWindowProc(p_wnd,GEditHook);
+ on_editbox_creation(p_wnd);
+ }
+private:
+ static void ForwardCompletion(HWND p_mywnd,unsigned p_code) {
+ HWND owner = GetParent(p_mywnd);
+ SendMessage(owner,MSG_DISABLE_EDITING,0,0);
+ PostMessage(owner,MSG_COMPLETION,p_code,0);
+ EnableWindow(p_mywnd,FALSE);
+ }
+ ~InPlaceEditHook() {}
+ LRESULT EditHook(HWND p_wnd,UINT p_msg,WPARAM p_wp,LPARAM p_lp) {
+ switch(p_msg) {
+ case WM_GETDLGCODE:
+ return DLGC_WANTALLKEYS;
+ case WM_KILLFOCUS:
+ ForwardCompletion(p_wnd,KEditLostFocus);
+ return m_oldproc(p_wnd,p_msg,p_wp,p_lp);
+ case WM_CHAR:
+ switch(p_wp) {
+ case VK_RETURN:
+ if (!IsKeyPressed(VK_LCONTROL) && !IsKeyPressed(VK_RCONTROL)) {
+ ForwardCompletion(p_wnd,KEditEnter);
+ return 0;
+ }
+ break;
+ case VK_TAB:
+ ForwardCompletion(p_wnd,IsKeyPressed(VK_SHIFT) ? KEditShiftTab : KEditTab);
+ return 0;
+ case VK_ESCAPE:
+ ForwardCompletion(p_wnd,KEditAborted);
+ return 0;
+ }
+ return m_oldproc(p_wnd,p_msg,p_wp,p_lp);
+ case WM_DESTROY:
+ {
+ WNDPROC l_wndproc = m_oldproc;
+ uHookWindowProc(p_wnd,l_wndproc);
+ RemoveProp(p_wnd,g_prop_instance);
+ on_editbox_destruction(p_wnd);
+ try {delete this;} catch(...) {}
+ return l_wndproc(p_wnd,p_msg,p_wp,p_lp);
+ }
+ default:
+ return m_oldproc(p_wnd,p_msg,p_wp,p_lp);
+ }
+ }
+
+ static LRESULT CALLBACK GEditHook(HWND p_wnd,UINT p_msg,WPARAM p_wp,LPARAM p_lp) {
+ InPlaceEditHook * instance = reinterpret_cast<InPlaceEditHook*>( GetProp(p_wnd,g_prop_instance) );
+ if (instance == NULL) return DefWindowProc(p_wnd,p_msg,p_wp,p_lp);
+ return instance->EditHook(p_wnd,p_msg,p_wp,p_lp);
+ }
+
+ WNDPROC m_oldproc;
+};
+
+class InPlaceEditContainer {
+public:
+ InPlaceEditContainer(HWND p_parentwnd,const RECT & p_rect,unsigned p_flags,pfc::rcptr_t<pfc::string_base> p_content,completion_notify_ptr p_notify)
+ : m_content(p_content), m_notify(p_notify), m_completed(false), m_initialized(false), m_changed(false), m_disable_editing(false) {
+ {
+ static volatile unsigned increment;
+ TCHAR classname[64];
+ wsprintf(classname,_T("{54340C80-248C-4b8e-8CD4-D624A8E9377B}/%u"),++increment);
+ m_class_scope.toggle_on(0,GWndProc,0,sizeof(void*),NULL,NULL,NULL,classname,NULL);
+ }
+
+ HWND container, edit;
+
+
+ RECT rect_cropped;
+ {
+ RECT client;
+ SetLastError(0);
+ if (!GetClientRect(p_parentwnd,&client)) throw exception_win32(GetLastError());
+ IntersectRect(&rect_cropped,&client,&p_rect);
+ }
+ AdjustWindowRect(&rect_cropped,WS_BORDER|WS_CHILD,FALSE);
+
+ SetLastError(0);
+ container = CreateWindowEx(
+ 0,
+ (const TCHAR*) m_class_scope.get_class(),
+ _T(""),
+ WS_BORDER|WS_CHILD,
+ rect_cropped.left,rect_cropped.top,
+ rect_cropped.right-rect_cropped.left,rect_cropped.bottom-rect_cropped.top,
+ p_parentwnd,NULL,
+ core_api::get_my_instance(),reinterpret_cast<void*>(this));
+ if (container == NULL) throw exception_win32(GetLastError());
+
+ try {
+
+ RECT parent_client;
+ SetLastError(0);
+ if (!GetClientRect(container,&parent_client)) throw exception_win32(GetLastError());
+ SetLastError(0);
+ edit = CreateWindowEx(
+ /*WS_EX_STATICEDGE*/ 0,
+ WC_EDIT,TEXT(""),
+ ((p_flags & KFlagMultiLine) ? (WS_VSCROLL|ES_MULTILINE) : ES_AUTOHSCROLL) |
+ ((p_flags & KFlagReadOnly) ? ES_READONLY : 0) |
+ WS_CHILD|ES_LEFT|WS_VISIBLE,//parent is invisible now
+ 0,0,
+ parent_client.right,parent_client.bottom,
+ container,
+ (HMENU)ID_MYEDIT,
+ core_api::get_my_instance(),
+ 0);
+
+ if (edit == NULL) throw exception_win32(GetLastError());
+
+ SendMessage(edit,WM_SETFONT,SendMessage(p_parentwnd,WM_GETFONT,0,0),0);
+
+ uSetWindowText(edit,*m_content);
+ SendMessage(edit,EM_SETSEL,0,-1);
+ } catch(...) {
+ PostMessage(container,MSG_COMPLETION,InPlaceEdit::KEditAborted,0);
+ return;
+ }
+
+ try {
+ new InPlaceEditHook(edit);
+ } catch(...) {
+ PostMessage(container,MSG_COMPLETION,InPlaceEdit::KEditAborted,0);
+ return;
+ }
+
+ ShowWindow(container,SW_SHOW);
+ SetFocus(edit);
+
+ m_initialized = true;
+ }
+private:
+ enum {ID_MYEDIT = 666};
+
+ LRESULT WndProc(HWND p_wnd,UINT p_msg,WPARAM p_wp,LPARAM p_lp) {
+ switch(p_msg) {
+ case WM_MOUSEWHEEL:
+ return 0;
+ case MSG_DISABLE_EDITING:
+ ShowWindow(p_wnd,SW_HIDE);
+ UpdateWindow(GetParent(p_wnd));
+ m_disable_editing = true;
+ return 0;
+ case MSG_COMPLETION:
+ PFC_ASSERT(m_initialized);
+ if ((p_wp & KEditMaskReason) != KEditLostFocus) {
+ SetFocus(GetParent(p_wnd));
+ }
+ OnCompletion(p_wp);
+ DestroyWindow(p_wnd);
+ return 0;
+ case WM_COMMAND:
+ switch(p_wp) {
+ case (EN_CHANGE << 16) | ID_MYEDIT:
+ if (m_initialized && !m_disable_editing) {
+ uGetDlgItemText(p_wnd,ID_MYEDIT,*m_content);
+ m_changed = true;
+ }
+ return 0;
+ default:
+ return 0;
+ }
+
+ case WM_DESTROY:
+ try {delete this;}catch(...){}
+ SetWindowLongPtr(p_wnd,0,NULL);
+ return DefWindowProc(p_wnd,p_msg,p_wp,p_lp);
+ default:
+ return DefWindowProc(p_wnd,p_msg,p_wp,p_lp);
+ }
+ }
+ static LRESULT CALLBACK GWndProc(HWND p_wnd,UINT p_msg,WPARAM p_wp,LPARAM p_lp) {
+ if (p_msg == WM_CREATE) {
+ const CREATESTRUCT * ptr = reinterpret_cast<const CREATESTRUCT*>(p_lp);
+ SetWindowLongPtr(p_wnd,0,reinterpret_cast<LONG_PTR>(ptr->lpCreateParams));
+ }
+
+ InPlaceEditContainer * instance = reinterpret_cast<InPlaceEditContainer*>(GetWindowLongPtr(p_wnd,0));
+ if (instance != NULL) {
+ return instance->WndProc(p_wnd,p_msg,p_wp,p_lp);
+ } else {
+ return DefWindowProc(p_wnd,p_msg,p_wp,p_lp);
+ }
+ }
+
+ void OnCompletion(unsigned p_status) {
+ if (!m_completed) {
+ m_completed = true;
+ p_status &= KEditMaskReason;
+ unsigned code = p_status;
+ if (m_changed && p_status != KEditAborted) code |= KEditFlagContentChanged;
+ if (m_notify.is_valid()) m_notify->on_completion(code);
+ }
+ }
+
+ registerclass_scope_delayed m_class_scope;
+ pfc::rcptr_t<pfc::string_base> m_content;
+ completion_notify_ptr m_notify;
+ bool m_completed;
+ bool m_initialized, m_changed;
+ bool m_disable_editing;
+};
+
+}
+
+static void fail(completion_notify_ptr p_notify) {
+ completion_notify::g_signal_completion_async(p_notify,KEditAborted);
+}
+
+void InPlaceEdit::Start(HWND p_parentwnd,const RECT & p_rect,bool p_multiline,pfc::rcptr_t<pfc::string_base> p_content,completion_notify_ptr p_notify) {
+ StartEx(p_parentwnd,p_rect,p_multiline ? KFlagMultiLine : 0, p_content,p_notify);
+}
+
+void InPlaceEdit::Start_FromListView(HWND p_listview,unsigned p_item,unsigned p_subitem,unsigned p_linecount,pfc::rcptr_t<pfc::string_base> p_content,completion_notify_ptr p_notify) {
+ Start_FromListViewEx(p_listview,p_item,p_subitem,p_linecount,0,p_content,p_notify);
+}
+
+bool InPlaceEdit::TableEditAdvance(unsigned & p_item,unsigned & p_column, unsigned p_item_count,unsigned p_column_count, unsigned p_whathappened) {
+ if (p_item >= p_item_count || p_column >= p_column_count) return false;
+ int delta = 0;
+
+ switch(p_whathappened & KEditMaskReason) {
+ case KEditEnter:
+ delta = (int) p_column_count;
+ break;
+ case KEditTab:
+ delta = 1;
+ break;
+ case KEditShiftTab:
+ delta = -1;
+ break;
+ default:
+ return false;
+ }
+ while(delta > 0) {
+ p_column++;
+ if (p_column >= p_column_count) {
+ p_column = 0;
+ p_item++;
+ if (p_item >= p_item_count) return false;
+ }
+ delta--;
+ }
+ while(delta < 0) {
+ if (p_column == 0) {
+ if (p_item == 0) return false;
+ p_item--;
+ p_column = p_column_count;
+ }
+ p_column--;
+ delta++;
+ }
+ return true;
+}
+
+void InPlaceEdit::StartEx(HWND p_parentwnd,const RECT & p_rect,unsigned p_flags,pfc::rcptr_t<pfc::string_base> p_content,completion_notify_ptr p_notify) {
+ try {
+ new InPlaceEditContainer(p_parentwnd,p_rect,p_flags,p_content,p_notify);
+ } catch(...) {
+ fail(p_notify);
+ }
+}
+
+void InPlaceEdit::Start_FromListViewEx(HWND p_listview,unsigned p_item,unsigned p_subitem,unsigned p_linecount,unsigned p_flags,pfc::rcptr_t<pfc::string_base> p_content,completion_notify_ptr p_notify) {
+ try {
+ ListView_EnsureVisible(p_listview,p_item,FALSE);
+ RECT itemrect;
+ if (!ListView_GetSubItemRect(p_listview,p_item,p_subitem,LVIR_BOUNDS,&itemrect)) throw pfc::exception("ListView_GetSubItemRect failure");
+
+ const bool multiline = p_linecount > 1;
+ if (multiline) {
+ itemrect.bottom = itemrect.top + (itemrect.bottom - itemrect.top) * p_linecount;
+ }
+
+ StartEx(p_listview,itemrect,p_flags | (multiline ? KFlagMultiLine : 0),p_content,p_notify);
+ } catch(...) {
+ fail(p_notify);
+ }
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/inplace_edit.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/inplace_edit.h
new file mode 100644
index 0000000..e44b6ce
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/inplace_edit.h
@@ -0,0 +1,116 @@
+namespace InPlaceEdit {
+
+ enum {
+ KEditAborted = 0,
+ KEditTab,
+ KEditShiftTab,
+ KEditEnter,
+ KEditLostFocus,
+
+ KEditMaskReason = 0xFF,
+ KEditFlagContentChanged = 0x100,
+
+ KFlagReadOnly = 1 << 0,
+ KFlagMultiLine = 1 << 1,
+ };
+
+ void Start(HWND p_parentwnd,const RECT & p_rect,bool p_multiline,pfc::rcptr_t<pfc::string_base> p_content,completion_notify_ptr p_notify);
+
+ void StartEx(HWND p_parentwnd,const RECT & p_rect,unsigned p_flags,pfc::rcptr_t<pfc::string_base> p_content,completion_notify_ptr p_notify);
+
+ void Start_FromListView(HWND p_listview,unsigned p_item,unsigned p_subitem,unsigned p_linecount,pfc::rcptr_t<pfc::string_base> p_content,completion_notify_ptr p_notify);
+ void Start_FromListViewEx(HWND p_listview,unsigned p_item,unsigned p_subitem,unsigned p_linecount,unsigned p_flags,pfc::rcptr_t<pfc::string_base> p_content,completion_notify_ptr p_notify);
+
+ bool TableEditAdvance(unsigned & p_item,unsigned & p_column, unsigned p_item_count,unsigned p_column_count, unsigned p_whathappened);
+
+
+ class CTableEditHelper {
+ public:
+ void TableEdit_Start(HWND p_listview,unsigned p_item,unsigned p_column,unsigned p_itemcount,unsigned p_columncount,unsigned p_basecolumn,unsigned p_flags = 0) {
+ if (m_notify.is_valid()) return;
+ m_listview = p_listview;
+ m_item = p_item;
+ m_column = p_column;
+ m_itemcount = p_itemcount;
+ m_columncount = p_columncount;
+ m_basecolumn = p_basecolumn;
+ m_flags = p_flags;
+ __Start();
+ }
+
+ void TableEdit_Abort(bool p_forwardcontent) {
+ if (m_notify.is_valid()) {
+ m_notify->orphan();
+ m_notify.release();
+
+ if (p_forwardcontent) {
+ if (m_content.is_valid()) {
+ pfc::string8 temp(*m_content);
+ m_content.release();
+ TableEdit_SetItemText(m_item,m_column,temp);
+ }
+ } else {
+ m_content.release();
+ }
+ SetFocus(NULL);
+ }
+ }
+
+
+ bool TableEdit_IsActive() const {
+ return m_notify.is_valid();
+ }
+
+ virtual bool TableEdit_GetItemText(unsigned p_item,unsigned p_column,pfc::string_base & p_out,unsigned & p_linecount) {
+ listview_helper::get_item_text(m_listview,p_item,p_column + m_basecolumn,p_out);
+ p_linecount = pfc::is_multiline(p_out) ? 5 : 1;
+ return true;
+ }
+ virtual void TableEdit_SetItemText(unsigned p_item,unsigned p_column,const char * p_text) {
+ listview_helper::set_item_text(m_listview,p_item,p_column + m_basecolumn,p_text);
+ }
+
+ void on_task_completion(unsigned p_taskid,unsigned p_state) {
+ if (p_taskid == KTaskID) {
+ m_notify.release();
+ if (m_content.is_valid()) {
+ if (p_state & InPlaceEdit::KEditFlagContentChanged) {
+ TableEdit_SetItemText(m_item,m_column,*m_content);
+ }
+ m_content.release();
+ }
+ if (InPlaceEdit::TableEditAdvance(m_item,m_column,m_itemcount,m_columncount,p_state)) {
+ __Start();
+ }
+ }
+ }
+
+ ~CTableEditHelper() {
+ if (m_notify.is_valid()) {
+ m_notify->orphan();
+ m_notify.release();
+ }
+ }
+ protected:
+ HWND TableEdit_GetListView() const {return m_listview;}
+ private:
+ void __Start() {
+ listview_helper::select_single_item(m_listview,m_item);
+ m_content.new_t();
+ unsigned linecount = 1;
+ if (!TableEdit_GetItemText(m_item,m_column,*m_content,linecount)) return;
+ m_notify = completion_notify_create(this,KTaskID);
+ InPlaceEdit::Start_FromListViewEx(m_listview,m_item,m_column+m_basecolumn,linecount,m_flags,m_content,m_notify);
+ }
+ enum {
+ KTaskID = 0xc0ffee
+ };
+ HWND m_listview;
+ unsigned m_item,m_column;
+ unsigned m_itemcount,m_columncount,m_basecolumn;
+ unsigned m_flags;
+ pfc::rcptr_t<pfc::string8> m_content;
+ service_ptr_t<completion_notify_orphanable> m_notify;
+ };
+
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/input_helpers.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/input_helpers.cpp
new file mode 100644
index 0000000..d1f4a54
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/input_helpers.cpp
@@ -0,0 +1,363 @@
+#include "stdafx.h"
+
+void input_helper::open(service_ptr_t<file> p_filehint,metadb_handle_ptr p_location,unsigned p_flags,abort_callback & p_abort,bool p_from_redirect,bool p_skip_hints)
+{
+ open(p_filehint,p_location->get_location(),p_flags,p_abort,p_from_redirect,p_skip_hints);
+}
+
+static void process_fullbuffer(service_ptr_t<file> & p_file,const char * p_path,t_filesize p_fullbuffer,abort_callback & p_abort) {
+ if (p_fullbuffer > 0) {
+ if (p_file.is_empty()) {
+ service_ptr_t<filesystem> fs;
+ if (filesystem::g_get_interface(fs,p_path)) {
+ fs->open(p_file,p_path,filesystem::open_mode_read,p_abort);
+ }
+ }
+
+ if (p_file.is_valid()) {
+ t_filesize size = p_file->get_size(p_abort);
+ if (size != filesize_invalid && size <= p_fullbuffer) {
+ service_ptr_t<file> l_file_buffered;
+ if (reader_membuffer_mirror::g_create(l_file_buffered,p_file,p_abort)) {
+ p_file = l_file_buffered;
+ }
+ }
+ }
+ }
+}
+
+void input_helper::open(service_ptr_t<file> p_filehint,const playable_location & p_location,unsigned p_flags,abort_callback & p_abort,bool p_from_redirect,bool p_skip_hints) {
+ p_abort.check();
+
+ if (m_input.is_empty() || metadb::path_compare(p_location.get_path(),m_path) != 0)
+ {
+ m_input.release();
+
+ service_ptr_t<file> l_file = p_filehint;
+ process_fullbuffer(l_file,p_location.get_path(),m_fullbuffer,p_abort);
+
+ TRACK_CODE("input_entry::g_open_for_decoding",
+ input_entry::g_open_for_decoding(m_input,l_file,p_location.get_path(),p_abort,p_from_redirect)
+ );
+
+
+ if (!p_skip_hints) {
+ try {
+ static_api_ptr_t<metadb_io>()->hint_reader(m_input.get_ptr(),p_location.get_path(),p_abort);
+ } catch(exception_io_data) {
+ //don't fail to decode when this barfs
+ m_input.release();
+ if (l_file.is_valid()) l_file->reopen(p_abort);
+ TRACK_CODE("input_entry::g_open_for_decoding",
+ input_entry::g_open_for_decoding(m_input,l_file,p_location.get_path(),p_abort,p_from_redirect)
+ );
+ }
+ }
+
+ m_path = p_location.get_path();
+ }
+
+ TRACK_CODE("input_decoder::initialize",m_input->initialize(p_location.get_subsong_index(),p_flags,p_abort));
+}
+
+
+void input_helper::close() {
+ m_input.release();
+}
+
+bool input_helper::is_open() {
+ return m_input.is_valid();
+}
+
+bool input_helper::run(audio_chunk & p_chunk,abort_callback & p_abort)
+{
+ if (m_input.is_valid()) {
+ TRACK_CODE("input_decoder::run",return m_input->run(p_chunk,p_abort));
+ } else {
+ throw pfc::exception_bug_check();
+ }
+}
+
+void input_helper::seek(double seconds,abort_callback & p_abort)
+{
+ if (m_input.is_valid()) {
+ TRACK_CODE("input_decoder::seek",m_input->seek(seconds,p_abort));
+ } else {
+ throw pfc::exception_bug_check();
+ }
+}
+
+bool input_helper::can_seek() {
+ if (m_input.is_valid()) {
+ return m_input->can_seek();
+ } else {
+ throw pfc::exception_bug_check();
+ }
+}
+
+void input_helper::set_full_buffer(t_filesize val) {
+ m_fullbuffer = val;
+}
+void input_helper::on_idle(abort_callback & p_abort) {
+ if (m_input.is_valid()) {
+ TRACK_CODE("input_decoder::on_idle",m_input->on_idle(p_abort));
+ }
+}
+
+bool input_helper::get_dynamic_info(file_info & p_out,double & p_timestamp_delta) {
+ if (m_input.is_valid()) {
+ TRACK_CODE("input_decoder::get_dynamic_info",return m_input->get_dynamic_info(p_out,p_timestamp_delta));
+ } else {
+ throw pfc::exception_bug_check();
+ }
+}
+
+bool input_helper::get_dynamic_info_track(file_info & p_out,double & p_timestamp_delta) {
+ if (m_input.is_valid()) {
+ TRACK_CODE("input_decoder::get_dynamic_info_track",return m_input->get_dynamic_info_track(p_out,p_timestamp_delta));
+ } else {
+ throw pfc::exception_bug_check();
+ }
+}
+
+void input_helper::get_info(t_uint32 p_subsong,file_info & p_info,abort_callback & p_abort) {
+ if (m_input.is_valid()) {
+ TRACK_CODE("input_decoder::get_info",m_input->get_info(p_subsong,p_info,p_abort));
+ } else {
+ throw pfc::exception_bug_check();
+ }
+}
+
+const char * input_helper::get_path() const {
+ return m_path;
+}
+
+
+input_helper::input_helper() : m_fullbuffer(0)
+{
+}
+
+
+void input_helper::g_get_info(const playable_location & p_location,file_info & p_info,abort_callback & p_abort,bool p_from_redirect) {
+ service_ptr_t<input_info_reader> instance;
+ input_entry::g_open_for_info_read(instance,0,p_location.get_path(),p_abort,p_from_redirect);
+ instance->get_info(p_location.get_subsong_index(),p_info,p_abort);
+}
+
+void input_helper::g_set_info(const playable_location & p_location,file_info & p_info,abort_callback & p_abort,bool p_from_redirect) {
+ service_ptr_t<input_info_writer> instance;
+ input_entry::g_open_for_info_write(instance,0,p_location.get_path(),p_abort,p_from_redirect);
+ instance->set_info(p_location.get_subsong_index(),p_info,p_abort);
+ instance->commit(p_abort);
+}
+
+
+bool dead_item_filter::run(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,bit_array_var & p_mask) {
+ file_list_helper::file_list_from_metadb_handle_list path_list;
+ path_list.init_from_list(p_list);
+ metadb_handle_list valid_handles;
+ static_api_ptr_t<metadb> l_metadb;
+ for(t_size pathidx=0;pathidx<path_list.get_count();pathidx++)
+ {
+ if (is_aborting()) return false;
+ on_progress(pathidx,path_list.get_count());
+
+ const char * path = path_list[pathidx];
+
+ if (filesystem::g_is_remote_safe(path)) {
+ metadb_handle_ptr temp;
+ l_metadb->handle_create(temp,make_playable_location(path,0));
+ valid_handles.add_item(temp);
+ } else {
+ try {
+ service_ptr_t<input_info_reader> reader;
+
+ input_entry::g_open_for_info_read(reader,0,path,*this);
+ t_uint32 count = reader->get_subsong_count();
+ for(t_uint32 n=0;n<count && !is_aborting();n++) {
+ metadb_handle_ptr ptr;
+ t_uint32 index = reader->get_subsong(n);
+ l_metadb->handle_create(ptr,make_playable_location(path,index));
+ valid_handles.add_item(ptr);
+ }
+ } catch(...) {}
+ }
+ }
+
+ if (is_aborting()) return false;
+
+ valid_handles.sort_by_pointer();
+ for(t_size listidx=0;listidx<p_list.get_count();listidx++) {
+ bool dead = valid_handles.bsearch_by_pointer(p_list[listidx]) == infinite;
+ if (dead) console::formatter() << "Dead item: " << p_list[listidx];
+ p_mask.set(listidx,dead);
+ }
+ return !is_aborting();
+}
+
+namespace {
+
+class dead_item_filter_impl_simple : public dead_item_filter
+{
+public:
+ inline dead_item_filter_impl_simple(abort_callback & p_abort) : m_abort(p_abort) {}
+ bool is_aborting() const {return m_abort.is_aborting();}
+ abort_callback_event get_abort_event() const {return m_abort.get_abort_event();}
+ void on_progress(t_size p_position,t_size p_total) {}
+private:
+ abort_callback & m_abort;
+};
+
+}
+
+bool input_helper::g_mark_dead(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,bit_array_var & p_mask,abort_callback & p_abort)
+{
+ dead_item_filter_impl_simple filter(p_abort);
+ return filter.run(p_list,p_mask);
+}
+
+void input_info_read_helper::open(const char * p_path,abort_callback & p_abort) {
+ if (m_input.is_empty() || metadb::path_compare(m_path,p_path) != 0)
+ {
+ TRACK_CODE("input_entry::g_open_for_info_read",input_entry::g_open_for_info_read(m_input,0,p_path,p_abort));
+
+ m_path = p_path;
+ }
+}
+
+void input_info_read_helper::get_info(const playable_location & p_location,file_info & p_info,t_filestats & p_stats,abort_callback & p_abort) {
+ open(p_location.get_path(),p_abort);
+
+ TRACK_CODE("input_info_reader::get_file_stats",p_stats = m_input->get_file_stats(p_abort));
+
+ TRACK_CODE("input_info_reader::get_info",m_input->get_info(p_location.get_subsong_index(),p_info,p_abort));
+}
+
+void input_info_read_helper::get_info_check(const playable_location & p_location,file_info & p_info,t_filestats & p_stats,bool & p_reloaded,abort_callback & p_abort) {
+ open(p_location.get_path(),p_abort);
+ t_filestats newstats;
+ TRACK_CODE("input_info_reader::get_file_stats",newstats = m_input->get_file_stats(p_abort));
+ if (metadb_handle::g_should_reload(p_stats,newstats,true)) {
+ p_stats = newstats;
+ TRACK_CODE("input_info_reader::get_info",m_input->get_info(p_location.get_subsong_index(),p_info,p_abort));
+ p_reloaded = true;
+ } else {
+ p_reloaded = false;
+ }
+}
+
+
+
+
+
+
+void input_helper_cue::open(service_ptr_t<file> p_filehint,const playable_location & p_location,unsigned p_flags,abort_callback & p_abort,double p_start,double p_length) {
+ p_abort.check();
+
+ m_start = p_start;
+ m_position = 0;
+ m_dynamic_info_trigger = false;
+ m_dynamic_info_track_trigger = false;
+
+ m_input.open(p_filehint,p_location,p_flags,p_abort,true,true);
+
+ if (!m_input.can_seek()) throw exception_io_object_not_seekable();
+
+ if (m_start > 0) {
+ m_input.seek(m_start,p_abort);
+ }
+
+ if (p_length > 0) {
+ m_length = p_length;
+ } else {
+ file_info_impl temp;
+ m_input.get_info(0,temp,p_abort);
+ double ref_length = temp.get_length();
+ if (ref_length <= 0) throw exception_io_data();
+ m_length = ref_length - m_start + p_length /* negative or zero */;
+ if (m_length <= 0) throw exception_io_data();
+ }
+}
+
+void input_helper_cue::close() {m_input.close();}
+bool input_helper_cue::is_open() {return m_input.is_open();}
+
+bool input_helper_cue::run(audio_chunk & p_chunk,abort_callback & p_abort) {
+ p_abort.check();
+
+
+ if (m_length > 0) {
+ if (m_position >= m_length) return false;
+
+ m_dynamic_info_trigger = true;
+ m_dynamic_info_track_trigger = true;
+
+ if (!m_input.run(p_chunk,p_abort)) return false;
+
+ t_uint64 max = (t_uint64) audio_math::time_to_samples(m_length - m_position, p_chunk.get_sample_rate());
+ if (max == 0)
+ {//handle rounding accidents, this normally shouldn't trigger
+ m_position = m_length;
+ return false;
+ }
+
+ t_size samples = p_chunk.get_sample_count();
+ if ((t_uint64)samples > max)
+ {
+ p_chunk.set_sample_count((unsigned)max);
+ m_position = m_length;
+ }
+ else
+ {
+ m_position += p_chunk.get_duration();
+ }
+ return true;
+ }
+ else
+ {
+ if (!m_input.run(p_chunk,p_abort)) return false;
+ m_position += p_chunk.get_duration();
+ return true;
+ }
+}
+
+void input_helper_cue::seek(double p_seconds,abort_callback & p_abort)
+{
+ m_dynamic_info_trigger = false;
+ m_dynamic_info_track_trigger = false;
+ if (m_length <= 0 || p_seconds < m_length) {
+ m_input.seek(p_seconds + m_start,p_abort);
+ m_position = p_seconds;
+ } else {
+ m_position = m_length;
+ }
+}
+
+bool input_helper_cue::can_seek() {return true;}
+void input_helper_cue::set_full_buffer(t_filesize val) {m_input.set_full_buffer(val);}
+
+void input_helper_cue::on_idle(abort_callback & p_abort) {m_input.on_idle(p_abort);}
+
+bool input_helper_cue::get_dynamic_info(file_info & p_out,double & p_timestamp_delta) {
+ if (m_dynamic_info_trigger) {
+ m_dynamic_info_trigger = false;
+ return m_input.get_dynamic_info(p_out,p_timestamp_delta);
+ } else {
+ return false;
+ }
+}
+
+bool input_helper_cue::get_dynamic_info_track(file_info & p_out,double & p_timestamp_delta) {
+ if (m_dynamic_info_track_trigger) {
+ m_dynamic_info_track_trigger = false;
+ return m_input.get_dynamic_info_track(p_out,p_timestamp_delta);
+ } else {
+ return false;
+ }
+}
+
+const char * input_helper_cue::get_path() const {return m_input.get_path();}
+
+void input_helper_cue::get_info(t_uint32 p_subsong,file_info & p_info,abort_callback & p_abort) {m_input.get_info(p_subsong,p_info,p_abort);}
+
+
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/input_helpers.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/input_helpers.h
new file mode 100644
index 0000000..f8ffab6
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/input_helpers.h
@@ -0,0 +1,83 @@
+#ifndef _INPUT_HELPERS_H_
+#define _INPUT_HELPERS_H_
+
+class input_helper {
+public:
+ input_helper();
+ void open(service_ptr_t<file> p_filehint,metadb_handle_ptr p_location,unsigned p_flags,abort_callback & p_abort,bool p_from_redirect = false,bool p_skip_hints = false);
+ void open(service_ptr_t<file> p_filehint,const playable_location & p_location,unsigned p_flags,abort_callback & p_abort,bool p_from_redirect = false,bool p_skip_hints = false);
+
+ void close();
+ bool is_open();
+ bool run(audio_chunk & p_chunk,abort_callback & p_abort);
+ void seek(double seconds,abort_callback & p_abort);
+ bool can_seek();
+ void set_full_buffer(t_filesize val);
+ void on_idle(abort_callback & p_abort);
+ bool get_dynamic_info(file_info & p_out,double & p_timestamp_delta);
+ bool get_dynamic_info_track(file_info & p_out,double & p_timestamp_delta);
+
+ //! Retrieves path of currently open file.
+ const char * get_path() const;
+
+ //! Retrieves info about specific subsong of currently open file.
+ void get_info(t_uint32 p_subsong,file_info & p_info,abort_callback & p_abort);
+
+ static void g_get_info(const playable_location & p_location,file_info & p_info,abort_callback & p_abort,bool p_from_redirect = false);
+ static void g_set_info(const playable_location & p_location,file_info & p_info,abort_callback & p_abort,bool p_from_redirect = false);
+
+
+ static bool g_mark_dead(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,bit_array_var & p_mask,abort_callback & p_abort);
+
+private:
+ service_ptr_t<input_decoder> m_input;
+ pfc::string8 m_path;
+ t_filesize m_fullbuffer;
+};
+
+class NOVTABLE dead_item_filter : public abort_callback {
+public:
+ virtual void on_progress(t_size p_position,t_size p_total) = 0;
+
+ bool run(const pfc::list_base_const_t<metadb_handle_ptr> & p_list,bit_array_var & p_mask);
+};
+
+class input_info_read_helper {
+public:
+ input_info_read_helper() {}
+ void get_info(const playable_location & p_location,file_info & p_info,t_filestats & p_stats,abort_callback & p_abort);
+ void get_info_check(const playable_location & p_location,file_info & p_info,t_filestats & p_stats,bool & p_reloaded,abort_callback & p_abort);
+private:
+ void open(const char * p_path,abort_callback & p_abort);
+
+ pfc::string8 m_path;
+ service_ptr_t<input_info_reader> m_input;
+};
+
+
+
+class input_helper_cue {
+public:
+ void open(service_ptr_t<file> p_filehint,const playable_location & p_location,unsigned p_flags,abort_callback & p_abort,double p_start,double p_length);
+
+ void close();
+ bool is_open();
+ bool run(audio_chunk & p_chunk,abort_callback & p_abort);
+ void seek(double seconds,abort_callback & p_abort);
+ bool can_seek();
+ void set_full_buffer(t_filesize val);
+ void on_idle(abort_callback & p_abort);
+ bool get_dynamic_info(file_info & p_out,double & p_timestamp_delta);
+ bool get_dynamic_info_track(file_info & p_out,double & p_timestamp_delta);
+
+ const char * get_path() const;
+
+ void get_info(t_uint32 p_subsong,file_info & p_info,abort_callback & p_abort);
+
+private:
+ input_helper m_input;
+ double m_start,m_length,m_position;
+ bool m_dynamic_info_trigger,m_dynamic_info_track_trigger;
+};
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/listview_helper.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/listview_helper.cpp
new file mode 100644
index 0000000..76cd1d8
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/listview_helper.cpp
@@ -0,0 +1,147 @@
+#include "stdafx.h"
+
+
+#define uTEXT(blah) TEXT(blah)
+#define uLVM_SETITEM LVM_SETITEM
+#define uLVM_INSERTITEM LVM_INSERTITEM
+#define uLVM_INSERTCOLUMN LVM_INSERTCOLUMN
+#define uLVM_GETITEM LVM_GETITEM
+
+namespace listview_helper {
+
+ unsigned insert_item(HWND p_listview,unsigned p_index,const char * p_name,LPARAM p_param)
+ {
+ if (p_index == infinite) p_index = ListView_GetItemCount(p_listview);
+ LVITEM item;
+ memset(&item,0,sizeof(item));
+
+ pfc::stringcvt::string_os_from_utf8 os_string_temp(p_name);
+ os_string_temp.convert(p_name);
+
+ item.mask = LVIF_TEXT | LVIF_PARAM;
+ item.iItem = p_index;
+ item.lParam = p_param;
+ item.pszText = const_cast<TCHAR*>(os_string_temp.get_ptr());
+
+ LRESULT ret = uSendMessage(p_listview,uLVM_INSERTITEM,0,(LPARAM)&item);
+ if (ret < 0) return infinite;
+ else return (unsigned) ret;
+ }
+
+
+
+ unsigned insert_column(HWND p_listview,unsigned p_index,const char * p_name,unsigned p_width_dlu)
+ {
+ pfc::stringcvt::string_os_from_utf8 os_string_temp;
+ os_string_temp.convert(p_name);
+
+ RECT rect = {0,0,p_width_dlu,0};
+ MapDialogRect(GetParent(p_listview),&rect);
+
+ LVCOLUMN data;
+ memset(&data,0,sizeof(data));
+ data.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_FMT;
+ data.fmt = LVCFMT_LEFT;
+ data.cx = rect.right;
+ data.pszText = const_cast<TCHAR*>(os_string_temp.get_ptr());
+
+ LRESULT ret = uSendMessage(p_listview,uLVM_INSERTCOLUMN,p_index,(LPARAM)&data);
+ if (ret < 0) return infinite;
+ else return (unsigned) ret;
+ }
+
+ void get_item_text(HWND p_listview,unsigned p_index,unsigned p_column,pfc::string_base & p_out) {
+ enum {buffer_length = 4096};
+ TCHAR buffer[buffer_length];
+ ListView_GetItemText(p_listview,p_index,p_column,buffer,buffer_length);
+ p_out = pfc::stringcvt::string_utf8_from_os(buffer,buffer_length);
+ }
+
+ bool set_item_text(HWND p_listview,unsigned p_index,unsigned p_column,const char * p_name)
+ {
+ LVITEM item;
+ memset(&item,0,sizeof(item));
+
+ pfc::stringcvt::string_os_from_utf8 os_string_temp;
+ os_string_temp.convert(p_name);
+
+ item.mask = LVIF_TEXT;
+ item.iItem = p_index;
+ item.iSubItem = p_column;
+ item.pszText = const_cast<TCHAR*>(os_string_temp.get_ptr());
+ return uSendMessage(p_listview,uLVM_SETITEM,0,(LPARAM)&item) ? true : false;
+ }
+
+ bool is_item_selected(HWND p_listview,unsigned p_index)
+ {
+ LVITEM item;
+ memset(&item,0,sizeof(item));
+ item.mask = LVIF_STATE;
+ item.iItem = p_index;
+ item.stateMask = LVIS_SELECTED;
+ if (!uSendMessage(p_listview,uLVM_GETITEM,0,(LPARAM)&item)) return false;
+ return (item.state & LVIS_SELECTED) ? true : false;
+ }
+
+ bool set_item_selection(HWND p_listview,unsigned p_index,bool p_state)
+ {
+ LVITEM item;
+ memset(&item,0,sizeof(item));
+ item.mask = LVIF_STATE;
+ item.iItem = p_index;
+ item.stateMask = LVIS_SELECTED;
+ item.state = p_state ? LVIS_SELECTED : 0;
+ return uSendMessage(p_listview,uLVM_SETITEM,0,(LPARAM)&item) ? true : false;
+ }
+
+ bool select_single_item(HWND p_listview,unsigned p_index)
+ {
+ LRESULT temp = SendMessage(p_listview,LVM_GETITEMCOUNT,0,0);
+ if (temp < 0) return false;
+ ListView_SetSelectionMark(p_listview,p_index);
+ unsigned n; const unsigned m = pfc::downcast_guarded<unsigned>(temp);
+ for(n=0;n<m;n++) {
+ enum {mask = LVIS_FOCUSED | LVIS_SELECTED};
+ ListView_SetItemState(p_listview,n,n == p_index ? mask : 0, mask);
+ }
+ return ensure_visible(p_listview,p_index);
+ }
+
+ bool ensure_visible(HWND p_listview,unsigned p_index)
+ {
+ return uSendMessage(p_listview,LVM_ENSUREVISIBLE,p_index,FALSE) ? true : false;
+ }
+}
+
+
+
+bool ListView_GetContextMenuPoint(HWND p_list,LPARAM p_coords,POINT & p_point,int & p_selection) {
+ if ((DWORD)p_coords == (DWORD)infinite) {
+ int firstsel = ListView_GetFirstSelection(p_list);
+ if (firstsel >= 0) {
+ RECT rect;
+ if (!ListView_GetItemRect(p_list,firstsel,&rect,LVIR_BOUNDS)) return false;
+ p_point.x = (rect.left + rect.right) / 2;
+ p_point.y = (rect.top + rect.bottom) / 2;
+ if (!ClientToScreen(p_list,&p_point)) return false;
+ } else {
+ RECT rect;
+ if (!GetClientRect(p_list,&rect)) return false;
+ p_point.x = (rect.left + rect.right) / 2;
+ p_point.y = (rect.top + rect.bottom) / 2;
+ if (!ClientToScreen(p_list,&p_point)) return false;
+ }
+ p_selection = firstsel;
+ return true;
+ } else {
+ POINT pt = {(short)LOWORD(p_coords),(short)HIWORD(p_coords)};
+ p_point = pt;
+ POINT client = pt;
+ if (!ScreenToClient(p_list,&client)) return false;
+ LVHITTESTINFO info;
+ memset(&info,0,sizeof(info));
+ info.pt = client;
+ p_selection = ListView_HitTest(p_list,&info);
+ return true;
+ }
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/listview_helper.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/listview_helper.h
new file mode 100644
index 0000000..cf9b202
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/listview_helper.h
@@ -0,0 +1,38 @@
+namespace listview_helper
+{
+ unsigned insert_item(HWND p_listview,unsigned p_index,const char * p_name,LPARAM p_param);//returns index of new item on success, infinite on failure
+
+ unsigned insert_column(HWND p_listview,unsigned p_index,const char * p_name,unsigned p_width_dlu);//returns index of new item on success, infinite on failure
+
+ bool set_item_text(HWND p_listview,unsigned p_index,unsigned p_column,const char * p_name);
+
+ bool is_item_selected(HWND p_listview,unsigned p_index);
+
+ bool set_item_selection(HWND p_listview,unsigned p_index,bool p_state);
+
+ bool select_single_item(HWND p_listview,unsigned p_index);
+
+ bool ensure_visible(HWND p_listview,unsigned p_index);
+
+ void get_item_text(HWND p_listview,unsigned p_index,unsigned p_column,pfc::string_base & p_out);
+
+};
+
+static int ListView_GetFirstSelection(HWND p_listview) {
+ return ListView_GetNextItem(p_listview,-1,LVNI_SELECTED);
+}
+
+static int ListView_GetSingleSelection(HWND p_listview) {
+ if (ListView_GetSelectedCount(p_listview) != 1) return -1;
+ return ListView_GetFirstSelection(p_listview);
+}
+
+static int ListView_GetFocusItem(HWND p_listview) {
+ return ListView_GetNextItem(p_listview,-1,LVNI_FOCUSED);
+}
+
+static bool ListView_IsItemSelected(HWND p_listview,int p_index) {
+ return ListView_GetItemState(p_listview,p_index,LVIS_SELECTED) != 0;
+}
+
+bool ListView_GetContextMenuPoint(HWND p_list,LPARAM p_coords,POINT & p_point,int & p_selection); \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/meta_table_builder.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/meta_table_builder.h
new file mode 100644
index 0000000..90b052a
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/meta_table_builder.h
@@ -0,0 +1,67 @@
+class __meta_table_enum_wrapper {
+public:
+ __meta_table_enum_wrapper(file_info & p_info) : m_info(p_info) {}
+ void operator() (const char * p_name,const pfc::chain_list_t<pfc::string8> & p_values) {
+ t_size index = infinite;
+ for(pfc::chain_list_t<pfc::string8>::const_iterator iter = p_values.first(); iter.is_valid(); ++iter) {
+ if (index == infinite) index = m_info.__meta_add_unsafe(p_name,*iter);
+ else m_info.meta_add_value(index,*iter);
+ }
+ }
+private:
+ file_info & m_info;
+};
+
+//! Purpose: building a file_info metadata table from loose input without search-for-existing-entry bottleneck
+class meta_table_builder {
+public:
+ void add(const char * p_name,const char * p_value,t_size p_value_len = infinite) {
+ if (file_info::g_is_valid_field_name(p_name)) {
+ __add(p_name).insert_last()->set_string(p_value,p_value_len);
+ }
+ }
+
+ void remove(const char * p_name) {
+ m_data.remove(p_name);
+ }
+ void set(const char * p_name,const char * p_value,t_size p_value_len = infinite) {
+ if (file_info::g_is_valid_field_name(p_name)) {
+ t_entry & entry = __add(p_name);
+ entry.remove_all();
+ entry.insert_last()->set_string(p_value,p_value_len);
+ }
+ }
+ pfc::chain_list_t<pfc::string8> & add(const char * p_name) {
+ if (!file_info::g_is_valid_field_name(p_name)) throw pfc::exception_bug_check();//we return a reference, nothing smarter to do
+ return __add(p_name);
+ }
+ void finalize(file_info & p_info) {
+ p_info.meta_remove_all();
+ m_data.enumerate(__meta_table_enum_wrapper(p_info));
+ }
+
+ void from_info(const file_info & p_info) {
+ m_data.remove_all();
+ from_info_overwrite(p_info);
+ }
+ void from_info_overwrite(const file_info & p_info) {
+ for(t_size metawalk = 0, metacount = p_info.meta_get_count(); metawalk < metacount; ++metawalk ) {
+ const t_size valuecount = p_info.meta_enum_value_count(metawalk);
+ if (valuecount > 0) {
+ t_entry & entry = add(p_info.meta_enum_name(metawalk));
+ entry.remove_all();
+ for(t_size valuewalk = 0; valuewalk < valuecount; ++valuewalk) {
+ entry.insert_last(p_info.meta_enum_value(metawalk,valuewalk));
+ }
+ }
+ }
+ }
+private:
+ typedef pfc::chain_list_t<pfc::string8> t_entry;
+
+ t_entry & __add(const char * p_name) {
+ return m_data.find_or_add(p_name);
+ }
+
+ pfc::map_t<pfc::string8,t_entry,file_info::field_name_comparator> m_data;
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/metadb_io_hintlist.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/metadb_io_hintlist.cpp
new file mode 100644
index 0000000..4849f11
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/metadb_io_hintlist.cpp
@@ -0,0 +1,39 @@
+#include "stdafx.h"
+
+void metadb_io_hintlist::run() {
+ if (m_entries.get_count() > 0) {
+ static_api_ptr_t<metadb_io>()->hint_multi_async(
+ metadb_io_hintlist_wrapper_part1(m_entries),
+ metadb_io_hintlist_wrapper_part2(m_entries),
+ metadb_io_hintlist_wrapper_part3(m_entries),
+ metadb_io_hintlist_wrapper_part4(m_entries)
+ );
+ }
+ m_entries.remove_all();
+}
+
+void metadb_io_hintlist::add(metadb_handle_ptr const & p_handle,const file_info & p_info,t_filestats const & p_stats,bool p_fresh) {
+ t_entry entry;
+ entry.m_handle = p_handle;
+ entry.m_info.new_t(p_info);
+ entry.m_stats = p_stats;
+ entry.m_fresh = p_fresh;
+ m_entries.add_item(entry);
+}
+
+void metadb_io_hintlist::hint_reader(service_ptr_t<input_info_reader> p_reader, const char * p_path,abort_callback & p_abort) {
+ static_api_ptr_t<metadb> api;
+ const t_uint32 subsongcount = p_reader->get_subsong_count();
+ t_filestats stats = p_reader->get_file_stats(p_abort);
+ for(t_uint32 subsong = 0; subsong < subsongcount; subsong++) {
+ t_uint32 subsong_id = p_reader->get_subsong(subsong);
+ metadb_handle_ptr handle;
+ api->handle_create(handle,make_playable_location(p_path,subsong_id));
+ if (handle->should_reload(stats,true)) {
+ file_info_impl temp;
+ p_reader->get_info(subsong_id,temp,p_abort);
+
+ add(handle,temp,stats,true);
+ }
+ }
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/metadb_io_hintlist.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/metadb_io_hintlist.h
new file mode 100644
index 0000000..92d60c8
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/metadb_io_hintlist.h
@@ -0,0 +1,49 @@
+
+class metadb_io_hintlist {
+public:
+ void hint_reader(service_ptr_t<input_info_reader> p_reader, const char * p_path,abort_callback & p_abort);
+ void add(metadb_handle_ptr const & p_handle,const file_info & p_info,t_filestats const & p_stats,bool p_fresh);
+ void run();
+private:
+ struct t_entry {
+ metadb_handle_ptr m_handle;
+ pfc::rcptr_t<file_info_const_impl> m_info;
+ t_filestats m_stats;
+ bool m_fresh;
+ };
+ class metadb_io_hintlist_wrapper_part1 : public pfc::list_base_const_t<metadb_handle_ptr> {
+ public:
+ metadb_io_hintlist_wrapper_part1(const pfc::list_base_const_t<metadb_io_hintlist::t_entry> & p_list) : m_list(p_list) {}
+ t_size get_count() const {return m_list.get_count();}
+ void get_item_ex(metadb_handle_ptr & p_out, t_size n) const {p_out = m_list[n].m_handle;}
+
+ private:
+ const pfc::list_base_const_t<metadb_io_hintlist::t_entry> & m_list;
+ };
+ class metadb_io_hintlist_wrapper_part2 : public pfc::list_base_const_t<const file_info*> {
+ public:
+ metadb_io_hintlist_wrapper_part2(const pfc::list_base_const_t<metadb_io_hintlist::t_entry> & p_list) : m_list(p_list) {}
+ t_size get_count() const {return m_list.get_count();}
+ void get_item_ex(const file_info* & p_out, t_size n) const {p_out = &*m_list[n].m_info;}
+ private:
+ const pfc::list_base_const_t<metadb_io_hintlist::t_entry> & m_list;
+ };
+ class metadb_io_hintlist_wrapper_part3 : public pfc::list_base_const_t<t_filestats> {
+ public:
+ metadb_io_hintlist_wrapper_part3(const pfc::list_base_const_t<metadb_io_hintlist::t_entry> & p_list) : m_list(p_list) {}
+ t_size get_count() const {return m_list.get_count();}
+ void get_item_ex(t_filestats & p_out, t_size n) const {p_out = m_list[n].m_stats;}
+ private:
+ const pfc::list_base_const_t<metadb_io_hintlist::t_entry> & m_list;
+ };
+ class metadb_io_hintlist_wrapper_part4 : public bit_array {
+ public:
+ metadb_io_hintlist_wrapper_part4(const pfc::list_base_const_t<metadb_io_hintlist::t_entry> & p_list) : m_list(p_list) {}
+ bool get(t_size n) const {return m_list[n].m_fresh;}
+ private:
+ const pfc::list_base_const_t<metadb_io_hintlist::t_entry> & m_list;
+ };
+
+ pfc::list_t<t_entry,pfc::alloc_fast> m_entries;
+};
+
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/mp3_utils.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/mp3_utils.cpp
new file mode 100644
index 0000000..f86333a
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/mp3_utils.cpp
@@ -0,0 +1,190 @@
+#include "stdafx.h"
+
+using namespace bitreader_helper;
+
+static unsigned extract_header_bits(const t_uint8 p_header[4],unsigned p_base,unsigned p_bits)
+{
+ assert(p_base+p_bits<=32);
+ return extract_bits(p_header,p_base,p_bits);
+}
+
+namespace {
+
+ class header_parser
+ {
+ public:
+ header_parser(const t_uint8 p_header[4]) : m_bitptr(0)
+ {
+ memcpy(m_header,p_header,4);
+ }
+ unsigned read(unsigned p_bits)
+ {
+ unsigned ret = extract_header_bits(m_header,m_bitptr,p_bits);
+ m_bitptr += p_bits;
+ return ret;
+ }
+ private:
+ t_uint8 m_header[4];
+ unsigned m_bitptr;
+ };
+}
+
+typedef t_uint16 uint16;
+
+static const uint16 bitrate_table_l1v1[16] = { 0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448, 0};
+static const uint16 bitrate_table_l2v1[16] = { 0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384, 0};
+static const uint16 bitrate_table_l3v1[16] = { 0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320, 0};
+static const uint16 bitrate_table_l1v2[16] = { 0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256, 0};
+static const uint16 bitrate_table_l23v2[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160, 0};
+static const uint16 sample_rate_table[] = {11025,12000,8000};
+
+unsigned mp3_utils::QueryMPEGFrameSize(const t_uint8 p_header[4])
+{
+ TMPEGFrameInfo info;
+ if (!ParseMPEGFrameHeader(info,p_header)) return 0;
+ return info.m_bytes;
+}
+
+bool mp3_utils::ParseMPEGFrameHeader(TMPEGFrameInfo & p_info,const t_uint8 p_header[4])
+{
+ enum {MPEG_LAYER_1 = 3, MPEG_LAYER_2 = 2, MPEG_LAYER_3 = 1};
+ enum {_MPEG_1 = 3, _MPEG_2 = 2, _MPEG_25 = 0};
+
+ header_parser parser(p_header);
+ if (parser.read(11) != 0x7FF) return false;
+ unsigned mpeg_version = parser.read(2);
+ unsigned layer = parser.read(2);
+ unsigned protection = parser.read(1);
+ unsigned bitrate_index = parser.read(4);
+ unsigned sample_rate_index = parser.read(2);
+ if (sample_rate_index == 11) return false;//reserved
+ unsigned paddingbit = parser.read(1);
+ int paddingdelta = 0;
+ parser.read(1);//private
+ unsigned channel_mode = parser.read(2);
+ parser.read(2);//channel_mode_extension
+ parser.read(1);//copyright
+ parser.read(1);//original
+ parser.read(2);//emphasis
+
+ unsigned bitrate = 0,sample_rate = 0;
+
+ switch(layer)
+ {
+ default:
+ return false;
+ case MPEG_LAYER_3:
+ paddingdelta = paddingbit ? 1 : 0;
+
+ p_info.m_layer = 3;
+ switch(mpeg_version)
+ {
+ case _MPEG_1:
+ p_info.m_duration = 1152;
+ bitrate = bitrate_table_l3v1[bitrate_index];
+ break;
+ case _MPEG_2:
+ case _MPEG_25:
+ p_info.m_duration = 576;
+ bitrate = bitrate_table_l23v2[bitrate_index];
+ break;
+ default:
+ return false;
+ }
+
+ break;
+ case MPEG_LAYER_2:
+ paddingdelta = paddingbit ? 1 : 0;
+ p_info.m_duration = 1152;
+ p_info.m_layer = 2;
+ switch(mpeg_version)
+ {
+ case _MPEG_1:
+ bitrate = bitrate_table_l2v1[bitrate_index];
+ break;
+ case _MPEG_2:
+ case _MPEG_25:
+ bitrate = bitrate_table_l23v2[bitrate_index];
+ break;
+ default:
+ return false;
+ }
+ break;
+ case MPEG_LAYER_1:
+ paddingdelta = paddingbit ? 4 : 0;
+ p_info.m_duration = 384;
+ p_info.m_layer = 1;
+ switch(mpeg_version)
+ {
+ case _MPEG_1:
+ bitrate = bitrate_table_l1v1[bitrate_index];
+ break;
+ case _MPEG_2:
+ case _MPEG_25:
+ bitrate = bitrate_table_l1v2[bitrate_index];
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ if (bitrate == 0) return false;
+
+ sample_rate = sample_rate_table[sample_rate_index];
+ if (sample_rate == 0) return false;
+ switch(mpeg_version)
+ {
+ case _MPEG_1:
+ sample_rate *= 4;
+ p_info.m_mpegversion = MPEG_1;
+ break;
+ case _MPEG_2:
+ sample_rate *= 2;
+ p_info.m_mpegversion = MPEG_2;
+ break;
+ case _MPEG_25:
+ p_info.m_mpegversion = MPEG_25;
+ break;
+ }
+
+ switch(channel_mode)
+ {
+ case 0:
+ case 1:
+ case 2:
+ p_info.m_channels = 2;
+ break;
+ case 3:
+ p_info.m_channels = 1;
+ break;
+ }
+
+ p_info.m_channel_mode = channel_mode;
+
+ p_info.m_sample_rate = sample_rate;
+
+
+ p_info.m_bytes = ( bitrate /*kbps*/ * (1000/8) /* kbps-to-bytes*/ * p_info.m_duration /*samples-per-frame*/ ) / sample_rate + paddingdelta;
+
+ if (p_info.m_layer == 1) p_info.m_bytes &= ~3;
+
+ p_info.m_crc = protection == 0;
+
+ return true;
+}
+
+unsigned mp3header::get_samples_per_frame()
+{
+ mp3_utils::TMPEGFrameInfo fr;
+ if (!decode(fr)) return 0;
+ return fr.m_duration;
+}
+
+
+bool mp3_utils::IsSameStream(TMPEGFrameInfo const & p_frame1,TMPEGFrameInfo const & p_frame2) {
+ return
+ p_frame1.m_channel_mode == p_frame2.m_channel_mode &&
+ p_frame1.m_sample_rate == p_frame2.m_sample_rate &&
+ p_frame1.m_layer == p_frame2.m_layer &&
+ p_frame1.m_mpegversion == p_frame2.m_mpegversion;
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/mp3_utils.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/mp3_utils.h
new file mode 100644
index 0000000..3c748c1
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/mp3_utils.h
@@ -0,0 +1,58 @@
+namespace mp3_utils
+{
+
+ enum {
+ MPG_MD_STEREO=0,
+ MPG_MD_JOINT_STEREO=1,
+ MPG_MD_DUAL_CHANNEL=2,
+ MPG_MD_MONO=3,
+ };
+
+ typedef t_uint8 byte;
+
+ enum {MPEG_1, MPEG_2, MPEG_25};
+
+ struct TMPEGFrameInfo
+ {
+ unsigned m_bytes;
+ unsigned m_sample_rate;
+ unsigned m_layer;
+ unsigned m_mpegversion;
+ unsigned m_channels;
+ unsigned m_duration;
+ unsigned m_channel_mode;
+ bool m_crc;
+ };
+
+
+ bool ParseMPEGFrameHeader(TMPEGFrameInfo & p_info,const t_uint8 p_header[4]);
+ unsigned QueryMPEGFrameSize(const t_uint8 p_header[4]);
+ bool IsSameStream(TMPEGFrameInfo const & p_frame1,TMPEGFrameInfo const & p_frame2);
+};
+
+class mp3header
+{
+ t_uint8 bytes[4];
+public:
+
+ inline void copy(const mp3header & src) {memcpy(bytes,src.bytes,4);}
+ inline void copy_raw(const void * src) {memcpy(bytes,src,4);}
+
+ inline mp3header(const mp3header & src) {copy(src);}
+ inline mp3header() {}
+
+ inline const mp3header & operator=(const mp3header & src) {copy(src); return *this;}
+
+ inline void get_bytes(void * out) {memcpy(out,bytes,4);}
+ inline unsigned get_frame_size() const {return mp3_utils::QueryMPEGFrameSize(bytes);}
+ inline bool decode(mp3_utils::TMPEGFrameInfo & p_out) {return mp3_utils::ParseMPEGFrameHeader(p_out,bytes);}
+
+ unsigned get_samples_per_frame();
+};
+
+static inline mp3header mp3header_from_buffer(const void * p_buffer)
+{
+ mp3header temp;
+ temp.copy_raw(p_buffer);
+ return temp;
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/preload_info_helper.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/preload_info_helper.cpp
new file mode 100644
index 0000000..1d35260
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/preload_info_helper.cpp
@@ -0,0 +1,29 @@
+#include "stdafx.h"
+
+bool preload_info_helper::preload_info(metadb_handle_ptr p_item,HWND p_parent_window,bool p_showerror) {
+ if (p_item->is_info_loaded()) return true;
+ return static_api_ptr_t<metadb_io>()->load_info(p_item,metadb_io::load_info_default,p_parent_window,p_showerror) == metadb_io::load_info_success;
+}
+
+bool preload_info_helper::are_all_loaded(const pfc::list_base_const_t<metadb_handle_ptr> & p_items)
+{
+ t_size n, m = p_items.get_count();
+ for(n=0;n<m;n++)
+ {
+ if (!p_items[n]->is_info_loaded()) return false;
+ }
+ return true;
+}
+
+bool preload_info_helper::preload_info_multi(const pfc::list_base_const_t<metadb_handle_ptr> & p_items,HWND p_parent_window,bool p_showerror)
+{
+ if (are_all_loaded(p_items)) return true;
+ return static_api_ptr_t<metadb_io>()->load_info_multi(p_items,metadb_io::load_info_default,p_parent_window,p_showerror) == metadb_io::load_info_success;
+}
+
+bool preload_info_helper::preload_info_multi_modalcheck(const pfc::list_base_const_t<metadb_handle_ptr> & p_items,HWND p_parent_window,bool p_showerror)
+{
+ if (are_all_loaded(p_items)) return true;
+ if (!modal_dialog_scope::can_create()) return false;
+ return static_api_ptr_t<metadb_io>()->load_info_multi(p_items,metadb_io::load_info_default,p_parent_window,p_showerror) == metadb_io::load_info_success;
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/preload_info_helper.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/preload_info_helper.h
new file mode 100644
index 0000000..5f3451f
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/preload_info_helper.h
@@ -0,0 +1,6 @@
+namespace preload_info_helper {
+ bool __declspec(deprecated("Use metadb_io_v2 methods instead.")) preload_info(metadb_handle_ptr p_item,HWND p_parent_window,bool p_showerror);
+ bool __declspec(deprecated("Use metadb_io_v2 methods instead.")) preload_info_multi(const pfc::list_base_const_t<metadb_handle_ptr> & p_items,HWND p_parent_window,bool p_showerror);
+ bool __declspec(deprecated("Use metadb_io_v2 methods instead.")) preload_info_multi_modalcheck(const pfc::list_base_const_t<metadb_handle_ptr> & p_items,HWND p_parent_window,bool p_showerror);
+ bool are_all_loaded(const pfc::list_base_const_t<metadb_handle_ptr> & p_items);
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/search_filter.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/search_filter.cpp
new file mode 100644
index 0000000..0c4a601
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/search_filter.cpp
@@ -0,0 +1,587 @@
+#include "stdafx.h"
+
+static bool is_spacing(char c) {return c == ' ' || c==10 || c==13;}
+static bool is_alpha(char c) {return (c>='a' && c<='z') || (c>='A' && c<='Z');}
+static bool is_alphanumeric(char c) {return is_alpha(c) || (c>='0' && c<='9');}
+static bool is_spacing_or_null(char c) {return c == 0 || is_spacing(c);}
+
+static bool is_format_spec(const char * ptr) {return strchr(ptr,'%') || strchr(ptr,'#') || strchr(ptr,'$');}
+
+namespace search_tools {
+
+ class substring_filter {
+ pfc::ptr_list_t<char> data;
+ mutable pfc::string8_fastalloc temp;
+ public:
+ substring_filter(const char * src) {
+ while(*src) {
+ while(*src && is_spacing(*src)) src++;
+ t_size ptr = 0;
+ while(src[ptr] && !is_spacing(src[ptr])) ptr++;
+ if (ptr) {
+ uStringLower(temp,src,ptr);
+ data.add_item(strdup(temp));
+ }
+ src+=ptr;
+ }
+ }
+ bool test(const char * src) const {
+ t_size n,m = data.get_count();
+ if (m==0) return false;
+ uStringLower(temp,src);
+ for(n=0;n<m;n++) {
+ if (!strstr(temp,data[n])) return false;
+ }
+ return true;
+ }
+ ~substring_filter() {data.free_all();}
+ };
+
+
+ class filter_node_and : public filter_node {
+ filter_node_cptr n1, n2;
+ public:
+ filter_node_and(filter_node_cptr p1,filter_node_cptr p2) : n1(p1), n2(p2) {}
+ virtual bool test(const file_info * item,const metadb_handle_ptr & handle) const {return n1->test(item,handle) && n2->test(item,handle);}
+ };
+
+ class filter_node_or : public filter_node {
+ filter_node_cptr n1, n2;
+ public:
+ filter_node_or(filter_node_cptr p1,filter_node_cptr p2) : n1(p1), n2(p2) {}
+ virtual bool test(const file_info * item,const metadb_handle_ptr & handle) const {return n1->test(item,handle) || n2->test(item,handle);}
+ };
+
+ class filter_node_not : public filter_node {
+ filter_node_cptr n;
+ public:
+ filter_node_not(filter_node_cptr p) : n(p) {}
+ virtual bool test(const file_info * item,const metadb_handle_ptr & handle) const {return !n->test(item,handle);}
+ };
+
+ class filter_node_missing : public filter_node {
+ pfc::string8 m_field;
+ public:
+ filter_node_missing(const char * p_string,t_size p_len) {
+ while(p_len > 0 && p_string[0] == ' ') {p_string++;p_len--;}
+ while(p_len > 0 && p_string[p_len - 1] == ' ') p_len--;
+ m_field.set_string(p_string,p_len);
+ }
+
+ bool test(const file_info * item,const metadb_handle_ptr & handle) const {
+ return item->meta_find(m_field) == infinite;
+ }
+ };
+
+ class filter_node_is_format : public filter_node {
+ pfc::string_simple param;
+ service_ptr_t<titleformat_object> m_script;
+ mutable pfc::string8_fastalloc temp;
+ bool is_wildcard;
+ bool test_internal(const char * src) const {
+ if (is_wildcard) return wildcard_helper::test(src,param,false);
+ else return !stricmp_utf8(src,param);
+ }
+ public:
+ filter_node_is_format(const char * p_field,const char * p_param)
+ : param(p_param), is_wildcard(wildcard_helper::has_wildcards(p_param))
+ {
+ if (!static_api_ptr_t<titleformat_compiler>()->compile(m_script,p_field))
+ throw exception_parse_error();
+ }
+
+ bool test(const file_info * item,const metadb_handle_ptr & handle) const {
+ handle->format_title(0,temp,m_script,0);
+ return test_internal(temp);
+ }
+ };
+
+ class filter_node_is : public filter_node {
+ pfc::string_simple field,param;
+ mutable pfc::string8_fastalloc temp;
+ bool is_wildcard;
+ bool test_internal(const char * src) const {
+ if (is_wildcard) return wildcard_helper::test(src,param,false);
+ else return !stricmp_utf8(src,param);
+ }
+ public:
+ filter_node_is(const char * p_field,const char * p_param)
+ : field(p_field), param(p_param), is_wildcard(wildcard_helper::has_wildcards(p_param))
+ {
+ }
+
+ bool test(const file_info * item,const metadb_handle_ptr & handle) const {
+ t_size index = item->meta_find(field);
+ if (index == infinite) return false;
+ t_size n,m = item->meta_enum_value_count(index);
+ for(n=0;n<m;n++)
+ {
+ if (test_internal(item->meta_enum_value(index,n))) return true;
+ }
+ return false;
+ }
+ };
+
+ class filter_node_has : public filter_node {
+ pfc::string_simple field;
+ mutable pfc::string8_fastalloc temp;
+ substring_filter m_filter;
+ public:
+ filter_node_has(const char * p_field,const char * p_param)
+ : field(p_field), m_filter(p_param)
+ {
+ }
+
+ ~filter_node_has() {}
+
+ bool test(const file_info * item,const metadb_handle_ptr & handle) const {
+ t_size index = item->meta_find(field);
+ if (index == infinite) return false;
+ t_size n, m = item->meta_enum_value_count(index);
+ temp.reset();
+ for(n=0;n<m;n++)
+ {
+ temp += " ";
+ temp += item->meta_enum_value(index,n);
+ }
+ return m_filter.test(temp);
+ }
+ };
+
+ class filter_node_has_ex : public filter_node {
+ pfc::string_simple field;
+ substring_filter m_filter;
+ mutable pfc::string8_fastalloc temp;
+ public:
+ filter_node_has_ex(const char * p_field,const char * p_param)
+ : field(p_field), m_filter(p_param)
+ {
+ }
+
+ bool test(const file_info * item,const metadb_handle_ptr & handle) const {
+ handle->format_title_legacy(0,temp,field,0);
+ return m_filter.test(temp);
+ }
+ };
+
+ class filter_node_simple : public filter_node {
+ substring_filter m_filter;
+ mutable pfc::string8_fastalloc temp;
+ public:
+ filter_node_simple(const char * src) : m_filter(src) {}
+ bool test(const file_info * info,const metadb_handle_ptr & handle) const {
+ t_size n, m = info->meta_get_count();
+ temp = handle->get_path();
+ for(n=0;n<m;n++) {
+ t_size n1, m1 = info->meta_enum_value_count(n);
+ for(n1=0;n1<m1;n1++)
+ {
+ temp += " ";
+ temp += info->meta_enum_value(n,n1);
+ }
+ }
+ m = info->info_get_count();
+ for(n=0;n<m;n++) {
+ temp += " ";
+ temp += info->info_enum_value(n);
+ }
+
+ return m_filter.test(temp);
+ }
+ };
+
+ class parser {
+ const char * base;
+ t_size len,ptr;
+ public:
+ inline parser() : base(0), len(0), ptr(0) {}
+ inline parser(const char * p_ptr,t_size p_len) : base(p_ptr), len(p_len), ptr(0) {}
+ inline parser(const parser & param) : base(param.get_ptr()), len(param.get_remaining()), ptr(0) {}
+ inline parser(const parser & param,t_size len) : base(param.get_ptr()), len(len), ptr(0) {assert(len<=param.get_remaining());}
+ inline const char * get_ptr() const {return base+ptr;}
+ inline t_size get_remaining() const {return len-ptr;}
+ inline t_size advance(t_size n) {ptr+=n; assert(ptr<=len);return n;}
+ inline char get_char() const {return get_ptr()[0];}
+ inline t_size get_offset() const {return ptr;}
+ inline void reset(t_size offset=0) {ptr=offset;}
+
+ t_size test_spacing() const {
+ t_size n = 0, m = get_remaining();
+ const char * src = get_ptr();
+ while(n<m && is_spacing(src[n])) n++;
+ return n;
+ }
+
+ t_size skip_spacing() {
+ return advance(test_spacing());
+ }
+
+ bool is_empty() const {return test_spacing() == get_remaining();}
+
+ t_size test_token() const {
+ parser p(*this);
+ if (p.get_remaining()==0) return 0;
+ if (p.get_char() == '\"')
+ {
+ p.advance(1);
+ for(;;)
+ {
+ if (p.get_remaining()==0) return 0;
+ if (p.get_char()=='\"')
+ {
+ p.advance(1);
+ return p.get_offset();
+ }
+ else p.advance(1);
+ }
+ }
+ else if (p.get_char()=='(')
+ {
+ p.advance(1);
+ p.skip_spacing();
+ do {
+ if (p.skip_token()==0) return 0;
+ p.skip_spacing();
+ if (p.get_remaining()==0) return 0;
+ } while(p.get_char()!=')');
+ p.advance(1);
+ return p.get_offset();
+ }
+ else if (p.get_char()==')') return 0;
+ else
+ {
+ do { p.advance(1); } while(p.get_remaining()>0 && p.get_char()!=')' && !is_spacing(p.get_char()));
+ return p.get_offset();
+ }
+ return 0;
+ }
+
+ t_size skip_token() {
+ return advance(test_token());
+ }
+ };
+
+ typedef filter_node_cptr (*operator_handler)(const parser & token_left,const parser & token_right);
+
+ static filter_node_cptr operator_handler_and(const parser & token_left,const parser & token_right) {
+ return pfc::rcnew_t<filter_node_and>(filter_node::g_create(token_left),filter_node::g_create(token_right));
+ }
+
+ static filter_node_cptr operator_handler_or(const parser & token_left,const parser & token_right) {
+ return pfc::rcnew_t<filter_node_or>(filter_node::g_create(token_left),filter_node::g_create(token_right));
+ }
+
+ static filter_node_cptr operator_handler_not(const parser & token_left,const parser & token_right) {
+ if (!token_left.is_empty()) throw exception_parse_error();
+ return pfc::rcnew_t<filter_node_not>(filter_node::g_create(token_right));
+ }
+
+ static filter_node_cptr operator_handler_missing(const parser & token_left,const parser & token_right)
+ {
+ if (!token_right.is_empty()) throw exception_parse_error();
+ return pfc::rcnew_t<filter_node_missing>(token_left.get_ptr(),token_left.get_remaining());
+ }
+
+ static void parse_string(const parser & src,pfc::string_base & out)
+ {
+ parser p(src);
+ p.skip_spacing();
+ out.reset();
+ if (p.get_remaining()>0)
+ {
+ if (p.get_char()=='\"')
+ {
+ p.advance(1);
+ while(p.get_remaining()>0 && p.get_char()!='\"') {out.add_byte(p.get_char());p.advance(1);}
+ if (p.get_remaining() == 0) throw exception_parse_error();
+ return;
+ }
+ else
+ {
+ out.add_string(p.get_ptr(),p.get_remaining());
+ t_size trunc = out.length();
+ while(trunc>0 && is_spacing(out[trunc-1])) trunc--;
+ out.truncate(trunc);
+ if (trunc == 0) throw exception_parse_error();
+ return;
+ }
+ }
+ else throw exception_parse_error();
+ }
+
+ static filter_node_cptr operator_handler_has(const parser & token_left,const parser & token_right) {
+ pfc::string8 name,value;
+ parse_string(token_left,name); parse_string(token_right,value);
+ if (!strcmp(name,"*")) return pfc::rcnew_t<filter_node_simple>(value);
+ else if (is_format_spec(name)) return pfc::rcnew_t<filter_node_has_ex>(name,value);
+ else return pfc::rcnew_t<filter_node_has>(name,value);
+ }
+
+ static filter_node_cptr operator_handler_is(const parser & token_left,const parser & token_right)
+ {
+ pfc::string8 name,value;
+ parse_string(token_left,name); parse_string(token_right,value);
+ if (is_format_spec(name)) return pfc::rcnew_t<filter_node_is_format>(name,value);
+ else return pfc::rcnew_t<filter_node_is>(name,value);
+ }
+
+ class filter_node_mathop : public filter_node
+ {
+ pfc::string_simple left;
+ service_ptr_t<titleformat_object> left_script;
+ t_int64 rval;
+ bool left_ex;
+ int type;
+ mutable pfc::string8_fastalloc ltemp;
+
+ static t_int64 parse_int_or_time(const char * ptr)
+ {
+ bool neg = false;
+ t_int64 a = 0;
+ // whitespace
+ while (ptr[0] == ' ' || ptr[0] == '\t')
+ ptr++;
+ // sign
+ neg = ptr[0] == '-';
+ if (ptr[0] == '+' || ptr[0] == '-')
+ ptr++;
+ // digits
+ if (ptr[0] >= '0' && ptr[0] <= '9')
+ {
+ do
+ {
+ a = a * 10 + (ptr[0] - '0');
+ ptr++;
+ }
+ while (*ptr >= '0' && *ptr <= '9');
+ }
+ else
+ return 0;
+ if (ptr[0] != ':')
+ return neg ? -a : a;
+ ptr++;
+ // minutes or seconds
+ if ((ptr[0] >= '0' && ptr[0] <= '5') && (ptr[1] >= '0' && ptr[1] <= '9'))
+ {
+ a = a * 60 + (ptr[0] - '0') * 10 + (ptr[1] - '0');
+ if (ptr[2] == ':')
+ {
+ // seconds
+ if ((ptr[3] >= '0' && ptr[3] <= '5') && (ptr[4] >= '0' && ptr[4] <= '9') && !(ptr[5] >= '0' && ptr[5] <= '9'))
+ {
+ a = a * 60 + (ptr[3] - '0') * 10 + (ptr[4] - '0');
+ }
+ }
+ }
+ return neg ? -a : a;
+ }
+
+ public:
+ explicit filter_node_mathop(const char * p_left,const char * p_right,int p_type) : left(p_left), rval(parse_int_or_time(p_right)), type(p_type),
+ left_ex(is_format_spec(p_left))
+ {
+ if (left_ex)
+ static_api_ptr_t<titleformat_compiler>()->compile_safe(left_script,left);
+ }
+
+ bool test(const file_info * item,const metadb_handle_ptr & handle) const
+ {
+ t_int64 lval;
+ if (left_ex)
+ {
+ handle->format_title(0,ltemp,left_script,0);
+ lval = parse_int_or_time(ltemp);
+ }
+ else
+ {
+ const char * ptr = item->meta_get(left,0);
+ if (!ptr) return false;
+ lval = parse_int_or_time(ptr);
+ }
+
+ switch(type)
+ {
+ case -1: return lval < rval;
+ case 0: return lval == rval;
+ case 1: return lval > rval;
+ default: assert(0); return false;
+ }
+ }
+ };
+
+ static filter_node_cptr operator_handler_mathop(const parser & token_left,const parser & token_right,int type) {
+ pfc::string8 left,right;
+ parse_string(token_left,left); parse_string(token_right,right);
+ return pfc::rcnew_t<filter_node_mathop>(left,right,type);
+ }
+
+ static filter_node_cptr operator_handler_greater(const parser & token_left,const parser & token_right)
+ {
+ return operator_handler_mathop(token_left,token_right,1);
+ }
+
+ static filter_node_cptr operator_handler_less(const parser & token_left,const parser & token_right)
+ {
+ return operator_handler_mathop(token_left,token_right,-1);
+ }
+
+ static filter_node_cptr operator_handler_equal(const parser & token_left,const parser & token_right)
+ {
+ return operator_handler_mathop(token_left,token_right,0);
+ }
+
+ struct operator_desc
+ {
+ const char * name;
+ bool right_to_left;
+ operator_handler handler;
+
+ bool test_name(const char * ptr,t_size len) const
+ {
+ const char * ptr2 = name;
+ while(len)
+ {
+ if (*ptr != *ptr2) return false;
+ ptr++;
+ ptr2++;
+ len--;
+ }
+ return *ptr2==0;
+ }
+ };
+
+ static operator_desc g_operators[] =
+ {
+ {"OR",false,operator_handler_or},
+ {"AND",false,operator_handler_and},
+ {"NOT",false,operator_handler_not},
+ {"HAS",false,operator_handler_has},
+ {"IS",false,operator_handler_is},
+ {"IST",false,operator_handler_is},
+ {"EQUAL",false,operator_handler_equal},
+ {"GREATER",false,operator_handler_greater},
+ {"LESS",false,operator_handler_less},
+ {"MISSING",false,operator_handler_missing},
+ };
+
+
+ static bool has_operators(const char * src) {
+ t_size n;
+ for(n=0;n<tabsize(g_operators);n++) {
+ const char * name = g_operators[n].name;
+ t_size namelen = strlen(name);
+ const char * ptr = src;
+ for(;;) {
+ ptr = strstr(ptr,name);
+ if (ptr) {
+ if (ptr && (ptr==src || is_spacing(ptr[-1])) && is_spacing_or_null(ptr[namelen])) return true;
+ ptr++;
+ }
+ else break;
+ }
+ }
+ return false;
+ }
+
+ struct token_info {
+ t_size ptr,len;
+ token_info() {}
+ token_info(t_size p_ptr,t_size p_len) : ptr(p_ptr), len(p_len) {}
+ };
+
+ static t_size test_operator(const char * ptr,t_size len) {
+ t_size n;
+ for(n=0;n<tabsize(g_operators);n++) {
+ if (g_operators[n].test_name(ptr,len)) return n;
+ }
+ return ~0;
+ }
+
+ static bool is_operator(const char * ptr,t_size len) {return test_operator(ptr,len)!=~0;}
+
+ filter_node_cptr filter_node::g_create(const parser & p_parser,bool b_allow_simple)
+ {
+ parser p(p_parser);
+
+ if (b_allow_simple)
+ {
+ if (!has_operators(pfc::string8(p.get_ptr(),p.get_remaining())))
+ {
+ pfc::string8 temp;
+ parse_string(p,temp);
+ return pfc::rcnew_t<filter_node_simple>(temp);
+ }
+ }
+
+ pfc::list_hybrid_t<token_info,8> operators;
+
+ p.skip_spacing();
+ while(p.get_remaining()>0)
+ {
+ t_size delta = p.test_token();
+ if (delta==0) throw exception_parse_error();
+ if (is_operator(p.get_ptr(),delta)) operators.add_item(token_info(p.get_offset(),delta));
+ p.advance(delta);
+ p.skip_spacing();
+ }
+
+ p.reset();
+
+ if (operators.get_count()>0)
+ {
+ t_size n;
+ for(n=0;n<tabsize(g_operators);n++)
+ {
+ if (g_operators[n].right_to_left)
+ {
+ t_size m;
+ for(m=operators.get_count()-1;m!=infinite;m--)
+ {
+ if (g_operators[n].test_name(p.get_ptr()+operators[m].ptr,operators[m].len))
+ {
+ t_size right_base = operators[m].ptr + operators[m].len;
+ return g_operators[n].handler(parser(p.get_ptr(),operators[m].ptr),parser(p.get_ptr()+right_base,p.get_remaining()-right_base));
+ }
+ }
+ }
+ else
+ {
+ t_size m;
+ for(m=0;m<operators.get_count();m++)
+ {
+ if (g_operators[n].test_name(p.get_ptr()+operators[m].ptr,operators[m].len))
+ {
+ t_size right_base = operators[m].ptr + operators[m].len;
+ return g_operators[n].handler(parser(p.get_ptr(),operators[m].ptr),parser(p.get_ptr()+right_base,p.get_remaining()-right_base));
+ }
+ }
+ }
+ }
+ throw exception_parse_error();
+ }
+ else
+ {
+ p.skip_spacing();
+ if (p.get_remaining()>0 && p.get_char()=='(')
+ {
+ t_size base = p.get_offset();
+ t_size len = p.skip_token();
+ if (len==0 || len<2) throw exception_parse_error();
+ if (!p.is_empty()) throw exception_parse_error();
+ p.reset(base+1);
+ return g_create(parser(p,len-2));
+ }
+ else if (b_allow_simple)
+ {
+ pfc::string8 temp;
+ parse_string(p,temp);
+ return pfc::rcnew_t<filter_node_simple>(temp);
+ }
+ throw exception_parse_error();
+ }
+ }
+
+ filter_node_cptr filter_node::g_create(const char * ptr,t_size len,bool b_allow_simple) {
+ return g_create(parser(ptr,len),b_allow_simple);
+ }
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/search_filter.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/search_filter.h
new file mode 100644
index 0000000..61d52d4
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/search_filter.h
@@ -0,0 +1,47 @@
+namespace search_tools {
+
+ PFC_DECLARE_EXCEPTION(exception_parse_error,pfc::exception,"Error parsing filter expression");
+
+ class filter_node;
+
+ typedef pfc::rcptr_const_t<filter_node> filter_node_cptr;
+ typedef pfc::rcptr_t<filter_node> filter_node_ptr;
+
+ class NOVTABLE filter_node {
+ public:
+ virtual bool test(const file_info * item,const metadb_handle_ptr & handle) const = 0;
+ virtual ~filter_node() {}
+ static filter_node_cptr g_create(const char * ptr,t_size len,bool b_allow_simple = false);
+ static filter_node_cptr g_create(const class parser & p,bool b_allow_simple = false);
+ };
+
+ class search_filter {
+ filter_node_cptr m_root;
+ public:
+ search_filter() {}
+ ~search_filter() {}
+ bool init(const char * pattern) {
+ try {
+ m_root = filter_node::g_create(pattern,strlen(pattern),true) ;
+ return true;
+ } catch(exception_parse_error) {return false;}
+ }
+
+ void deinit() {
+ m_root.release();
+ }
+
+ bool test(const file_info * item,const metadb_handle_ptr & handle) const {
+ return m_root.is_valid() ? m_root->test(item,handle) : false;
+ }
+
+ bool test(const metadb_handle_ptr & item) const {
+ bool rv = false;
+ const file_info * ptr;
+ if (item->get_info_locked(ptr)) rv = test(ptr,item);
+ return rv;
+ }
+ };
+
+
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/seekabilizer.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/seekabilizer.cpp
new file mode 100644
index 0000000..5173d39
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/seekabilizer.cpp
@@ -0,0 +1,218 @@
+#include "stdafx.h"
+
+enum {backread_on_seek = 1024};
+
+void seekabilizer_backbuffer::initialize(t_size p_size)
+{
+ m_depth = m_cursor = 0;
+
+ m_buffer.set_size(p_size);
+}
+
+void seekabilizer_backbuffer::write(const void * p_buffer,t_size p_bytes)
+{
+ if (p_bytes >= m_buffer.get_size())
+ {
+ memcpy(m_buffer.get_ptr(),(const t_uint8*)p_buffer + p_bytes - m_buffer.get_size(),m_buffer.get_size());
+ m_cursor = 0;
+ m_depth = m_buffer.get_size();
+ }
+ else
+ {
+ const t_uint8* sourceptr = (const t_uint8*) p_buffer;
+ t_size remaining = p_bytes;
+ while(remaining > 0)
+ {
+ t_size delta = m_buffer.get_size() - m_cursor;
+ if (delta > remaining) delta = remaining;
+
+ memcpy(m_buffer.get_ptr() + m_cursor,sourceptr,delta);
+
+ sourceptr += delta;
+ remaining -= delta;
+ m_cursor = (m_cursor + delta) % m_buffer.get_size();
+
+ m_depth = pfc::min_t<t_size>(m_buffer.get_size(),m_depth + delta);
+
+ }
+ }
+}
+
+void seekabilizer_backbuffer::read(t_size p_backlogdepth,void * p_buffer,t_size p_bytes) const
+{
+ assert(p_backlogdepth <= m_depth);
+ assert(p_backlogdepth >= p_bytes);
+
+
+ t_uint8* targetptr = (t_uint8*) p_buffer;
+ t_size remaining = p_bytes;
+ t_size cursor = (m_cursor + m_buffer.get_size() - p_backlogdepth) % m_buffer.get_size();
+
+ while(remaining > 0)
+ {
+ t_size delta = m_buffer.get_size() - cursor;
+ if (delta > remaining) delta = remaining;
+
+ memcpy(targetptr,m_buffer.get_ptr() + cursor,delta);
+
+ targetptr += delta;
+ remaining -= delta;
+ cursor = (cursor + delta) % m_buffer.get_size();
+ }
+}
+
+t_size seekabilizer_backbuffer::get_depth() const
+{
+ return m_depth;
+}
+
+t_size seekabilizer_backbuffer::get_max_depth() const
+{
+ return m_buffer.get_size();
+}
+
+void seekabilizer_backbuffer::reset()
+{
+ m_depth = m_cursor = 0;
+}
+
+
+void seekabilizer::initialize(service_ptr_t<file> p_base,t_size p_buffer_size,abort_callback & p_abort) {
+ m_buffer.initialize(p_buffer_size);
+ m_file = p_base;
+ m_position = m_position_base = 0;
+ m_size = m_file->get_size(p_abort);
+}
+
+void seekabilizer::g_seekabilize(service_ptr_t<file> & p_reader,t_size p_buffer_size,abort_callback & p_abort) {
+ if (p_reader.is_valid() && p_reader->is_remote() && p_buffer_size > 0) {
+ service_ptr_t<seekabilizer> instance = new service_impl_t<seekabilizer>();
+ instance->initialize(p_reader,p_buffer_size,p_abort);
+ p_reader = instance.get_ptr();
+ }
+}
+
+t_size seekabilizer::read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ p_abort.check_e();
+
+ if (m_position > m_position_base + pfc::max_t<t_size>(m_buffer.get_max_depth(),backread_on_seek) && m_file->can_seek()) {
+ t_filesize target = m_position;
+ if (target < backread_on_seek) target = 0;
+ else target -= backread_on_seek;
+ m_file->seek(target,p_abort);
+ m_position_base = target;
+ }
+
+ //seek ahead
+ while(m_position > m_position_base) {
+ enum {tempsize = 1024};
+ t_uint8 temp[tempsize];
+ t_size delta = (t_size) pfc::min_t<t_filesize>(tempsize,m_position - m_position_base);
+ t_size bytes_read = 0;
+ bytes_read = m_file->read(temp,delta,p_abort);
+ m_buffer.write(temp,bytes_read);
+ m_position_base += bytes_read;
+
+ if (bytes_read < delta) {
+ return 0;
+ }
+ }
+
+ t_size done = 0;
+ t_uint8 * targetptr = (t_uint8*) p_buffer;
+
+ //try to read backbuffer
+ if (m_position < m_position_base) {
+ if (m_position_base - m_position > (t_filesize)m_buffer.get_depth()) throw exception_io_seek_out_of_range();
+ t_size backread_depth = (t_size) (m_position_base - m_position);
+ t_size delta = pfc::min_t<t_size>(backread_depth,p_bytes-done);
+ m_buffer.read(backread_depth,targetptr,delta);
+ done += delta;
+ m_position += delta;
+ }
+
+ //regular read
+ if (done < p_bytes)
+ {
+ t_size bytes_read;
+ bytes_read = m_file->read(targetptr+done,p_bytes-done,p_abort);
+
+ m_buffer.write(targetptr+done,bytes_read);
+
+ done += bytes_read;
+ m_position += bytes_read;
+ m_position_base += bytes_read;
+ }
+
+ return done;
+}
+
+t_filesize seekabilizer::get_size(abort_callback & p_abort) {
+ p_abort.check_e();
+ return m_size;
+}
+
+t_filesize seekabilizer::get_position(abort_callback & p_abort) {
+ p_abort.check_e();
+ return m_position;
+}
+
+void seekabilizer::seek(t_filesize p_position,abort_callback & p_abort) {
+ assert(m_position_base >= m_buffer.get_depth());
+ p_abort.check_e();
+
+ if (m_size != filesize_invalid && p_position > m_size) throw exception_io_seek_out_of_range();
+
+ t_filesize lowest = m_position_base - m_buffer.get_depth();
+
+ if (p_position < lowest) {
+ if (m_file->can_seek()) {
+ m_buffer.reset();
+ t_filesize target = p_position;
+ t_size delta = m_buffer.get_max_depth();
+ if (delta > backread_on_seek) delta = backread_on_seek;
+ if (target > delta) target -= delta;
+ else target = 0;
+ m_file->seek(target,p_abort);
+ m_position_base = target;
+ }
+ else {
+ m_buffer.reset();
+ m_file->reopen(p_abort);
+ m_position_base = 0;
+ }
+ }
+
+ m_position = p_position;
+}
+
+bool seekabilizer::can_seek()
+{
+ return true;
+}
+
+bool seekabilizer::get_content_type(pfc::string_base & p_out) {return m_file->get_content_type(p_out);}
+
+bool seekabilizer::is_in_memory() {return false;}
+
+void seekabilizer::on_idle(abort_callback & p_abort) {return m_file->on_idle(p_abort);}
+
+t_filetimestamp seekabilizer::get_timestamp(abort_callback & p_abort) {
+ p_abort.check_e();
+ return m_file->get_timestamp(p_abort);
+}
+
+void seekabilizer::reopen(abort_callback & p_abort) {
+ if (m_position_base - m_buffer.get_depth() == 0) {
+ seek(0,p_abort);
+ } else {
+ m_position = m_position_base = 0;
+ m_buffer.reset();
+ m_file->reopen(p_abort);
+ }
+}
+
+bool seekabilizer::is_remote()
+{
+ return m_file->is_remote();
+}
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/seekabilizer.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/seekabilizer.h
new file mode 100644
index 0000000..454546b
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/seekabilizer.h
@@ -0,0 +1,36 @@
+class seekabilizer_backbuffer
+{
+public:
+ void initialize(t_size p_size);
+ void write(const void * p_buffer,t_size p_bytes);
+ void read(t_size p_backlogdepth,void * p_buffer,t_size p_bytes) const;
+ t_size get_depth() const;
+ void reset();
+ t_size get_max_depth() const;
+private:
+ pfc::array_t<t_uint8> m_buffer;
+ t_size m_depth,m_cursor;
+};
+
+class seekabilizer : public file_readonly {
+public:
+ void initialize(service_ptr_t<file> p_base,t_size p_buffer_size,abort_callback & p_abort);
+
+ static void g_seekabilize(service_ptr_t<file> & p_reader,t_size p_buffer_size,abort_callback & p_abort);
+
+ t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort);
+ t_filesize get_size(abort_callback & p_abort);
+ t_filesize get_position(abort_callback & p_abort);
+ void seek(t_filesize p_position,abort_callback & p_abort);
+ bool can_seek();
+ bool get_content_type(pfc::string_base & p_out);
+ bool is_in_memory();
+ void on_idle(abort_callback & p_abort);
+ t_filetimestamp get_timestamp(abort_callback & p_abort);
+ void reopen(abort_callback & p_abort);
+ bool is_remote();
+private:
+ service_ptr_t<file> m_file;
+ seekabilizer_backbuffer m_buffer;
+ t_filesize m_size,m_position,m_position_base;
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/stream_buffer_helper.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/stream_buffer_helper.cpp
new file mode 100644
index 0000000..6e6c099
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/stream_buffer_helper.cpp
@@ -0,0 +1,79 @@
+#include "stdafx.h"
+
+stream_reader_buffered::stream_reader_buffered(stream_reader * p_base,t_size p_buffer) : m_base(p_base)
+{
+ m_buffer.set_size(p_buffer);
+ m_buffer_ptr = 0;
+ m_buffer_max = 0;
+}
+
+t_size stream_reader_buffered::read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ p_abort.check_e();
+ char * output = (char*) p_buffer;
+ t_size output_ptr = 0;
+
+ while(output_ptr < p_bytes) {
+ {
+ t_size delta = pfc::min_t(p_bytes - output_ptr, m_buffer_max - m_buffer_ptr);
+ if (delta > 0)
+ {
+ memcpy(output + output_ptr, m_buffer.get_ptr() + m_buffer_ptr, delta);
+ output_ptr += delta;
+ m_buffer_ptr += delta;
+ }
+ }
+
+ if (m_buffer_ptr == m_buffer_max)
+ {
+ t_size bytes_read;
+ bytes_read = m_base->read(m_buffer.get_ptr(), m_buffer.get_size(), p_abort);
+ m_buffer_ptr = 0;
+ m_buffer_max = bytes_read;
+
+ if (m_buffer_max == 0) break;
+ }
+ }
+
+ return output_ptr;
+}
+
+stream_writer_buffered::stream_writer_buffered(stream_writer * p_base,t_size p_buffer)
+ : m_base(p_base)
+{
+ m_buffer.set_size(p_buffer);
+ m_buffer_ptr = 0;
+}
+
+void stream_writer_buffered::write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
+ p_abort.check_e();
+ const char * source = (const char*)p_buffer;
+ t_size source_remaining = p_bytes;
+ const t_size buffer_size = m_buffer.get_size();
+ if (source_remaining >= buffer_size)
+ {
+ flush(p_abort);
+ m_base->write_object(source,source_remaining,p_abort);
+ return;
+ }
+
+ if (m_buffer_ptr + source_remaining >= buffer_size)
+ {
+ t_size delta = buffer_size - m_buffer_ptr;
+ memcpy(m_buffer.get_ptr() + m_buffer_ptr, source,delta);
+ source += delta;
+ source_remaining -= delta;
+ m_buffer_ptr += delta;
+ flush(p_abort);
+ }
+
+ memcpy(m_buffer.get_ptr() + m_buffer_ptr, source,source_remaining);
+ m_buffer_ptr += source_remaining;
+}
+
+
+void stream_writer_buffered::flush(abort_callback & p_abort) {
+ if (m_buffer_ptr > 0) {
+ m_base->write_object(m_buffer.get_ptr(),m_buffer_ptr,p_abort);
+ m_buffer_ptr = 0;
+ }
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/stream_buffer_helper.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/stream_buffer_helper.h
new file mode 100644
index 0000000..b58c382
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/stream_buffer_helper.h
@@ -0,0 +1,26 @@
+class stream_reader_buffered : public stream_reader
+{
+public:
+ stream_reader_buffered(stream_reader * p_base,t_size p_buffer);
+ t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort);
+private:
+ stream_reader * m_base;
+ pfc::array_t<char> m_buffer;
+ t_size m_buffer_ptr, m_buffer_max;
+};
+
+class stream_writer_buffered : public stream_writer
+{
+public:
+ stream_writer_buffered(stream_writer * p_base,t_size p_buffer);
+
+ void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort);
+
+ void flush(abort_callback & p_abort);
+
+private:
+ stream_writer * m_base;
+ pfc::array_t<char> m_buffer;
+ t_size m_buffer_ptr;
+};
+
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/string_filter.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/string_filter.h
new file mode 100644
index 0000000..6507407
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/string_filter.h
@@ -0,0 +1,24 @@
+class string_filter_noncasesensitive {
+public:
+ string_filter_noncasesensitive(const char * p_string,t_size p_string_len = infinite) {
+ uStringLower(m_pattern,p_string,p_string_len);
+ }
+
+ bool test(const char * p_string,t_size p_string_len = infinite) const {
+ ::uStringLower(m_lowercasebuffer,p_string,p_string_len);
+ t_size walk = 0;
+ while(m_pattern[walk] != 0) {
+ while(m_pattern[walk] == ' ') walk++;
+ t_size delta = 0;
+ while(m_pattern[walk+delta] != 0 && m_pattern[walk+delta] != ' ') delta++;
+ if (delta > 0) {
+ if (pfc::string_find_first_ex(m_lowercasebuffer,infinite,m_pattern+walk,delta) == infinite) return false;
+ }
+ walk += delta;
+ }
+ return true;
+ }
+private:
+ mutable pfc::string8_fastalloc m_lowercasebuffer;
+ pfc::string8 m_pattern;
+};
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/text_file_loader.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/text_file_loader.cpp
new file mode 100644
index 0000000..ec63ff4
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/text_file_loader.cpp
@@ -0,0 +1,100 @@
+#include "StdAfx.h"
+
+static const unsigned char utf8_header[3] = {0xEF,0xBB,0xBF};
+
+namespace text_file_loader
+{
+ void write(const service_ptr_t<file> & p_file,abort_callback & p_abort,const char * p_string,bool is_utf8)
+ {
+ p_file->seek(0,p_abort);
+ p_file->set_eof(p_abort);
+ if (is_utf8)
+ {
+ p_file->write_object(utf8_header,sizeof(utf8_header),p_abort);
+ p_file->write_object(p_string,strlen(p_string),p_abort);
+ }
+ else
+ {
+ pfc::stringcvt::string_ansi_from_utf8 bah(p_string);
+ p_file->write_object(bah,bah.length(),p_abort);
+ }
+ }
+
+ void read(const service_ptr_t<file> & p_file,abort_callback & p_abort,pfc::string_base & p_out,bool & is_utf8) {
+ p_out.reset();
+ if (p_file->can_seek())
+ {
+ p_file->seek(0,p_abort);
+ }
+
+ pfc::array_t<char> mem;
+ t_filesize size64;
+ size64 = p_file->get_size(p_abort);
+ if (size64 == filesize_invalid)//typically HTTP
+ {
+ pfc::string8 ansitemp;
+ is_utf8 = false;
+ enum {delta = 1024*64, max = 1024*512};
+ char temp[3];
+ t_size done;
+ done = p_file->read(temp,3,p_abort);
+ if (done != 3)
+ {
+ if (done > 0) p_out = pfc::stringcvt::string_utf8_from_ansi(temp,done);
+ return;
+ }
+ if (!memcmp(utf8_header,temp,3)) is_utf8 = true;
+ else ansitemp.add_string(temp,3);
+
+ mem.set_size(delta);
+
+ for(;;)
+ {
+ done = p_file->read(mem.get_ptr(),delta,p_abort);
+ if (done > 0)
+ {
+ if (is_utf8) p_out.add_string(mem.get_ptr(),done);
+ else ansitemp.add_string(mem.get_ptr(),done);
+ }
+ if (done < delta) break;
+ }
+
+ if (!is_utf8)
+ {
+ p_out = pfc::stringcvt::string_utf8_from_ansi(ansitemp);
+ }
+
+ return;
+ }
+ else
+ {
+ if (size64>1024*1024*128) throw exception_io_data();//hard limit
+ t_size size = pfc::downcast_guarded<t_size>(size64);
+ mem.set_size(size+1);
+ char * asdf = mem.get_ptr();
+ p_file->read_object(asdf,size,p_abort);
+ asdf[size]=0;
+ if (size>3 && !memcmp(utf8_header,asdf,3)) {is_utf8 = true; p_out.add_string(asdf+3); }
+ else {
+ is_utf8 = false;
+ p_out = pfc::stringcvt::string_utf8_from_ansi(asdf);
+ }
+ return;
+ }
+ }
+
+ void write(const char * p_path,abort_callback & p_abort,const char * p_string,bool is_utf8)
+ {
+ service_ptr_t<file> f;
+ filesystem::g_open_write_new(f,p_path,p_abort);
+ write(f,p_abort,p_string,is_utf8);
+ }
+
+ void read(const char * p_path,abort_callback & p_abort,pfc::string_base & p_out,bool & is_utf8)
+ {
+ service_ptr_t<file> f;
+ filesystem::g_open_read(f,p_path,p_abort);
+ read(f,p_abort,p_out,is_utf8);
+ }
+
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/text_file_loader.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/text_file_loader.h
new file mode 100644
index 0000000..fd4b836
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/text_file_loader.h
@@ -0,0 +1,9 @@
+namespace text_file_loader
+{
+ void write(const service_ptr_t<file> & p_file,abort_callback & p_abort,const char * p_string,bool is_utf8);
+ void read(const service_ptr_t<file> & p_file,abort_callback & p_abort,pfc::string_base & p_out,bool & is_utf8);
+
+ void write(const char * p_path,abort_callback & p_abort,const char * p_string,bool is_utf8);
+ void read(const char * p_path,abort_callback & p_abort,pfc::string_base & p_out,bool & is_utf8);
+
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/wildcard.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/wildcard.cpp
new file mode 100644
index 0000000..63cbb03
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/wildcard.cpp
@@ -0,0 +1,44 @@
+#include "stdafx.h"
+
+static bool test_recur(const char * fn,const char * rm,bool b_sep)
+{
+ for(;;)
+ {
+ if ((b_sep && *rm==';') || *rm==0) return *fn==0;
+ else if (*rm=='*')
+ {
+ rm++;
+ do
+ {
+ if (test_recur(fn,rm,b_sep)) return true;
+ } while(pfc::utf8_advance(fn));
+ return false;
+ }
+ else if (*fn==0) return false;
+ else if (*rm!='?' && char_lower(pfc::utf8_get_char(fn))!=char_lower(pfc::utf8_get_char(rm))) return false;
+
+ fn = pfc::utf8_char_next(fn); rm = pfc::utf8_char_next(rm);
+ }
+}
+
+bool wildcard_helper::test_path(const char * path,const char * pattern,bool b_sep) {return test(path + pfc::scan_filename(path),pattern,b_sep);}
+
+bool wildcard_helper::test(const char * fn,const char * pattern,bool b_sep)
+{
+ if (!b_sep) return test_recur(fn,pattern,false);
+ const char * rm=pattern;
+ while(*rm)
+ {
+ if (test_recur(fn,rm,true)) return true;
+ while(*rm && *rm!=';') rm++;
+ if (*rm==';')
+ {
+ while(*rm==';') rm++;
+ while(*rm==' ') rm++;
+ }
+ };
+
+ return false;
+}
+
+bool wildcard_helper::has_wildcards(const char * str) {return strchr(str,'*') || strchr(str,'?');} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/wildcard.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/wildcard.h
new file mode 100644
index 0000000..4282094
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/wildcard.h
@@ -0,0 +1,11 @@
+#ifndef __FOOBAR2000_HELPER_WILDCARD_H__
+#define __FOOBAR2000_HELPER_WILDCARD_H__
+
+namespace wildcard_helper
+{
+ bool test_path(const char * path,const char * pattern,bool b_separate_by_semicolon = false);//will extract filename from path first
+ bool test(const char * str,const char * pattern,bool b_separate_by_semicolon = false);//tests if str matches pattern
+ bool has_wildcards(const char * str);
+};
+
+#endif //__FOOBAR2000_HELPER_WILDCARD_H__ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_dialog.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_dialog.cpp
new file mode 100644
index 0000000..613b366
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_dialog.cpp
@@ -0,0 +1,278 @@
+#include "stdafx.h"
+
+
+namespace dialog_helper {
+
+
+ INT_PTR CALLBACK dialog::DlgProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
+ {
+ dialog * p_this;
+ BOOL rv;
+ if (msg==WM_INITDIALOG)
+ {
+ p_this = reinterpret_cast<dialog*>(lp);
+ p_this->wnd = wnd;
+ SetWindowLongPtr(wnd,DWLP_USER,lp);
+
+ if (p_this->m_is_modal) p_this->m_modal_scope.initialize(wnd);
+ }
+ else p_this = reinterpret_cast<dialog*>(GetWindowLongPtr(wnd,DWLP_USER));
+
+ rv = p_this ? p_this->on_message(msg,wp,lp) : FALSE;
+
+ if (msg==WM_DESTROY && p_this)
+ {
+ SetWindowLongPtr(wnd,DWLP_USER,0);
+// p_this->wnd = 0;
+ }
+
+ return rv;
+ }
+
+
+ int dialog::run_modal(unsigned id,HWND parent)
+ {
+ assert(wnd == 0);
+ if (wnd != 0) return -1;
+ m_is_modal = true;
+ return uDialogBox(id,parent,DlgProc,reinterpret_cast<LPARAM>(this));
+ }
+ HWND dialog::run_modeless(unsigned id,HWND parent)
+ {
+ assert(wnd == 0);
+ if (wnd != 0) return 0;
+ m_is_modal = false;
+ return uCreateDialog(id,parent,DlgProc,reinterpret_cast<LPARAM>(this));
+ }
+
+ void dialog::end_dialog(int code)
+ {
+ assert(m_is_modal);
+ if (m_is_modal) uEndDialog(wnd,code);
+ }
+
+
+
+
+
+
+
+
+
+
+ int dialog_modal::run(unsigned p_id,HWND p_parent,HINSTANCE p_instance)
+ {
+ int status;
+
+ // note: uDialogBox() has its own modal scope, we don't want that to trigger
+ // if this is ever changed, move deinit to WM_DESTROY handler in DlgProc
+
+ status = (int)DialogBoxParam(p_instance,MAKEINTRESOURCE(p_id),p_parent,DlgProc,reinterpret_cast<LPARAM>(this));
+
+ m_modal_scope.deinitialize();
+
+ return status;
+ }
+
+ void dialog_modal::end_dialog(int p_code)
+ {
+ EndDialog(m_wnd,p_code);
+ }
+
+
+ INT_PTR CALLBACK dialog_modal::DlgProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
+ {
+ dialog_modal * _this;
+ if (msg==WM_INITDIALOG)
+ {
+ _this = reinterpret_cast<dialog_modal*>(lp);
+ _this->m_wnd = wnd;
+ SetWindowLongPtr(wnd,DWLP_USER,lp);
+
+ _this->m_modal_scope.initialize(wnd);
+ }
+ else _this = reinterpret_cast<dialog_modal*>(GetWindowLongPtr(wnd,DWLP_USER));
+
+ assert(_this == 0 || _this->m_wnd == wnd);
+
+ return _this ? _this->on_message(msg,wp,lp) : FALSE;
+ }
+
+
+ bool dialog_modeless::create(unsigned p_id,HWND p_parent,HINSTANCE p_instance) {
+ assert(!m_is_in_create);
+ if (m_is_in_create) return false;
+ pfc::vartoggle_t<bool> scope(m_is_in_create,true);
+ if (CreateDialogParam(p_instance,MAKEINTRESOURCE(p_id),p_parent,DlgProc,reinterpret_cast<LPARAM>(this)) == 0) return false;
+ return m_wnd != 0;
+ }
+
+ dialog_modeless::~dialog_modeless() {
+ assert(!m_is_in_create);
+ switch(m_destructor_status)
+ {
+ case destructor_none:
+ m_destructor_status = destructor_normal;
+ if (m_wnd != 0)
+ {
+ DestroyWindow(m_wnd);
+ m_wnd = 0;
+ }
+ break;
+ case destructor_fromwindow:
+ if (m_wnd != 0) SetWindowLongPtr(m_wnd,DWLP_USER,0);
+ break;
+ default:
+ //should never trigger
+ pfc::crash();
+ break;
+ }
+ }
+
+ void dialog_modeless::on_window_destruction()
+ {
+ if (m_is_in_create)
+ {
+ m_wnd = 0;
+ }
+ else
+ switch(m_destructor_status)
+ {
+ case destructor_none:
+ m_destructor_status = destructor_fromwindow;
+ delete this;
+ break;
+ case destructor_fromwindow:
+ pfc::crash();
+ break;
+ default:
+ break;
+ }
+ }
+
+ BOOL dialog_modeless::on_message_wrap(UINT msg,WPARAM wp,LPARAM lp)
+ {
+ if (m_destructor_status == destructor_none)
+ return on_message(msg,wp,lp);
+ else
+ return FALSE;
+ }
+
+ INT_PTR CALLBACK dialog_modeless::DlgProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
+ {
+ dialog_modeless * thisptr;
+ BOOL rv;
+ if (msg == WM_INITDIALOG)
+ {
+ thisptr = reinterpret_cast<dialog_modeless*>(lp);
+ thisptr->m_wnd = wnd;
+ SetWindowLongPtr(wnd,DWLP_USER,lp);
+ modeless_dialog_manager::g_add(wnd);
+ }
+ else thisptr = reinterpret_cast<dialog_modeless*>(GetWindowLongPtr(wnd,DWLP_USER));
+
+ rv = thisptr ? thisptr->on_message_wrap(msg,wp,lp) : FALSE;
+
+ if (msg == WM_DESTROY)
+ modeless_dialog_manager::g_remove(wnd);
+
+ if (msg == WM_DESTROY && thisptr != 0)
+ thisptr->on_window_destruction();
+
+ return rv;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ dialog_modeless_v2::dialog_modeless_v2(unsigned p_id,HWND p_parent,HINSTANCE p_instance,bool p_stealfocus) : m_wnd(0), m_status(status_construction), m_stealfocus(p_stealfocus)
+ {
+ SetLastError(NO_ERROR);
+ HWND result = CreateDialogParam(p_instance,MAKEINTRESOURCE(p_id),p_parent,DlgProc,reinterpret_cast<LPARAM>(this));
+ if (result == 0 || m_wnd == 0) throw exception_win32(GetLastError());
+ m_status = status_lifetime;
+ }
+
+ dialog_modeless_v2::~dialog_modeless_v2()
+ {
+ bool is_window_being_destroyed = (m_status == status_destruction_requested);
+ m_status = status_destruction;
+
+ if (m_wnd != 0)
+ {
+ if (is_window_being_destroyed)
+ detach_window();
+ else
+ DestroyWindow(m_wnd);
+ }
+ }
+
+ INT_PTR CALLBACK dialog_modeless_v2::DlgProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
+ {
+ dialog_modeless_v2 * thisptr;
+ BOOL rv = FALSE;
+ if (msg == WM_INITDIALOG)
+ {
+ thisptr = reinterpret_cast<dialog_modeless_v2*>(lp);
+ assert(thisptr->m_status == status_construction);
+ thisptr->m_wnd = wnd;
+ SetWindowLongPtr(wnd,DWLP_USER,lp);
+ modeless_dialog_manager::g_add(wnd);
+ }
+ else thisptr = reinterpret_cast<dialog_modeless_v2*>(GetWindowLongPtr(wnd,DWLP_USER));
+
+ if (thisptr != NULL) rv = thisptr->on_message_internal(msg,wp,lp);
+
+ if (msg == WM_DESTROY)
+ {
+ modeless_dialog_manager::g_remove(wnd);
+ }
+
+ return rv;
+ }
+
+
+ void dialog_modeless_v2::detach_window()
+ {
+ if (m_wnd != 0)
+ {
+ SetWindowLongPtr(m_wnd,DWLP_USER,0);
+ m_wnd = 0;
+ }
+ }
+
+
+ BOOL dialog_modeless_v2::on_message_internal(UINT msg,WPARAM wp,LPARAM lp)
+ {
+ if (m_status == status_lifetime || m_status == status_destruction_requested)
+ {
+ if (msg == WM_DESTROY)
+ {
+ assert(m_status == status_lifetime);
+ m_status = status_destruction_requested;
+ delete this;
+ return TRUE;
+ }
+ else
+ return on_message(msg,wp,lp);
+ }
+ else if (m_status == status_construction)
+ {
+ if (msg == WM_INITDIALOG) return m_stealfocus ? TRUE : FALSE;
+ else return FALSE;
+ }
+ else return FALSE;
+ }
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_dialog.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_dialog.h
new file mode 100644
index 0000000..eb0951b
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_dialog.h
@@ -0,0 +1,121 @@
+#ifndef _FOOBAR2000_HELPERS_WIN32_DIALOG_H_
+#define _FOOBAR2000_HELPERS_WIN32_DIALOG_H_
+
+
+namespace dialog_helper
+{
+ class dialog
+ {
+ protected:
+
+ dialog() : wnd(0), m_is_modal(false) {}
+ ~dialog() { }
+
+ virtual BOOL on_message(UINT msg,WPARAM wp,LPARAM lp)=0;
+
+ void end_dialog(int code);
+
+ public:
+ inline HWND get_wnd() {return wnd;}
+
+ int run_modal(unsigned id,HWND parent);
+
+ HWND run_modeless(unsigned id,HWND parent);
+ private:
+ HWND wnd;
+ static INT_PTR CALLBACK DlgProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp);
+
+ bool m_is_modal;
+
+ modal_dialog_scope m_modal_scope;
+ };
+
+
+ //! This class is meant to be instantiated on-stack, as a local variable. Using new/delete operators instead or even making this a member of another object works, but does not make much sense because of the way this works (single run() call).
+ class dialog_modal
+ {
+ public:
+ int run(unsigned p_id,HWND p_parent,HINSTANCE p_instance = core_api::get_my_instance());
+ protected:
+ virtual BOOL on_message(UINT msg,WPARAM wp,LPARAM lp)=0;
+
+ inline dialog_modal() : m_wnd(0) {}
+ void end_dialog(int p_code);
+ inline HWND get_wnd() const {return m_wnd;}
+ private:
+ static INT_PTR CALLBACK DlgProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp);
+
+ HWND m_wnd;
+ modal_dialog_scope m_modal_scope;
+ };
+
+
+ //! This class is meant to be used with new/delete operators only. Destroying the window - outside create() / WM_INITDIALOG - will result in object calling delete this. If object is deleted directly using delete operator, WM_DESTROY handler may not be called so it should not be used (use destructor of derived class instead).
+ //! Classes derived from dialog_modeless must not be instantiated in any other way than operator new().
+ /*! Typical usage : \n
+ class mydialog : public dialog_helper::dialog_modeless {...};
+ (...)
+ bool createmydialog()
+ {
+ mydialog * instance = new mydialog;
+ if (instance == 0) return flase;
+ if (!instance->create(...)) {delete instance; return false;}
+ return true;
+ }
+
+ */
+ class dialog_modeless
+ {
+ public:
+ //! Creates the dialog window. This will call on_message with WM_INITDIALOG. To abort creation, you can call DestroyWindow() on our window; it will not delete the object but make create() return false instead. You should not delete the object from inside WM_INITDIALOG handler or anything else possibly called from create().
+ //! @returns true on success, false on failure.
+ bool create(unsigned p_id,HWND p_parent,HINSTANCE p_instance = core_api::get_my_instance());
+ protected:
+ //! Standard windows message handler (DialogProc-style). Use get_wnd() to retrieve our dialog window handle.
+ virtual BOOL on_message(UINT msg,WPARAM wp,LPARAM lp)=0;
+
+ inline dialog_modeless() : m_wnd(0), m_destructor_status(destructor_none), m_is_in_create(false) {}
+ inline HWND get_wnd() const {return m_wnd;}
+ virtual ~dialog_modeless();
+ private:
+ static INT_PTR CALLBACK DlgProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp);
+ void on_window_destruction();
+
+ BOOL on_message_wrap(UINT msg,WPARAM wp,LPARAM lp);
+
+ HWND m_wnd;
+ enum {destructor_none,destructor_normal,destructor_fromwindow} m_destructor_status;
+ bool m_is_in_create;
+ };
+
+#pragma deprecated(dialog_modeless)
+
+
+
+ class dialog_modeless_v2
+ {
+ protected:
+ explicit dialog_modeless_v2(unsigned p_id,HWND p_parent,HINSTANCE p_instance = core_api::get_my_instance(),bool p_stealfocus = true);
+ virtual ~dialog_modeless_v2();
+ HWND get_wnd() const {return m_wnd;}
+ virtual BOOL on_message(UINT msg,WPARAM wp,LPARAM lp) {return FALSE;}
+
+ static dialog_modeless_v2 * __unsafe__instance_from_window(HWND p_wnd) {return reinterpret_cast<dialog_modeless_v2*>(GetWindowLongPtr(p_wnd,DWLP_USER));}
+ private:
+ static INT_PTR CALLBACK DlgProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp);
+ void detach_window();
+ BOOL on_message_internal(UINT msg,WPARAM wp,LPARAM lp);
+ enum {status_construction, status_lifetime, status_destruction_requested, status_destruction} m_status;
+ HWND m_wnd;
+ const bool m_stealfocus;
+
+ const dialog_modeless_v2 & operator=(const dialog_modeless_v2 &);
+ dialog_modeless_v2(const dialog_modeless_v2 &);
+ };
+
+
+};
+
+
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_misc.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_misc.cpp
new file mode 100644
index 0000000..d8328cc
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_misc.cpp
@@ -0,0 +1,68 @@
+#include "stdafx.h"
+
+void registerclass_scope_delayed::toggle_on(UINT p_style,WNDPROC p_wndproc,int p_clsextra,int p_wndextra,HICON p_icon,HCURSOR p_cursor,HBRUSH p_background,const TCHAR * p_class_name,const TCHAR * p_menu_name) {
+ toggle_off();
+ WNDCLASS wc;
+ memset(&wc,0,sizeof(wc));
+ wc.style = p_style;
+ wc.lpfnWndProc = p_wndproc;
+ wc.cbClsExtra = p_clsextra;
+ wc.cbWndExtra = p_wndextra;
+ wc.hInstance = core_api::get_my_instance();
+ wc.hIcon = p_icon;
+ wc.hCursor = p_cursor;
+ wc.hbrBackground = p_background;
+ wc.lpszMenuName = p_menu_name;
+ wc.lpszClassName = p_class_name;
+ SetLastError(NO_ERROR);
+ m_class = RegisterClass(&wc);
+ if (m_class == 0) throw ::exception_win32(GetLastError());
+}
+
+void registerclass_scope_delayed::toggle_off() {
+ if (m_class != 0) {
+ UnregisterClass((LPCTSTR)m_class,core_api::get_my_instance());
+ m_class = 0;
+ }
+}
+
+namespace {
+ class clipboard_scope {
+ public:
+ clipboard_scope() : m_open(false) {}
+ ~clipboard_scope() {close();}
+ bool open(HWND p_owner) {
+ close();
+ if (OpenClipboard(p_owner) == TRUE) {
+ m_open = true;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ void close() {
+ if (m_open) {
+ m_open = false;
+ CloseClipboard();
+ }
+ }
+ private:
+ bool m_open;
+ };
+};
+bool uGetClipboardString(pfc::string_base & p_out) {
+ clipboard_scope scope;
+ if (!scope.open(NULL)) return false;
+ HANDLE data = GetClipboardData(
+#ifdef UNICODE
+ CF_UNICODETEXT
+#else
+ CF_TEXT
+#endif
+ );
+ if (data == NULL) return false;
+
+ CGlobalLock lock(data);
+ p_out = pfc::stringcvt::string_utf8_from_os( (const TCHAR*) lock.GetPtr(), lock.GetSize() / sizeof(TCHAR) );
+ return true;
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_misc.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_misc.h
new file mode 100644
index 0000000..db61a29
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/win32_misc.h
@@ -0,0 +1,168 @@
+class registerclass_scope_delayed {
+public:
+ registerclass_scope_delayed() : m_class(0) {}
+
+ bool is_registered() const {return m_class != 0;}
+ void toggle_on(UINT p_style,WNDPROC p_wndproc,int p_clsextra,int p_wndextra,HICON p_icon,HCURSOR p_cursor,HBRUSH p_background,const TCHAR * p_classname,const TCHAR * p_menuname);
+ void toggle_off();
+ ATOM get_class() const {return m_class;}
+
+ ~registerclass_scope_delayed() {toggle_off();}
+private:
+ registerclass_scope_delayed(const registerclass_scope_delayed &) {throw pfc::exception_not_implemented();}
+ const registerclass_scope_delayed & operator=(const registerclass_scope_delayed &) {throw pfc::exception_not_implemented();}
+
+ ATOM m_class;
+};
+
+
+
+template<typename t_object>
+class syncd_storage {
+private:
+ typedef syncd_storage<t_object> t_self;
+public:
+ syncd_storage() {}
+ template<typename t_source>
+ syncd_storage(const t_source & p_source) : m_object(p_source) {}
+ template<typename t_source>
+ void set(t_source const & p_in) {
+ insync(m_sync);
+ m_object = p_in;
+ }
+ template<typename t_destination>
+ void get(t_destination & p_out) const {
+ insync(m_sync);
+ p_out = m_object;
+ }
+ t_object get() const {
+ insync(m_sync);
+ return m_object;
+ }
+ template<typename t_source>
+ const t_self & operator=(t_source const & p_source) {set(p_source); return *this;}
+private:
+ mutable critical_section m_sync;
+ t_object m_object;
+};
+
+template<typename t_object>
+class syncd_storage_flagged {
+private:
+ typedef syncd_storage_flagged<t_object> t_self;
+public:
+ syncd_storage_flagged() : m_changed_flag(false) {}
+ template<typename t_source>
+ syncd_storage_flagged(const t_source & p_source) : m_changed_flag(false), m_object(p_source) {}
+ void set_changed(bool p_flag = true) {
+ insync(m_sync);
+ m_changed_flag = p_flag;
+ }
+ template<typename t_source>
+ void set(t_source const & p_in) {
+ insync(m_sync);
+ m_object = p_in;
+ m_changed_flag = true;
+ }
+ bool has_changed() const {
+ insync(m_sync);
+ return m_changed_flag;
+ }
+ t_object peek() const {insync(m_sync); return m_object;}
+ template<typename t_destination>
+ bool get_if_changed(t_destination & p_out) {
+ insync(m_sync);
+ if (m_changed_flag) {
+ p_out = m_object;
+ m_changed_flag = false;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ t_object get() {
+ insync(m_sync);
+ m_changed_flag = false;
+ return m_object;
+ }
+ template<typename t_destination>
+ void get(t_destination & p_out) {
+ insync(m_sync);
+ p_out = m_object;
+ m_changed_flag = false;
+ }
+ template<typename t_source>
+ const t_self & operator=(t_source const & p_source) {set(p_source); return *this;}
+private:
+ bool m_changed_flag;
+ mutable critical_section m_sync;
+ t_object m_object;
+};
+
+class CGlobalLock {
+public:
+ CGlobalLock(HGLOBAL p_handle) : m_handle(p_handle), m_ptr(GlobalLock(p_handle)) {}
+ ~CGlobalLock() {
+ if (m_ptr != NULL) GlobalUnlock(m_handle);
+ }
+ void * GetPtr() const {return m_ptr;}
+ t_size GetSize() const {return GlobalSize(m_handle);}
+private:
+ void * m_ptr;
+ HGLOBAL m_handle;
+};
+
+bool uGetClipboardString(pfc::string_base & p_out);
+
+
+
+#ifdef __ATLWIN_H__
+
+class CMenuSelectionReceiver : public CWindowImpl<CMenuSelectionReceiver> {
+public:
+ CMenuSelectionReceiver(HWND p_parent) {
+ SetLastError(NO_ERROR);
+ if (Create(p_parent) == NULL) throw exception_win32(GetLastError());
+ }
+ ~CMenuSelectionReceiver() {
+ DestroyWindow();
+ }
+ typedef CWindowImpl<CMenuSelectionReceiver> _baseClass;
+ DECLARE_WND_CLASS_EX(TEXT("{DF0087DB-E765-4283-BBAB-6AB2E8AB64A1}"),0,0);
+
+ BEGIN_MSG_MAP(CMenuSelectionReceiver)
+ MESSAGE_HANDLER(WM_MENUSELECT,OnMenuSelect)
+ END_MSG_MAP()
+protected:
+ virtual bool QueryHint(unsigned p_id,pfc::string_base & p_out) {
+ return false;
+ }
+private:
+ LRESULT OnMenuSelect(UINT,WPARAM p_wp,LPARAM p_lp,BOOL&) {
+ if (p_lp != 0) {
+ if (HIWORD(p_wp) & MF_POPUP) {
+ m_status.release();
+ } else {
+ pfc::string8 msg;
+ if (!QueryHint(LOWORD(p_wp),msg)) {
+ m_status.release();
+ } else {
+ if (m_status.is_empty()) {
+ if (!static_api_ptr_t<ui_control>()->override_status_text_create(m_status)) m_status.release();
+ }
+ if (m_status.is_valid()) {
+ m_status->override_text(msg);
+ }
+ }
+ }
+ } else {
+ m_status.release();
+ }
+ return 0;
+ }
+
+ service_ptr_t<ui_status_text_override> m_status;
+
+ PFC_CLASS_NOT_COPYABLE(CMenuSelectionReceiver,CMenuSelectionReceiver);
+};
+#endif //#ifdef __ATLWIN_H__
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/window_placement_helper.cpp b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/window_placement_helper.cpp
new file mode 100644
index 0000000..e1b5994
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/window_placement_helper.cpp
@@ -0,0 +1,202 @@
+#include "stdafx.h"
+
+static bool g_is_enabled()
+{
+ return standard_config_objects::query_remember_window_positions();
+}
+
+static BOOL CALLBACK __MonitorEnumProc(
+ HMONITOR hMonitor, // handle to display monitor
+ HDC hdcMonitor, // handle to monitor DC
+ LPRECT lprcMonitor, // monitor intersection rectangle
+ LPARAM dwData // data
+ ) {
+ RECT * clip = (RECT*)dwData;
+ RECT newclip;
+ UnionRect(&newclip,clip,lprcMonitor);
+ *clip = newclip;
+ return TRUE;
+}
+
+static bool test_rect(const RECT * rc) {
+ RECT clip = {};
+ if (EnumDisplayMonitors(NULL,NULL,__MonitorEnumProc,(LPARAM)&clip)) {
+ const LONG sanitycheck = 4;
+ const LONG cwidth = clip.right - clip.left;
+ const LONG cheight = clip.bottom - clip.top;
+
+ const LONG width = rc->right - rc->left;
+ const LONG height = rc->bottom - rc->top;
+
+ if (width > cwidth * sanitycheck || height > cheight * sanitycheck) return false;
+ }
+
+ return MonitorFromRect(rc,MONITOR_DEFAULTTONULL) != NULL;
+}
+
+
+
+bool cfg_window_placement::read_from_window(HWND window)
+{
+ WINDOWPLACEMENT wp;
+ memset(&wp,0,sizeof(wp));
+ if (g_is_enabled())
+ {
+ wp.length = sizeof(wp);
+ if (!GetWindowPlacement(window,&wp))
+ memset(&wp,0,sizeof(wp));
+ /*else
+ {
+ if (!IsWindowVisible(window)) wp.showCmd = SW_HIDE;
+ }*/
+ }
+ m_data = wp;
+ return m_data.length == sizeof(m_data);
+}
+
+bool cfg_window_placement::on_window_creation(HWND window)
+{
+ bool ret = false;
+ PFC_ASSERT(!m_windows.have_item(window));
+ m_windows.add_item(window);
+
+ if (g_is_enabled())
+ {
+ if (m_data.length==sizeof(m_data) && test_rect(&m_data.rcNormalPosition))
+ {
+ if (SetWindowPlacement(window,&m_data))
+ {
+ ret = true;
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+void cfg_window_placement::on_window_destruction(HWND window)
+{
+ if (m_windows.have_item(window))
+ {
+ read_from_window(window);
+ m_windows.remove_item(window);
+ }
+}
+
+void cfg_window_placement::get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {
+ if (g_is_enabled()) {
+ {
+ t_size n, m = m_windows.get_count();
+ for(n=0;n<m;n++) {
+ HWND window = m_windows[n];
+ PFC_ASSERT(IsWindow(window));
+ if (IsWindow(window) && read_from_window(window)) break;
+ }
+ }
+
+ if (m_data.length == sizeof(m_data)) {
+ p_stream->write_object(&m_data,sizeof(m_data),p_abort);
+ }
+ }
+}
+
+void cfg_window_placement::set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
+ WINDOWPLACEMENT temp;
+ try {
+ p_stream->read_object(&temp,sizeof(temp),p_abort);
+ } catch(exception_io_data const &) {return;}
+ if (temp.length == sizeof(temp)) m_data = temp;
+}
+
+
+cfg_window_placement::cfg_window_placement(const GUID & p_guid) : cfg_var(p_guid)
+{
+ memset(&m_data,0,sizeof(m_data));
+}
+
+
+cfg_window_size::cfg_window_size(const GUID & p_guid) : cfg_var(p_guid), m_width(infinite32), m_height(infinite32) {}
+
+static BOOL SetWindowSize(HWND p_wnd,unsigned p_x,unsigned p_y)
+{
+ if (p_x != infinite32 && p_y != infinite32)
+ return SetWindowPos(p_wnd,0,0,0,p_x,p_y,SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
+ else
+ return FALSE;
+}
+
+bool cfg_window_size::on_window_creation(HWND p_wnd)
+{
+ bool ret = false;
+ PFC_ASSERT(!m_windows.have_item(p_wnd));
+ m_windows.add_item(p_wnd);
+
+ if (g_is_enabled())
+ {
+ if (SetWindowSize(p_wnd,m_width,m_height)) ret = true;
+ }
+
+ return ret;
+}
+
+void cfg_window_size::on_window_destruction(HWND p_wnd)
+{
+ if (m_windows.have_item(p_wnd))
+ {
+ read_from_window(p_wnd);
+ m_windows.remove_item(p_wnd);
+ }
+}
+
+bool cfg_window_size::read_from_window(HWND p_wnd)
+{
+ if (g_is_enabled())
+ {
+ RECT r;
+ if (GetWindowRect(p_wnd,&r))
+ {
+ m_width = r.right - r.left;
+ m_height = r.bottom - r.top;
+ return true;
+ }
+ else
+ {
+ m_width = m_height = infinite32;
+ return false;
+ }
+ }
+ else
+ {
+ m_width = m_height = infinite32;
+ return false;
+ }
+}
+
+void cfg_window_size::get_data_raw(stream_writer * p_stream,abort_callback & p_abort) {
+ if (g_is_enabled()) {
+ {
+ t_size n, m = m_windows.get_count();
+ for(n=0;n<m;n++) {
+ HWND window = m_windows[n];
+ PFC_ASSERT(IsWindow(window));
+ if (IsWindow(window) && read_from_window(window)) break;
+ }
+ }
+
+ if (m_width != infinite32 && m_height != infinite32) {
+ p_stream->write_lendian_t(m_width,p_abort);
+ p_stream->write_lendian_t(m_height,p_abort);
+ }
+ }
+}
+
+void cfg_window_size::set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
+ t_uint32 width,height;
+ try {
+ p_stream->read_lendian_t(width,p_abort);
+ p_stream->read_lendian_t(height,p_abort);
+ } catch(exception_io_data const &) {return;}
+
+ m_width = width; m_height = height;
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/window_placement_helper.h b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/window_placement_helper.h
new file mode 100644
index 0000000..dbe276d
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/helpers/window_placement_helper.h
@@ -0,0 +1,33 @@
+#ifndef _WINDOW_PLACEMENT_HELPER_H_
+#define _WINDOW_PLACEMENT_HELPER_H_
+
+class cfg_window_placement : public cfg_var
+{
+public:
+ bool on_window_creation(HWND window);//returns true if window position has been changed, false if not
+ void on_window_destruction(HWND window);
+ bool read_from_window(HWND window);
+ void get_data_raw(stream_writer * p_stream,abort_callback & p_abort);
+ void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort);
+ cfg_window_placement(const GUID & p_guid);
+private:
+ pfc::list_hybrid_t<HWND,2> m_windows;
+ WINDOWPLACEMENT m_data;
+};
+
+class cfg_window_size : public cfg_var
+{
+public:
+ bool on_window_creation(HWND window);//returns true if window position has been changed, false if not
+ void on_window_destruction(HWND window);
+ bool read_from_window(HWND window);
+ void get_data_raw(stream_writer * p_stream,abort_callback & p_abort);
+ void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort);
+ cfg_window_size(const GUID & p_guid);
+private:
+ pfc::list_hybrid_t<HWND,2> m_windows;
+ t_uint32 m_width,m_height;
+};
+
+
+#endif //_WINDOW_PLACEMENT_HELPER_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/shared/audio_math.h b/Plugins/listeningto/players/foo_mlt/foobar2000/shared/audio_math.h
new file mode 100644
index 0000000..f58c171
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/shared/audio_math.h
@@ -0,0 +1,78 @@
+#include <math.h>
+
+#ifdef _M_X64
+#include <xmmintrin.h>
+#include <emmintrin.h>
+#endif
+
+
+#define audio_sample_size 32
+
+#if audio_sample_size == 32
+typedef float audio_sample;
+#define audio_sample_asm dword
+#elif audio_sample_size == 64
+typedef double audio_sample;
+#define audio_sample_asm qword
+#else
+#error wrong audio_sample_size
+#endif
+
+#define audio_sample_bytes (audio_sample_size/8)
+
+namespace audio_math
+{
+ //! p_source/p_output can point to same buffer
+ void SHARED_EXPORT scale(const audio_sample * p_source,t_size p_count,audio_sample * p_output,audio_sample p_scale);
+ void SHARED_EXPORT convert_to_int16(const audio_sample * p_source,t_size p_count,t_int16 * p_output,audio_sample p_scale);
+ void SHARED_EXPORT convert_to_int32(const audio_sample * p_source,t_size p_count,t_int32 * p_output,audio_sample p_scale);
+ audio_sample SHARED_EXPORT convert_to_int16_calculate_peak(const audio_sample * p_source,t_size p_count,t_int16 * p_output,audio_sample p_scale);
+ void SHARED_EXPORT convert_from_int16(const t_int16 * p_source,t_size p_count,audio_sample * p_output,audio_sample p_scale);
+ void SHARED_EXPORT convert_from_int32(const t_int32 * p_source,t_size p_count,audio_sample * p_output,audio_sample p_scale);
+ audio_sample SHARED_EXPORT convert_to_int32_calculate_peak(const audio_sample * p_source,t_size p_count,t_int32 * p_output,audio_sample p_scale);
+ audio_sample SHARED_EXPORT calculate_peak(const audio_sample * p_source,t_size p_count);
+ void SHARED_EXPORT remove_denormals(audio_sample * p_buffer,t_size p_count);
+ void SHARED_EXPORT add_offset(audio_sample * p_buffer,audio_sample p_delta,t_size p_count);
+
+
+ inline t_uint64 time_to_samples(double p_time,t_uint32 p_sample_rate) {
+ return (t_uint64)floor((double)p_sample_rate * p_time + 0.5);
+ }
+
+ inline double samples_to_time(t_uint64 p_samples,t_uint32 p_sample_rate) {
+ PFC_ASSERT(p_sample_rate > 0);
+ return (double) p_samples / (double) p_sample_rate;
+ }
+
+
+#ifdef _M_IX86
+ inline static t_int64 rint64(audio_sample val) {
+ t_int64 rv;
+ _asm {
+ fld val;
+ fistp rv;
+ }
+ return rv;
+ }
+ inline static t_int32 rint32(audio_sample val) {
+ t_int32 rv;
+ _asm {
+ fld val;
+ fistp rv;
+ }
+ return rv;
+ }
+#elif defined(_M_X64)
+ inline static t_int64 rint64(audio_sample val) {return (t_int64)floor(val+0.5);}
+ static inline t_int32 rint32(float p_val) {
+ return (t_int32)_mm_cvtss_si32(_mm_load_ss(&p_val));
+ }
+#else
+ inline static t_int64 rint64(audio_sample val) {return (t_int64)floor(val+0.5);}
+ inline static t_int32 rint32(audio_sample val) {return (t_int32)floor(val+0.5);}
+#endif
+
+
+ inline audio_sample gain_to_scale(double p_gain) {return (audio_sample) pow(10.0,p_gain / 20.0);}
+
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/shared/shared.h b/Plugins/listeningto/players/foo_mlt/foobar2000/shared/shared.h
new file mode 100644
index 0000000..05db496
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/shared/shared.h
@@ -0,0 +1,655 @@
+#ifndef _SHARED_DLL__SHARED_H_
+#define _SHARED_DLL__SHARED_H_
+
+#include "../../pfc/pfc.h"
+
+#ifndef WIN32
+#error N/A
+#endif
+
+#ifndef STRICT
+#define STRICT
+#endif
+
+#include <windows.h>
+#include <ddeml.h>
+#include <commctrl.h>
+
+#ifndef NOTHROW
+#ifdef _MSC_VER
+#define NOTHROW __declspec(nothrow)
+#else
+#define NOTHROW
+#endif
+#endif
+
+#define SHARED_API /*NOTHROW*/ __stdcall
+
+#ifndef SHARED_EXPORTS
+#define SHARED_EXPORT __declspec(dllimport) SHARED_API
+#else
+#define SHARED_EXPORT __declspec(dllexport) SHARED_API
+#endif
+
+extern "C" {
+
+//SHARED_EXPORT BOOL IsUnicode();
+#ifdef UNICODE
+#define IsUnicode() 1
+#else
+#define IsUnicode() 0
+#endif
+
+LRESULT SHARED_EXPORT uSendMessageText(HWND wnd,UINT msg,WPARAM wp,const char * text);
+LRESULT SHARED_EXPORT uSendDlgItemMessageText(HWND wnd,UINT id,UINT msg,WPARAM wp,const char * text);
+BOOL SHARED_EXPORT uGetWindowText(HWND wnd,pfc::string_base & out);
+BOOL SHARED_EXPORT uSetWindowText(HWND wnd,const char * p_text);
+BOOL SHARED_EXPORT uSetWindowTextEx(HWND wnd,const char * p_text,unsigned p_text_length);
+BOOL SHARED_EXPORT uGetDlgItemText(HWND wnd,UINT id,pfc::string_base & out);
+BOOL SHARED_EXPORT uSetDlgItemText(HWND wnd,UINT id,const char * p_text);
+BOOL SHARED_EXPORT uSetDlgItemTextEx(HWND wnd,UINT id,const char * p_text,unsigned p_text_length);
+BOOL SHARED_EXPORT uBrowseForFolder(HWND parent,const char * title,pfc::string_base & out);
+BOOL SHARED_EXPORT uBrowseForFolderWithFile(HWND parent,const char * title,pfc::string_base & out,const char * p_file_to_find);
+int SHARED_EXPORT uMessageBox(HWND wnd,const char * text,const char * caption,UINT type);
+void SHARED_EXPORT uOutputDebugString(const char * msg);
+BOOL SHARED_EXPORT uAppendMenu(HMENU menu,UINT flags,UINT_PTR id,const char * content);
+BOOL SHARED_EXPORT uInsertMenu(HMENU menu,UINT position,UINT flags,UINT_PTR id,const char * content);
+int SHARED_EXPORT uStringCompare(const char * elem1, const char * elem2);
+int SHARED_EXPORT uCharCompare(t_uint32 p_char1,t_uint32 p_char2);
+int SHARED_EXPORT uStringCompare_ConvertNumbers(const char * elem1,const char * elem2);
+HINSTANCE SHARED_EXPORT uLoadLibrary(const char * name);
+HANDLE SHARED_EXPORT uCreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualReset,BOOL bInitialState, const char * lpName);
+DWORD SHARED_EXPORT uGetModuleFileName(HMODULE hMod,pfc::string_base & out);
+BOOL SHARED_EXPORT uSetClipboardString(const char * ptr);
+BOOL SHARED_EXPORT uIsDialogMessage(HWND dlg,LPMSG msg);
+BOOL SHARED_EXPORT uGetMessage(LPMSG msg,HWND wnd,UINT min,UINT max);
+BOOL SHARED_EXPORT uGetClassName(HWND wnd,pfc::string_base & out);
+t_size SHARED_EXPORT uCharLength(const char * src);
+BOOL SHARED_EXPORT uDragQueryFile(HDROP hDrop,UINT idx,pfc::string_base & out);
+UINT SHARED_EXPORT uDragQueryFileCount(HDROP hDrop);
+BOOL SHARED_EXPORT uGetTextExtentPoint32(HDC dc,const char * text,UINT cb,LPSIZE size);//note, cb is number of bytes, not actual unicode characters in the string (read: plain strlen() will do)
+BOOL SHARED_EXPORT uExtTextOut(HDC dc,int x,int y,UINT flags,const RECT * rect,const char * text,UINT cb,const int * lpdx);
+BOOL SHARED_EXPORT uTextOutColors(HDC dc,const char * src,UINT len,int x,int y,const RECT * clip,BOOL is_selected,DWORD default_color);
+BOOL SHARED_EXPORT uTextOutColorsTabbed(HDC dc,const char * src,UINT src_len,const RECT * item,int border,const RECT * clip,BOOL selected,DWORD default_color,BOOL use_columns);
+UINT SHARED_EXPORT uGetTextHeight(HDC dc);
+UINT SHARED_EXPORT uGetFontHeight(HFONT font);
+BOOL SHARED_EXPORT uChooseColor(DWORD * p_color,HWND parent,DWORD * p_custom_colors);
+HCURSOR SHARED_EXPORT uLoadCursor(HINSTANCE hIns,const char * name);
+HICON SHARED_EXPORT uLoadIcon(HINSTANCE hIns,const char * name);
+HMENU SHARED_EXPORT uLoadMenu(HINSTANCE hIns,const char * name);
+BOOL SHARED_EXPORT uGetEnvironmentVariable(const char * name,pfc::string_base & out);
+HMODULE SHARED_EXPORT uGetModuleHandle(const char * name);
+UINT SHARED_EXPORT uRegisterWindowMessage(const char * name);
+BOOL SHARED_EXPORT uMoveFile(const char * src,const char * dst);
+BOOL SHARED_EXPORT uDeleteFile(const char * fn);
+DWORD SHARED_EXPORT uGetFileAttributes(const char * fn);
+BOOL SHARED_EXPORT uFileExists(const char * fn);
+BOOL SHARED_EXPORT uRemoveDirectory(const char * fn);
+HANDLE SHARED_EXPORT uCreateFile(const char * p_path,DWORD p_access,DWORD p_sharemode,LPSECURITY_ATTRIBUTES p_security_attributes,DWORD p_createmode,DWORD p_flags,HANDLE p_template);
+HANDLE SHARED_EXPORT uCreateFileMapping(HANDLE hFile,LPSECURITY_ATTRIBUTES lpFileMappingAttributes,DWORD flProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,const char * lpName);
+BOOL SHARED_EXPORT uCreateDirectory(const char * fn,LPSECURITY_ATTRIBUTES blah);
+HANDLE SHARED_EXPORT uCreateMutex(LPSECURITY_ATTRIBUTES blah,BOOL bInitialOwner,const char * name);
+BOOL SHARED_EXPORT uGetLongPathName(const char * name,pfc::string_base & out);//may just fail to work on old windows versions, present on win98/win2k+
+BOOL SHARED_EXPORT uGetFullPathName(const char * name,pfc::string_base & out);
+BOOL SHARED_EXPORT uSearchPath(const char * path, const char * filename, const char * extension, pfc::string_base & p_out);
+BOOL SHARED_EXPORT uFixPathCaps(const char * path,pfc::string_base & p_out);
+void SHARED_EXPORT uGetCommandLine(pfc::string_base & out);
+BOOL SHARED_EXPORT uGetTempPath(pfc::string_base & out);
+BOOL SHARED_EXPORT uGetTempFileName(const char * path_name,const char * prefix,UINT unique,pfc::string_base & out);
+BOOL SHARED_EXPORT uGetOpenFileName(HWND parent,const char * p_ext_mask,unsigned def_ext_mask,const char * p_def_ext,const char * p_title,const char * p_directory,pfc::string_base & p_filename,BOOL b_save);
+//note: uGetOpenFileName extension mask uses | as separator, not null
+HANDLE SHARED_EXPORT uLoadImage(HINSTANCE hIns,const char * name,UINT type,int x,int y,UINT flags);
+UINT SHARED_EXPORT uRegisterClipboardFormat(const char * name);
+BOOL SHARED_EXPORT uGetClipboardFormatName(UINT format,pfc::string_base & out);
+BOOL SHARED_EXPORT uFormatSystemErrorMessage(pfc::string_base & p_out,DWORD p_code);
+
+HANDLE SHARED_EXPORT uSortStringCreate(const char * src);
+int SHARED_EXPORT uSortStringCompare(HANDLE string1,HANDLE string2);
+int SHARED_EXPORT uSortStringCompareEx(HANDLE string1,HANDLE string2,DWORD flags);//flags - see win32 CompareString
+int SHARED_EXPORT uSortPathCompare(HANDLE string1,HANDLE string2);
+void SHARED_EXPORT uSortStringFree(HANDLE string);
+
+
+int SHARED_EXPORT uCompareString(DWORD flags,const char * str1,unsigned len1,const char * str2,unsigned len2);
+
+class NOVTABLE uGetOpenFileNameMultiResult : public pfc::list_base_const_t<const char*>
+{
+public:
+ inline t_size GetCount() {return get_count();}
+ inline const char * GetFileName(t_size index) {return get_item(index);}
+ virtual ~uGetOpenFileNameMultiResult() {}
+};
+
+typedef uGetOpenFileNameMultiResult * puGetOpenFileNameMultiResult;
+
+puGetOpenFileNameMultiResult SHARED_EXPORT uGetOpenFileNameMulti(HWND parent,const char * p_ext_mask,unsigned def_ext_mask,const char * p_def_ext,const char * p_title,const char * p_directory);
+
+class NOVTABLE uFindFile
+{
+protected:
+ uFindFile() {}
+public:
+ virtual BOOL FindNext()=0;
+ virtual const char * GetFileName()=0;
+ virtual t_uint64 GetFileSize()=0;
+ virtual DWORD GetAttributes()=0;
+ virtual FILETIME GetCreationTime()=0;
+ virtual FILETIME GetLastAccessTime()=0;
+ virtual FILETIME GetLastWriteTime()=0;
+ virtual ~uFindFile() {};
+ inline bool IsDirectory() {return (GetAttributes() & FILE_ATTRIBUTE_DIRECTORY) ? true : false;}
+};
+
+typedef uFindFile * puFindFile;
+
+puFindFile SHARED_EXPORT uFindFirstFile(const char * path);
+
+HINSTANCE SHARED_EXPORT uShellExecute(HWND wnd,const char * oper,const char * file,const char * params,const char * dir,int cmd);
+HWND SHARED_EXPORT uCreateStatusWindow(LONG style,const char * text,HWND parent,UINT id);
+
+BOOL SHARED_EXPORT uShellNotifyIcon(DWORD dwMessage,HWND wnd,UINT id,UINT callbackmsg,HICON icon,const char * tip);
+BOOL SHARED_EXPORT uShellNotifyIconEx(DWORD dwMessage,HWND wnd,UINT id,UINT callbackmsg,HICON icon,const char * tip,const char * balloon_title,const char * balloon_msg);
+
+HWND SHARED_EXPORT uCreateWindowEx(DWORD dwExStyle,const char * lpClassName,const char * lpWindowName,DWORD dwStyle,int x,int y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam);
+
+BOOL SHARED_EXPORT uGetSystemDirectory(pfc::string_base & out);
+BOOL SHARED_EXPORT uGetWindowsDirectory(pfc::string_base & out);
+BOOL SHARED_EXPORT uSetCurrentDirectory(const char * path);
+BOOL SHARED_EXPORT uGetCurrentDirectory(pfc::string_base & out);
+BOOL SHARED_EXPORT uExpandEnvironmentStrings(const char * src,pfc::string_base & out);
+BOOL SHARED_EXPORT uGetUserName(pfc::string_base & out);
+BOOL SHARED_EXPORT uGetShortPathName(const char * src,pfc::string_base & out);
+
+HSZ SHARED_EXPORT uDdeCreateStringHandle(DWORD ins,const char * src);
+BOOL SHARED_EXPORT uDdeQueryString(DWORD ins,HSZ hsz,pfc::string_base & out);
+UINT SHARED_EXPORT uDdeInitialize(LPDWORD pidInst,PFNCALLBACK pfnCallback,DWORD afCmd,DWORD ulRes);
+BOOL SHARED_EXPORT uDdeAccessData_Text(HDDEDATA data,pfc::string_base & out);
+
+HIMAGELIST SHARED_EXPORT uImageList_LoadImage(HINSTANCE hi, const char * lpbmp, int cx, int cGrow, COLORREF crMask, UINT uType, UINT uFlags);
+
+#define uDdeFreeStringHandle DdeFreeStringHandle
+#define uDdeCmpStringHandles DdeCmpStringHandles
+#define uDdeKeepStringHandle DdeKeepStringHandle
+#define uDdeUninitialize DdeUninitialize
+#define uDdeNameService DdeNameService
+#define uDdeFreeDataHandle DdeFreeDataHandle
+
+
+typedef TVINSERTSTRUCTA uTVINSERTSTRUCT;
+
+HTREEITEM SHARED_EXPORT uTreeView_InsertItem(HWND wnd,const uTVINSERTSTRUCT * param);
+LPARAM SHARED_EXPORT uTreeView_GetUserData(HWND wnd,HTREEITEM item);
+bool SHARED_EXPORT uTreeView_GetText(HWND wnd,HTREEITEM item,pfc::string_base & out);
+
+#define uSetWindowsHookEx SetWindowsHookEx
+#define uUnhookWindowsHookEx UnhookWindowsHookEx
+#define uCallNextHookEx CallNextHookEx
+
+
+/* usage:
+
+ const char * src = "something";
+
+ void * temp = malloc(uOSStringEstimateSize(src));
+ uOSStringConvert(src,temp);
+ //now temp contains OS-friendly (TCHAR) version of src
+*/
+
+typedef TCITEMA uTCITEM;
+int SHARED_EXPORT uTabCtrl_InsertItem(HWND wnd,t_size idx,const uTCITEM * item);
+int SHARED_EXPORT uTabCtrl_SetItem(HWND wnd,t_size idx,const uTCITEM * item);
+
+int SHARED_EXPORT uGetKeyNameText(LONG lparam,pfc::string_base & out);
+
+void SHARED_EXPORT uFixAmpersandChars(const char * src,pfc::string_base & out);//for systray
+void SHARED_EXPORT uFixAmpersandChars_v2(const char * src,pfc::string_base & out);//for other controls
+
+//deprecated
+t_size SHARED_EXPORT uPrintCrashInfo(LPEXCEPTION_POINTERS param,const char * extrainfo,char * out);
+enum {uPrintCrashInfo_max_length = 1024};
+
+void SHARED_EXPORT uPrintCrashInfo_Init(const char * name);//called only by exe on startup
+void SHARED_EXPORT uPrintCrashInfo_AddInfo(const char * p_info);//called only by exe on startup
+void SHARED_EXPORT uPrintCrashInfo_SetDumpPath(const char * name);//called only by exe on startup
+
+
+void SHARED_EXPORT uDumpCrashInfo(LPEXCEPTION_POINTERS param);
+
+BOOL SHARED_EXPORT uListBox_GetText(HWND listbox,UINT index,pfc::string_base & out);
+
+void SHARED_EXPORT uPrintfV(pfc::string_base & out,const char * fmt,va_list arglist);
+static inline void uPrintf(pfc::string_base & out,const char * fmt,...) {va_list list;va_start(list,fmt);uPrintfV(out,fmt,list);va_end(list);}
+
+
+class NOVTABLE uResource
+{
+public:
+ virtual const void * GetPointer() = 0;
+ virtual unsigned GetSize() = 0;
+ virtual ~uResource() {}
+};
+
+typedef uResource* puResource;
+
+puResource SHARED_EXPORT uLoadResource(HMODULE hMod,const char * name,const char * type,WORD wLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) );
+puResource SHARED_EXPORT LoadResourceEx(HMODULE hMod,const TCHAR * name,const TCHAR * type,WORD wLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) );
+HRSRC SHARED_EXPORT uFindResource(HMODULE hMod,const char * name,const char * type,WORD wLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) );
+
+BOOL SHARED_EXPORT uLoadString(HINSTANCE ins,UINT id,pfc::string_base & out);
+
+UINT SHARED_EXPORT uCharLower(UINT c);
+UINT SHARED_EXPORT uCharUpper(UINT c);
+
+BOOL SHARED_EXPORT uGetMenuString(HMENU menu,UINT id,pfc::string_base & out,UINT flag);
+BOOL SHARED_EXPORT uModifyMenu(HMENU menu,UINT id,UINT flags,UINT newitem,const char * data);
+UINT SHARED_EXPORT uGetMenuItemType(HMENU menu,UINT position);
+
+
+}//extern "C"
+
+inline char * uCharNext(char * src) {return src+uCharLength(src);}
+inline const char * uCharNext(const char * src) {return src+uCharLength(src);}
+
+
+class string_utf8_from_window
+{
+public:
+ string_utf8_from_window(HWND wnd)
+ {
+ uGetWindowText(wnd,m_data);
+ }
+ string_utf8_from_window(HWND wnd,UINT id)
+ {
+ uGetDlgItemText(wnd,id,m_data);
+ }
+ inline operator const char * () const {return m_data.get_ptr();}
+ inline t_size length() const {return m_data.length();}
+ inline bool is_empty() const {return length() == 0;}
+ inline const char * get_ptr() const {return m_data.get_ptr();}
+private:
+ pfc::string8 m_data;
+};
+
+#define uMAKEINTRESOURCE(x) ((const char*)LOWORD(x))
+
+#ifdef _DEBUG
+class critical_section {
+private:
+ CRITICAL_SECTION sec;
+ int count;
+public:
+ int enter() {EnterCriticalSection(&sec);return ++count;}
+ int leave() {int rv = --count;LeaveCriticalSection(&sec);return rv;}
+ int get_lock_count() {return count;}
+ int get_lock_count_check() {enter();return leave();}
+ inline void assert_locked() {assert(get_lock_count_check()>0);}
+ inline void assert_not_locked() {assert(get_lock_count_check()==0);}
+ critical_section() {InitializeCriticalSection(&sec);count=0;}
+ ~critical_section() {DeleteCriticalSection(&sec);}
+private:
+ critical_section(const critical_section&) {throw pfc::exception_not_implemented();}
+ const critical_section & operator=(const critical_section &) {throw pfc::exception_not_implemented();}
+};
+#else
+class critical_section {
+private:
+ CRITICAL_SECTION sec;
+public:
+ void enter() throw() {EnterCriticalSection(&sec);}
+ void leave() throw() {LeaveCriticalSection(&sec);}
+ critical_section() {InitializeCriticalSection(&sec);}
+ ~critical_section() {DeleteCriticalSection(&sec);}
+private:
+ critical_section(const critical_section&) {throw pfc::exception_not_implemented();}
+ const critical_section & operator=(const critical_section &) {throw pfc::exception_not_implemented();}
+};
+#endif
+class c_insync
+{
+private:
+ critical_section & m_section;
+public:
+ c_insync(critical_section * p_section) throw() : m_section(*p_section) {m_section.enter();}
+ c_insync(critical_section & p_section) throw() : m_section(p_section) {m_section.enter();}
+ ~c_insync() throw() {m_section.leave();}
+};
+
+#define insync(X) c_insync blah____sync(X)
+
+
+class critical_section2 //smarter version, has try_enter()
+{
+private:
+ HANDLE hMutex;
+ int count;
+public:
+ int enter() {return enter_timeout(INFINITE);}
+ int leave() {int rv = --count;ReleaseMutex(hMutex);return rv;}
+ int get_lock_count() {return count;}
+ int get_lock_count_check()
+ {
+ int val = try_enter();
+ if (val>0) val = leave();
+ return val;
+ }
+ int enter_timeout(DWORD t) {return WaitForSingleObject(hMutex,t)==WAIT_OBJECT_0 ? ++count : 0;}
+ int try_enter() {return enter_timeout(0);}
+ int check_count() {enter();return leave();}
+ critical_section2()
+ {
+ hMutex = uCreateMutex(0,0,0);
+ count=0;
+ }
+ ~critical_section2() {CloseHandle(hMutex);}
+
+ inline void assert_locked() {assert(get_lock_count_check()>0);}
+ inline void assert_not_locked() {assert(get_lock_count_check()==0);}
+
+};
+
+class c_insync2
+{
+private:
+ critical_section2 * ptr;
+public:
+ c_insync2(critical_section2 * p) {ptr=p;ptr->enter();}
+ c_insync2(critical_section2 & p) {ptr=&p;ptr->enter();}
+ ~c_insync2() {ptr->leave();}
+};
+
+#define insync2(X) c_insync2 blah____sync2(X)
+
+
+//other
+
+#define uIsDialogMessage IsDialogMessage
+#define uGetMessage GetMessage
+#define uPeekMessage PeekMessage
+#define uDispatchMessage DispatchMessage
+
+#define uCallWindowProc CallWindowProc
+#define uDefWindowProc DefWindowProc
+#define uGetWindowLong GetWindowLong
+#define uSetWindowLong SetWindowLong
+
+#define uEndDialog EndDialog
+#define uDestroyWindow DestroyWindow
+#define uGetDlgItem GetDlgItem
+#define uEnableWindow EnableWindow
+#define uGetDlgItemInt GetDlgItemInt
+#define uSetDlgItemInt SetDlgItemInt
+
+#define __uHookWindowProc(WND,PROC) ((WNDPROC)SetWindowLongPtr(WND,GWLP_WNDPROC,(LONG_PTR)(PROC)))
+static WNDPROC uHookWindowProc(HWND p_wnd,WNDPROC p_proc) {return __uHookWindowProc(p_wnd,p_proc);}
+
+#define uCreateToolbarEx CreateToolbarEx
+#define uIsBadStringPtr IsBadStringPtrA
+#define uSendMessage SendMessage
+#define uSendDlgItemMessage SendDlgItemMessage
+#define uSendMessageTimeout SendMessageTimeout
+#define uSendNotifyMessage SendNotifyMessage
+#define uSendMessageCallback SendMessageCallback
+#define uPostMessage PostMessage
+#define uPostThreadMessage PostThreadMessage
+
+
+class string_print_crash
+{
+ char block[uPrintCrashInfo_max_length];
+public:
+ inline operator const char * () const {return block;}
+ inline const char * get_ptr() const {return block;}
+ inline t_size length() {return strlen(block);}
+ inline string_print_crash(LPEXCEPTION_POINTERS param,const char * extrainfo = 0) {uPrintCrashInfo(param,extrainfo,block);}
+};
+
+class uStringPrintf
+{
+public:
+ inline explicit uStringPrintf(const char * fmt,...)
+ {
+ va_list list;
+ va_start(list,fmt);
+ uPrintfV(m_data,fmt,list);
+ va_end(list);
+ }
+ inline operator const char * () const {return m_data.get_ptr();}
+ inline t_size length() const {return m_data.length();}
+ inline bool is_empty() const {return length() == 0;}
+ inline const char * get_ptr() const {return m_data.get_ptr();}
+private:
+ pfc::string8_fastalloc m_data;
+};
+#pragma deprecated(uStringPrintf, uPrintf, uPrintfV)
+
+inline LRESULT uButton_SetCheck(HWND wnd,UINT id,bool state) {return uSendDlgItemMessage(wnd,id,BM_SETCHECK,state ? BST_CHECKED : BST_UNCHECKED,0); }
+inline bool uButton_GetCheck(HWND wnd,UINT id) {return uSendDlgItemMessage(wnd,id,BM_GETCHECK,0,0) == BST_CHECKED;}
+
+class uCallStackTracker
+{
+ t_size param;
+public:
+ explicit SHARED_EXPORT uCallStackTracker(const char * name);
+ SHARED_EXPORT ~uCallStackTracker();
+};
+
+extern "C"
+{
+ LPCSTR SHARED_EXPORT uGetCallStackPath();
+}
+
+#if 1
+#define TRACK_CALL(X) uCallStackTracker TRACKER__##X(#X)
+#define TRACK_CALL_TEXT(X) uCallStackTracker TRACKER__BLAH(X)
+#define TRACK_CODE(description,code) {uCallStackTracker __call_tracker(description); code;}
+#else
+#define TRACK_CALL(X)
+#define TRACK_CALL_TEXT(X)
+#define TRACK_CODE(description,code) {code;}
+#endif
+
+extern "C" {
+int SHARED_EXPORT stricmp_utf8(const char * p1,const char * p2);
+int SHARED_EXPORT stricmp_utf8_ex(const char * p1,t_size len1,const char * p2,t_size len2);
+int SHARED_EXPORT stricmp_utf8_stringtoblock(const char * p1,const char * p2,t_size p2_bytes);
+int SHARED_EXPORT stricmp_utf8_partial(const char * p1,const char * p2,t_size num = ~0);
+int SHARED_EXPORT stricmp_utf8_max(const char * p1,const char * p2,t_size p1_bytes);
+t_size SHARED_EXPORT uReplaceStringAdd(pfc::string_base & out,const char * src,t_size src_len,const char * s1,t_size len1,const char * s2,t_size len2,bool casesens);
+t_size SHARED_EXPORT uReplaceCharAdd(pfc::string_base & out,const char * src,t_size src_len,unsigned c1,unsigned c2,bool casesens);
+//all lengths in uReplaceString functions are optional, set to -1 if parameters is a simple null-terminated string
+void SHARED_EXPORT uAddStringLower(pfc::string_base & out,const char * src,t_size len = ~0);
+void SHARED_EXPORT uAddStringUpper(pfc::string_base & out,const char * src,t_size len = ~0);
+}
+
+class comparator_stricmp_utf8 {
+public:
+ static int compare(const char * p_string1,const char * p_string2) {return stricmp_utf8(p_string1,p_string2);}
+};
+
+inline void uStringLower(pfc::string_base & out,const char * src,t_size len = ~0) {out.reset();uAddStringLower(out,src,len);}
+inline void uStringUpper(pfc::string_base & out,const char * src,t_size len = ~0) {out.reset();uAddStringUpper(out,src,len);}
+
+inline t_size uReplaceString(pfc::string_base & out,const char * src,t_size src_len,const char * s1,t_size len1,const char * s2,t_size len2,bool casesens)
+{
+ out.reset();
+ return uReplaceStringAdd(out,src,src_len,s1,len1,s2,len2,casesens);
+}
+
+inline t_size uReplaceChar(pfc::string_base & out,const char * src,t_size src_len,unsigned c1,unsigned c2,bool casesens)
+{
+ out.reset();
+ return uReplaceCharAdd(out,src,src_len,c1,c2,casesens);
+}
+
+class string_lower
+{
+public:
+ explicit string_lower(const char * ptr,t_size p_count = ~0) {uAddStringLower(m_data,ptr,p_count);}
+ inline operator const char * () const {return m_data.get_ptr();}
+ inline t_size length() const {return m_data.length();}
+ inline bool is_empty() const {return length() == 0;}
+ inline const char * get_ptr() const {return m_data.get_ptr();}
+private:
+ pfc::string8 m_data;
+};
+
+class string_upper
+{
+public:
+ explicit string_upper(const char * ptr,t_size p_count = ~0) {uAddStringUpper(m_data,ptr,p_count);}
+ inline operator const char * () const {return m_data.get_ptr();}
+ inline t_size length() const {return m_data.length();}
+ inline bool is_empty() const {return length() == 0;}
+ inline const char * get_ptr() const {return m_data.get_ptr();}
+private:
+ pfc::string8 m_data;
+};
+
+inline UINT char_lower(UINT c) {return uCharLower(c);}
+inline UINT char_upper(UINT c) {return uCharUpper(c);}
+
+inline BOOL uGetLongPathNameEx(const char * name,pfc::string_base & out)
+{
+ if (uGetLongPathName(name,out)) return TRUE;
+ return uGetFullPathName(name,out);
+}
+
+struct t_font_description
+{
+ enum
+ {
+ m_facename_length = LF_FACESIZE*2,
+ m_height_dpi = 480,
+ };
+
+ t_uint32 m_height;
+ t_uint32 m_weight;
+ t_uint8 m_italic;
+ t_uint8 m_charset;
+ char m_facename[m_facename_length];
+
+ HFONT SHARED_EXPORT create() const;
+ bool SHARED_EXPORT popup_dialog(HWND p_parent);
+ void SHARED_EXPORT from_font(HFONT p_font);
+ static t_font_description SHARED_EXPORT g_from_font(HFONT p_font);
+};
+
+
+struct t_modal_dialog_entry
+{
+ HWND m_wnd_to_poke;
+ bool m_in_use;
+};
+
+extern "C" {
+ void SHARED_EXPORT ModalDialog_Switch(t_modal_dialog_entry & p_entry);
+ void SHARED_EXPORT ModalDialog_PokeExisting();
+ bool SHARED_EXPORT ModalDialog_CanCreateNew();
+
+ HWND SHARED_EXPORT FindOwningPopup(HWND p_wnd);
+ void SHARED_EXPORT PokeWindow(HWND p_wnd);
+};
+
+//! The purpose of modal_dialog_scope is to help to avoid the modal dialog recursion problem. Current toplevel modal dialog handle is stored globally, so when creation of a new modal dialog is blocked, it can be activated to indicate the reason for the task being blocked.
+class modal_dialog_scope {
+public:
+ //! This constructor initializes the modal dialog scope with specified dialog handle.
+ inline modal_dialog_scope(HWND p_wnd) : m_initialized(false) {initialize(p_wnd);}
+ //! This constructor leaves the scope uninitialized (you can call initialize() later with your window handle).
+ inline modal_dialog_scope() : m_initialized(false) {}
+ inline ~modal_dialog_scope() {deinitialize();}
+
+ //! Returns whether creation of a new modal dialog is allowed (false when there's another one active).\n
+ //! NOTE: when calling context is already inside a modal dialog that you own, you should not be checking this before creating a new modal dialog.
+ inline static bool can_create() {return ModalDialog_CanCreateNew();}
+ //! Activates the top-level modal dialog existing, if one exists.
+ inline static void poke_existing() {ModalDialog_PokeExisting();}
+
+ //! Initializes the scope with specified window handle.
+ void initialize(HWND p_wnd)
+ {
+ if (!m_initialized)
+ {
+ m_initialized = true;
+ m_entry.m_in_use = true;
+ m_entry.m_wnd_to_poke = p_wnd;
+ ModalDialog_Switch(m_entry);
+ }
+ }
+
+ void deinitialize()
+ {
+ if (m_initialized)
+ {
+ ModalDialog_Switch(m_entry);
+ m_initialized = false;
+ }
+ }
+
+
+
+private:
+ modal_dialog_scope(const modal_dialog_scope & p_scope) {assert(0);}
+ const modal_dialog_scope & operator=(const modal_dialog_scope &) {assert(0); return *this;}
+
+ t_modal_dialog_entry m_entry;
+
+ bool m_initialized;
+};
+
+class format_win32_error {
+public:
+ format_win32_error(DWORD p_code) {
+ if (!uFormatSystemErrorMessage(m_buffer,p_code)) m_buffer << "Unknown error code (" << (unsigned)p_code << ")";
+ }
+
+ const char * get_ptr() const {return m_buffer.get_ptr();}
+ operator const char*() const {return m_buffer.get_ptr();}
+private:
+ pfc::string8 m_buffer;
+};
+
+struct exception_win32 : public std::exception {
+ exception_win32(DWORD p_code) : std::exception(format_win32_error(p_code)), m_code(p_code) {}
+ DWORD get_code() const {return m_code;}
+private:
+ DWORD m_code;
+};
+
+
+class uDebugLog : public pfc::string_formatter {
+public:
+ ~uDebugLog() {*this << "\n"; uOutputDebugString(get_ptr());}
+};
+
+static void uAddWindowStyle(HWND p_wnd,LONG p_style) {
+ SetWindowLong(p_wnd,GWL_STYLE, GetWindowLong(p_wnd,GWL_STYLE) | p_style);
+}
+
+static void uRemoveWindowStyle(HWND p_wnd,LONG p_style) {
+ SetWindowLong(p_wnd,GWL_STYLE, GetWindowLong(p_wnd,GWL_STYLE) & ~p_style);
+}
+
+static void uAddWindowExStyle(HWND p_wnd,LONG p_style) {
+ SetWindowLong(p_wnd,GWL_EXSTYLE, GetWindowLong(p_wnd,GWL_EXSTYLE) | p_style);
+}
+
+static void uRemoveWindowExStyle(HWND p_wnd,LONG p_style) {
+ SetWindowLong(p_wnd,GWL_EXSTYLE, GetWindowLong(p_wnd,GWL_EXSTYLE) & ~p_style);
+}
+
+static unsigned MapDialogWidth(HWND p_dialog,unsigned p_value) {
+ RECT temp;
+ temp.left = 0; temp.right = p_value; temp.top = temp.bottom = 0;
+ if (!MapDialogRect(p_dialog,&temp)) return 0;
+ return temp.right;
+}
+
+static bool IsKeyPressed(unsigned vk) {
+ return (GetKeyState(vk) & 0x8000) ? true : false;
+}
+
+#include "audio_math.h"
+#include "win32_misc.h"
+
+#endif //_SHARED_DLL__SHARED_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/shared/shared.lib b/Plugins/listeningto/players/foo_mlt/foobar2000/shared/shared.lib
new file mode 100644
index 0000000..eb23dce
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/shared/shared.lib
Binary files differ
diff --git a/Plugins/listeningto/players/foo_mlt/foobar2000/shared/win32_misc.h b/Plugins/listeningto/players/foo_mlt/foobar2000/shared/win32_misc.h
new file mode 100644
index 0000000..f5c42cf
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/foobar2000/shared/win32_misc.h
@@ -0,0 +1,194 @@
+class win32_menu {
+public:
+ win32_menu(HMENU p_initval) : m_menu(p_initval) {}
+ win32_menu() : m_menu(NULL) {}
+ ~win32_menu() {release();}
+ void release() {
+ if (m_menu != NULL) {
+ DestroyMenu(m_menu);
+ m_menu = NULL;
+ }
+ }
+ void set(HMENU p_menu) {release(); m_menu = p_menu;}
+ void create_popup() {
+ release();
+ SetLastError(NO_ERROR);
+ m_menu = CreatePopupMenu();
+ if (m_menu == NULL) throw exception_win32(GetLastError());
+ }
+ HMENU get() const {return m_menu;}
+ HMENU detach() {return pfc::replace_t(m_menu,(HMENU)NULL);}
+
+ bool is_valid() const {return m_menu != NULL;}
+private:
+ win32_menu(const win32_menu &) {throw pfc::exception_not_implemented();}
+ const win32_menu & operator=(const win32_menu &) {throw pfc::exception_not_implemented();}
+
+ HMENU m_menu;
+};
+
+class win32_font {
+public:
+ win32_font(HFONT p_initval) : m_font(p_initval) {}
+ win32_font() : m_font(NULL) {}
+ ~win32_font() {release();}
+
+ void release() {
+ HFONT temp = detach();
+ if (temp != NULL) DeleteObject(temp);
+ }
+
+ void set(HFONT p_font) {release(); m_font = p_font;}
+ HFONT get() const {return m_font;}
+ HFONT detach() {return pfc::replace_t(m_font,(HFONT)NULL);}
+
+ void create(const t_font_description & p_desc) {
+ SetLastError(NO_ERROR);
+ HFONT temp = p_desc.create();
+ if (temp == NULL) throw exception_win32(GetLastError());
+ set(temp);
+ }
+
+ bool is_valid() const {return m_font != NULL;}
+
+private:
+ win32_font(const win32_font&) {throw pfc::exception_not_implemented();}
+ const win32_font & operator=(const win32_font &) {throw pfc::exception_not_implemented();}
+
+ HFONT m_font;
+};
+
+class win32_event {
+public:
+ win32_event() : m_handle(NULL) {}
+ ~win32_event() {release();}
+
+ void create(bool p_manualreset,bool p_initialstate) {
+ release();
+ SetLastError(NO_ERROR);
+ m_handle = CreateEvent(NULL,p_manualreset ? TRUE : FALSE, p_initialstate ? TRUE : FALSE,NULL);
+ if (m_handle == NULL) throw exception_win32(GetLastError());
+ }
+
+ void set(HANDLE p_handle) {release(); m_handle = p_handle;}
+ HANDLE get() const {return m_handle;}
+ HANDLE detach() {return pfc::replace_t(m_handle,(HANDLE)NULL);}
+ bool is_valid() const {return m_handle != NULL;}
+
+ void release() {
+ HANDLE temp = detach();
+ if (temp != NULL) CloseHandle(temp);
+ }
+
+
+ //! Returns true when signaled, false on timeout
+ bool wait_for(double p_timeout_seconds) {return g_wait_for(get(),p_timeout_seconds);}
+
+ static DWORD g_calculate_wait_time(double p_seconds) {
+ DWORD time = 0;
+ if (p_seconds> 0) {
+ time = audio_math::rint32((audio_sample)(p_seconds * 1000.0));
+ if (time == 0) time = 1;
+ } else if (p_seconds < 0) {
+ time = INFINITE;
+ }
+ return time;
+ }
+
+ //! Returns true when signaled, false on timeout
+ static bool g_wait_for(HANDLE p_event,double p_timeout_seconds) {
+ SetLastError(NO_ERROR);
+ DWORD status = WaitForSingleObject(p_event,g_calculate_wait_time(p_timeout_seconds));
+ switch(status) {
+ case WAIT_FAILED:
+ throw exception_win32(GetLastError());
+ default:
+ throw pfc::exception_bug_check();
+ case WAIT_OBJECT_0:
+ return true;
+ case WAIT_TIMEOUT:
+ return false;
+ }
+ }
+
+ void set_state(bool p_state) {
+ PFC_ASSERT(m_handle != NULL);
+ if (p_state) SetEvent(m_handle);
+ else ResetEvent(m_handle);
+ }
+
+private:
+ win32_event(const win32_event&) {throw pfc::exception_not_implemented();}
+ const win32_event & operator=(const win32_event &) {throw pfc::exception_not_implemented();}
+
+ HANDLE m_handle;
+};
+
+static void uSleepSeconds(double p_time,bool p_alertable) {
+ SleepEx(win32_event::g_calculate_wait_time(p_time),p_alertable ? TRUE : FALSE);
+}
+
+
+
+
+class win32_icon {
+public:
+ win32_icon(HICON p_initval) : m_icon(p_initval) {}
+ win32_icon() : m_icon(NULL) {}
+ ~win32_icon() {release();}
+
+ void release() {
+ HICON temp = detach();
+ if (temp != NULL) DestroyIcon(temp);
+ }
+
+ void set(HICON p_icon) {release(); m_icon = p_icon;}
+ HICON get() const {return m_icon;}
+ HICON detach() {return pfc::replace_t(m_icon,(HICON)NULL);}
+
+ bool is_valid() const {return m_icon != NULL;}
+
+private:
+ win32_icon(const win32_icon&) {throw pfc::exception_not_implemented();}
+ const win32_icon & operator=(const win32_icon &) {throw pfc::exception_not_implemented();}
+
+ HICON m_icon;
+};
+
+class win32_accelerator {
+public:
+ win32_accelerator() : m_accel(NULL) {}
+ ~win32_accelerator() {release();}
+ HACCEL get() const {return m_accel;}
+
+ void load(HINSTANCE p_inst,const TCHAR * p_id) {
+ release();
+ SetLastError(NO_ERROR);
+ m_accel = LoadAccelerators(p_inst,p_id);
+ if (m_accel == NULL) {
+ throw exception_win32(GetLastError());
+ }
+ }
+
+ void release() {
+ if (m_accel != NULL) {
+ DestroyAcceleratorTable(m_accel);
+ m_accel = NULL;
+ }
+ }
+private:
+ HACCEL m_accel;
+ PFC_CLASS_NOT_COPYABLE(win32_accelerator,win32_accelerator);
+};
+
+
+class SelectObjectScope {
+public:
+ SelectObjectScope(HDC p_dc,HGDIOBJ p_obj) : m_dc(p_dc), m_obj(SelectObject(p_dc,p_obj)) {}
+ ~SelectObjectScope() {SelectObject(m_dc,m_obj);}
+private:
+ SelectObjectScope(const SelectObjectScope&) {throw pfc::exception_not_implemented();}
+ const SelectObjectScope & operator=(const SelectObjectScope&) {throw pfc::exception_not_implemented();}
+ HDC m_dc;
+ HGDIOBJ m_obj;
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/alloc.h b/Plugins/listeningto/players/foo_mlt/pfc/alloc.h
new file mode 100644
index 0000000..218afa8
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/alloc.h
@@ -0,0 +1,408 @@
+namespace pfc {
+
+ static void * raw_malloc(t_size p_size) {
+ return p_size > 0 ? new_ptr_check_t(malloc(p_size)) : NULL;
+ }
+
+ static void raw_free(void * p_block) throw() {free(p_block);}
+
+ static void* raw_realloc(void * p_ptr,t_size p_size) {
+ if (p_size == 0) {raw_free(p_ptr); return NULL;}
+ else if (p_ptr == NULL) return raw_malloc(p_size);
+ else return pfc::new_ptr_check_t(::realloc(p_ptr,p_size));
+ }
+
+ static bool raw_realloc_inplace(void * p_block,t_size p_size) throw() {
+ if (p_block == NULL) return p_size == 0;
+#ifdef _MSC_VER
+ if (p_size == 0) return false;
+ return _expand(p_block,p_size) != NULL;
+#else
+ return false;
+#endif
+ }
+
+ template<typename T>
+ t_size calc_array_width(t_size p_width) {
+ return pfc::mul_safe_t<std::bad_alloc,t_size>(p_width,sizeof(T));
+ }
+
+ template<typename T>
+ T * __raw_malloc_t(t_size p_size) {
+ return reinterpret_cast<T*>(raw_malloc(calc_array_width<T>(p_size)));
+ }
+
+ template<typename T>
+ void __raw_free_t(T * p_block) throw() {
+ raw_free(reinterpret_cast<void*>(p_block));
+ }
+
+ template<typename T>
+ T * __raw_realloc_t(T * p_block,t_size p_size) {
+ return reinterpret_cast<T*>(raw_realloc(p_block,calc_array_width<T>(p_size)));
+ }
+
+ template<typename T>
+ bool __raw_realloc_inplace_t(T * p_block,t_size p_size) {
+ return raw_realloc_inplace(p_block,calc_array_width<T>(p_size));
+ }
+
+
+ template<typename t_exception,typename t_int>
+ inline t_int safe_shift_left_t(t_int p_val,t_size p_shift = 1) {
+ t_int newval = p_val << p_shift;
+ if (newval >> p_shift != p_val) throw t_exception();
+ return newval;
+ }
+
+ template<typename t_item> class alloc_dummy {
+ private: typedef alloc_dummy<t_item> t_self;
+ public:
+ alloc_dummy() {}
+ void set_size(t_size p_size) {throw pfc::exception_not_implemented();}
+ t_size get_size() const {throw pfc::exception_not_implemented();}
+ const t_item & operator[](t_size p_index) const {throw pfc::exception_not_implemented();}
+ t_item & operator[](t_size p_index) {throw pfc::exception_not_implemented();}
+
+ bool is_ptr_owned(const void * p_item) const {return false;}
+
+ //not mandatory
+ const t_item * get_ptr() const {throw pfc::exception_not_implemented();}
+ t_item * get_ptr() {throw pfc::exception_not_implemented();}
+ void prealloc(t_size) {throw pfc::exception_not_implemented();}
+ void force_reset() {throw pfc::exception_not_implemented();}
+ private:
+ const t_self & operator=(const t_self &) {throw pfc::exception_not_implemented();}
+ alloc_dummy(const t_self&) {throw pfc::exception_not_implemented();}
+ };
+
+ template<typename t_item>
+ bool is_pointer_in_range(const t_item * p_buffer,t_size p_buffer_size,const void * p_pointer) {
+ return p_pointer >= reinterpret_cast<const void*>(p_buffer) && p_pointer < reinterpret_cast<const void*>(p_buffer + p_buffer_size);
+ }
+
+
+ //! Simple inefficient fully portable allocator.
+ template<typename t_item> class alloc_simple {
+ private: typedef alloc_simple<t_item> t_self;
+ public:
+ alloc_simple() : m_data(NULL), m_size(0) {}
+ void set_size(t_size p_size) {
+ if (p_size != m_size) {
+ t_item * l_data = NULL;
+ if (p_size > 0) l_data = new t_item[p_size];
+ try {
+ pfc::memcpy_t(l_data,m_data,pfc::min_t(m_size,p_size));
+ } catch(...) {
+ delete[] l_data;
+ throw;
+ }
+ delete[] m_data;
+ m_data = l_data;
+ m_size = p_size;
+ }
+ }
+ t_size get_size() const {return m_size;}
+ const t_item & operator[](t_size p_index) const {PFC_ASSERT(p_index < m_size); return m_data[p_index];}
+ t_item & operator[](t_size p_index) {PFC_ASSERT(p_index < m_size); return m_data[p_index];}
+ bool is_ptr_owned(const void * p_item) const {return is_pointer_in_range(get_ptr(),get_size(),p_item);}
+
+ t_item * get_ptr() {return m_data;}
+ const t_item * get_ptr() const {return m_data;}
+
+ void prealloc(t_size) {}
+ void force_reset() {set_size(0);}
+
+ ~alloc_simple() {delete[] m_data;}
+ private:
+ const t_self & operator=(const t_self &) {throw pfc::exception_not_implemented();}
+ alloc_simple(const t_self&) {throw pfc::exception_not_implemented();}
+
+ t_item * m_data;
+ t_size m_size;
+ };
+
+ template<typename t_item> class __array_fast_helper_t {
+ private:
+ typedef __array_fast_helper_t<t_item> t_self;
+ public:
+ __array_fast_helper_t() : m_buffer(NULL), m_size_total(0), m_size(0) {}
+
+
+ void set_size(t_size p_size,t_size p_size_total) {
+ PFC_ASSERT(p_size <= p_size_total);
+ PFC_ASSERT(m_size <= m_size_total);
+ if (p_size_total > m_size_total) {
+ resize_storage(p_size_total);
+ resize_content(p_size);
+ } else {
+ resize_content(p_size);
+ resize_storage(p_size_total);
+ }
+ }
+
+
+
+ t_size get_size() const {return m_size;}
+ t_size get_size_total() const {return m_size_total;}
+ const t_item & operator[](t_size p_index) const {PFC_ASSERT(p_index < m_size); return m_buffer[p_index];}
+ t_item & operator[](t_size p_index) {PFC_ASSERT(p_index < m_size); return m_buffer[p_index];}
+ ~__array_fast_helper_t() {
+ set_size(0,0);
+ }
+ t_item * get_ptr() {return m_buffer;}
+ const t_item * get_ptr() const {return m_buffer;}
+ bool is_ptr_owned(const void * p_item) const {return is_pointer_in_range(m_buffer,m_size_total,p_item);}
+ private:
+ const t_self & operator=(const t_self &) {throw pfc::exception_not_implemented();}
+ __array_fast_helper_t(const t_self &) {throw pfc::exception_not_implemented();}
+
+
+ void resize_content(t_size p_size) {
+ if (traits_t<t_item>::needs_constructor || traits_t<t_item>::needs_destructor) {
+ if (p_size > m_size) {//expand
+ do {
+ __unsafe__in_place_constructor_t(m_buffer[m_size]);
+ m_size++;
+ } while(m_size < p_size);
+ } else if (p_size < m_size) {
+ __unsafe__in_place_destructor_array_t(m_buffer + p_size, m_size - p_size);
+ m_size = p_size;
+ }
+ } else {
+ m_size = p_size;
+ }
+ }
+
+ void resize_storage(t_size p_size) {
+ PFC_ASSERT( m_size <= m_size_total );
+ PFC_ASSERT( m_size <= p_size );
+ if (m_size_total != p_size) {
+ if (pfc::traits_t<t_item>::realloc_safe) {
+ m_buffer = pfc::__raw_realloc_t(m_buffer,p_size);
+ m_size_total = p_size;
+ } else if (__raw_realloc_inplace_t(m_buffer,p_size)) {
+ //success
+ m_size_total = p_size;
+ } else {
+ t_item * newbuffer = pfc::__raw_malloc_t<t_item>(p_size);
+ try {
+ pfc::__unsafe__in_place_constructor_array_copy_t(newbuffer,m_size,m_buffer);
+ } catch(...) {
+ pfc::__raw_free_t(newbuffer);
+ throw;
+ }
+ pfc::__unsafe__in_place_destructor_array_t(m_buffer,m_size);
+ pfc::__raw_free_t(m_buffer);
+ m_buffer = newbuffer;
+ m_size_total = p_size;
+ }
+ }
+ }
+
+ t_item * m_buffer;
+ t_size m_size,m_size_total;
+ };
+
+ template<typename t_item> class alloc_standard {
+ private: typedef alloc_standard<t_item> t_self;
+ public:
+ alloc_standard() {}
+ void set_size(t_size p_size) {m_content.set_size(p_size,p_size);}
+
+ t_size get_size() const {return m_content.get_size();}
+
+ const t_item & operator[](t_size p_index) const {return m_content[p_index];}
+ t_item & operator[](t_size p_index) {return m_content[p_index];}
+
+ const t_item * get_ptr() const {return m_content.get_ptr();}
+ t_item * get_ptr() {return m_content.get_ptr();}
+
+ bool is_ptr_owned(const void * p_item) const {return m_content.is_ptr_owned(p_item);}
+ void prealloc(t_size p_size) {}
+ void force_reset() {set_size(0);}
+ private:
+ alloc_standard(const t_self &) {throw pfc::exception_not_implemented();}
+ const t_self & operator=(const t_self&) {throw pfc::exception_not_implemented();}
+
+ __array_fast_helper_t<t_item> m_content;
+ };
+
+ template<typename t_item> class alloc_fast {
+ private: typedef alloc_fast<t_item> t_self;
+ public:
+ alloc_fast() {}
+
+ void set_size(t_size p_size) {
+ t_size size_base = m_data.get_size_total();
+ if (size_base == 0) size_base = 1;
+ while(size_base < p_size) {
+ size_base = safe_shift_left_t<std::bad_alloc,t_size>(size_base,1);
+ }
+ while(size_base >> 2 > p_size) {
+ size_base >>= 1;
+ }
+ m_data.set_size(p_size,size_base);
+ }
+
+ t_size get_size() const {return m_data.get_size();}
+ const t_item & operator[](t_size p_index) const {return m_data[p_index];}
+ t_item & operator[](t_size p_index) {return m_data[p_index];}
+
+ const t_item * get_ptr() const {return m_data.get_ptr();}
+ t_item * get_ptr() {return m_data.get_ptr();}
+ bool is_ptr_owned(const void * p_item) const {return m_data.is_ptr_owned(p_item);}
+ void prealloc(t_size) {}
+ void force_reset() {m_data.set_size(0,0);}
+ private:
+ alloc_fast(const t_self &) {throw pfc::exception_not_implemented();}
+ const t_self & operator=(const t_self&) {throw pfc::exception_not_implemented();}
+ __array_fast_helper_t<t_item> m_data;
+ };
+
+ template<typename t_item> class alloc_fast_aggressive {
+ private: typedef alloc_fast_aggressive<t_item> t_self;
+ public:
+ alloc_fast_aggressive() {}
+
+ void set_size(t_size p_size) {
+ t_size size_base = m_data.get_size_total();
+ if (size_base == 0) size_base = 1;
+ while(size_base < p_size) {
+ size_base = safe_shift_left_t<std::bad_alloc,t_size>(size_base,1);
+ }
+ m_data.set_size(p_size,size_base);
+ }
+
+ void prealloc(t_size p_size) {
+ if (p_size > 0) {
+ t_size size_base = m_data.get_size_total();
+ if (size_base == 0) size_base = 1;
+ while(size_base < p_size) {
+ size_base = safe_shift_left_t<std::bad_alloc,t_size>(size_base,1);
+ }
+ m_data.set_size(m_data.get_size(),size_base);
+ }
+ }
+
+ t_size get_size() const {return m_data.get_size();}
+ const t_item & operator[](t_size p_index) const {;return m_data[p_index];}
+ t_item & operator[](t_size p_index) {return m_data[p_index];}
+
+ const t_item * get_ptr() const {return m_data.get_ptr();}
+ t_item * get_ptr() {return m_data.get_ptr();}
+ bool is_ptr_owned(const void * p_item) const {return m_data.is_ptr_owned(p_item);}
+ void force_reset() {m_data.set_size(0,0);}
+ private:
+ alloc_fast_aggressive(const t_self &) {throw pfc::exception_not_implemented();}
+ const t_self & operator=(const t_self&) {throw pfc::exception_not_implemented();}
+ __array_fast_helper_t<t_item> m_data;
+ };
+
+ template<t_size p_width> class alloc_fixed {
+ public:
+ template<typename t_item> class alloc {
+ private: typedef alloc<t_item> t_self;
+ public:
+ alloc() : m_size(0) {}
+
+ void set_size(t_size p_size) {
+ static_assert_t<sizeof(m_array) == sizeof(t_item[p_width])>();
+
+ if (p_size > p_width) throw pfc::exception_overflow();
+ else if (p_size > m_size) {
+ __unsafe__in_place_constructor_array_t(get_ptr()+m_size,p_size-m_size);
+ m_size = p_size;
+ } else if (p_size < m_size) {
+ __unsafe__in_place_destructor_array_t(get_ptr()+p_size,m_size-p_size);
+ m_size = p_size;
+ }
+ }
+
+ ~alloc() {
+ if (pfc::traits_t<t_item>::needs_destructor) set_size(0);
+ }
+
+ t_size get_size() const {return m_size;}
+
+ t_item * get_ptr() {return reinterpret_cast<t_item*>(&m_array);}
+ const t_item * get_ptr() const {return reinterpret_cast<const t_item*>(&m_array);}
+
+ const t_item & operator[](t_size n) const {return get_ptr()[n];}
+ t_item & operator[](t_size n) {return get_ptr()[n];}
+ bool is_ptr_owned(const void * p_item) const {return is_pointer_in_range(get_ptr(),p_width,p_item);}
+ void prealloc(t_size) {}
+ void force_reset() {set_size(0);}
+ private:
+ alloc(const t_self&) {throw pfc::exception_not_implemented();}
+ const t_self& operator=(const t_self&) {throw pfc::exception_not_implemented();}
+
+ t_uint8 m_array[sizeof(t_item[p_width])];
+ t_size m_size;
+ };
+ };
+
+ template<t_size p_width, template<typename> class t_alloc = alloc_standard > class alloc_hybrid {
+ public:
+ template<typename t_item> class alloc {
+ private: typedef alloc<t_item> t_self;
+ public:
+ alloc() {}
+
+ void set_size(t_size p_size) {
+ if (p_size > p_width) {
+ m_fixed.set_size(p_width);
+ m_variable.set_size(p_size - p_width);
+ } else {
+ m_fixed.set_size(p_size);
+ m_variable.set_size(0);
+ }
+ }
+
+ t_item & operator[](t_size p_index) {
+ PFC_ASSERT(p_index < get_size());
+ if (p_index < p_width) return m_fixed[p_index];
+ else return m_variable[p_index - p_width];
+ }
+
+ const t_item & operator[](t_size p_index) const {
+ PFC_ASSERT(p_index < get_size());
+ if (p_index < p_width) return m_fixed[p_index];
+ else return m_variable[p_index - p_width];
+ }
+
+ t_size get_size() const {return m_fixed.get_size() + m_variable.get_size();}
+ bool is_ptr_owned(const void * p_item) const {return m_fixed.is_ptr_owned(p_item) || m_variable.is_ptr_owned(p_item);}
+ void prealloc(t_size p_size) {
+ if (p_size > p_width) m_variable.prealloc(p_size - p_width);
+ }
+ void force_reset() {
+ m_fixed.force_reset(); m_variable.force_reset();
+ }
+ private:
+ alloc(const t_self&) {throw pfc::exception_not_implemented();}
+ const t_self& operator=(const t_self&) {throw pfc::exception_not_implemented();}
+
+ typename alloc_fixed<p_width>::template alloc<t_item> m_fixed;
+ t_alloc<t_item> m_variable;
+ };
+ };
+
+ template<typename t_item> class traits_t<alloc_simple<t_item> > : public traits_default_movable {};
+ template<typename t_item> class traits_t<__array_fast_helper_t<t_item> > : public traits_default_movable {};
+ template<typename t_item> class traits_t<alloc_standard<t_item> > : public pfc::traits_t<__array_fast_helper_t<t_item> > {};
+ template<typename t_item> class traits_t<alloc_fast<t_item> > : public pfc::traits_t<__array_fast_helper_t<t_item> > {};
+ template<typename t_item> class traits_t<alloc_fast_aggressive<t_item> > : public pfc::traits_t<__array_fast_helper_t<t_item> > {};
+
+#if 0//not working (compiler bug?)
+ template<t_size p_width,typename t_item> class traits_t<typename alloc_fixed<p_width>::template alloc<t_item> > : public pfc::traits_t<t_item> {
+ public:
+ enum {
+ needs_constructor = true,
+ };
+ };
+
+ template<t_size p_width,template<typename> class t_alloc,typename t_item>
+ class traits_t<typename alloc_hybrid<p_width,t_alloc>::template alloc<t_item> > : public traits_combined<t_alloc,typename alloc_fixed<p_width>::template alloc<t_item> > {};
+#endif
+};
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/array.h b/Plugins/listeningto/players/foo_mlt/pfc/array.h
new file mode 100644
index 0000000..fa296bc
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/array.h
@@ -0,0 +1,229 @@
+#ifndef _PFC_ARRAY_H_
+#define _PFC_ARRAY_H_
+
+namespace pfc {
+
+ template<typename t_item, template<typename> class t_alloc = alloc_standard> class array_t;
+
+
+ //! Special simplififed version of array class that avoids stepping on landmines with classes without public copy operators/constructors.
+ template<typename _t_item>
+ class array_staticsize_t {
+ public: typedef _t_item t_item;
+ private: typedef array_staticsize_t<t_item> t_self;
+ public:
+ array_staticsize_t() : m_size(0), m_array(NULL) {}
+ array_staticsize_t(t_size p_size) : m_size(0), m_array(NULL) {set_size_discard(p_size);}
+ ~array_staticsize_t() {__release();}
+
+ //! Copy constructor nonfunctional when data type is not copyable.
+ array_staticsize_t(const t_self & p_source) : m_size(0), m_array(NULL) {
+ *this = p_source;
+ }
+
+ //! Copy operator nonfunctional when data type is not copyable.
+ const t_self & operator=(const t_self & p_source) {
+ __release();
+
+ //m_array = pfc::malloc_copy_t(p_source.get_size(),p_source.get_ptr());
+ const t_size newsize = p_source.get_size()
+ m_array = new t_item[newsize]
+ m_size = newsize;
+ for(t_size n = 0; n < newsize; n++) m_array[n] = p_source[n];
+ return *this;
+ }
+
+ void set_size_discard(t_size p_size) {
+ __release();
+ if (p_size > 0) {
+ m_array = new t_item[p_size];
+ m_size = p_size;
+ }
+ }
+
+ t_size get_size() const {return m_size;}
+ const t_item * get_ptr() const {return m_array;}
+ t_item * get_ptr() {return m_array;}
+
+ const t_item & operator[](t_size p_index) const {PFC_ASSERT(p_index < get_size());return m_array[p_index];}
+ t_item & operator[](t_size p_index) {PFC_ASSERT(p_index < get_size());return m_array[p_index];}
+
+ template<typename t_source> bool is_owned(const t_source & p_item) {return pfc::is_pointer_in_range(get_ptr(),get_size(),&p_item);}
+ private:
+ void __release() {
+ m_size = 0;
+ delete[] pfc::replace_null_t(m_array);
+ }
+ t_item * m_array;
+ t_size m_size;
+ };
+
+ template<typename t_to,typename t_from>
+ inline void copy_array_t(t_to & p_to,const t_from & p_from) {
+ const t_size size = array_size_t(p_from);
+ if (p_to.has_owned_items(p_from)) {//avoid landmines with actual array data overlapping, or p_from being same as p_to
+ array_staticsize_t<typename t_to::t_item> temp;
+ temp.set_size_discard(size);
+ pfc::copy_array_loop_t(temp,p_from,size);
+ p_to.set_size(size);
+ pfc::copy_array_loop_t(p_to,temp,size);
+ } else {
+ p_to.set_size(size);
+ pfc::copy_array_loop_t(p_to,p_from,size);
+ }
+ }
+
+ template<typename t_array,typename t_value>
+ inline void fill_array_t(t_array & p_array,const t_value & p_value) {
+ const t_size size = array_size_t(p_array);
+ for(t_size n=0;n<size;n++) p_array[n] = p_value;
+ }
+
+ template<typename _t_item, template<typename> class t_alloc> class array_t {
+ public: typedef _t_item t_item;
+ private: typedef array_t<t_item,t_alloc> t_self;
+ public:
+ array_t() {}
+ array_t(const t_self & p_source) {copy_array_t(*this,p_source);}
+ template<typename t_source> array_t(const t_source & p_source) {copy_array_t(*this,p_source);}
+ const t_self & operator=(const t_self & p_source) {copy_array_t(*this,p_source); return *this;}
+ template<typename t_source> const t_self & operator=(const t_source & p_source) {copy_array_t(*this,p_source); return *this;}
+
+ void set_size(t_size p_size) {m_alloc.set_size(p_size);}
+ void set_count(t_size p_count) {m_alloc.set_size(p_count);}
+ t_size get_size() const {return m_alloc.get_size();}
+ t_size get_count() const {return m_alloc.get_size();}
+ void force_reset() {m_alloc.force_reset();}
+
+ const t_item & operator[](t_size p_index) const {PFC_ASSERT(p_index < get_size());return m_alloc[p_index];}
+ t_item & operator[](t_size p_index) {PFC_ASSERT(p_index < get_size());return m_alloc[p_index];}
+
+ //! Warning: buffer pointer must not point to buffer allocated by this array (fixme).
+ template<typename t_source>
+ void set_data_fromptr(const t_source * p_buffer,t_size p_count) {
+
+ set_size(p_count);
+ pfc::copy_array_loop_t(*this,p_buffer,p_count);
+ }
+
+ template<typename t_array>
+ void append(const t_array & p_source) {
+ if (has_owned_items(p_source)) append(array_t<t_item>(p_source));
+ else {
+ const t_size source_size = array_size_t(p_source);
+ const t_size base = get_size();
+ increase_size(source_size);
+ for(t_size n=0;n<source_size;n++) m_alloc[base+n] = p_source[n];
+ }
+ }
+
+ //! Warning: buffer pointer must not point to buffer allocated by this array (fixme).
+ template<typename t_append>
+ void append_fromptr(const t_append * p_buffer,t_size p_count) {
+ PFC_ASSERT( !is_owned(&p_buffer[0]) );
+ t_size base = get_size();
+ increase_size(p_count);
+ for(t_size n=0;n<p_count;n++) m_alloc[base+n] = p_buffer[n];
+ }
+
+ void increase_size(t_size p_delta) {
+ t_size new_size = get_size() + p_delta;
+ if (new_size < p_delta) throw std::bad_alloc();
+ set_size(new_size);
+ }
+
+ template<typename t_append>
+ void append_single(const t_append & p_item) {
+ if (is_owned(p_item)) append_single(t_append(p_item));
+ else {
+ const t_size base = get_size();
+ increase_size(1);
+ m_alloc[base] = p_item;
+ }
+ }
+
+ template<typename t_filler>
+ void fill(const t_filler & p_filler) {
+ const t_size max = get_size();
+ for(t_size n=0;n<max;n++) m_alloc[n] = p_filler;
+ }
+
+ void fill_null() {
+ const t_size max = get_size();
+ for(t_size n=0;n<max;n++) m_alloc[n] = 0;
+}
+
+ void grow_size(t_size p_size) {
+ if (p_size > get_size()) set_size(p_size);
+ }
+
+ //not supported by some allocs
+ const t_item * get_ptr() const {return m_alloc.get_ptr();}
+ t_item * get_ptr() {return m_alloc.get_ptr();}
+
+ void prealloc(t_size p_size) {m_alloc.prealloc(p_size);}
+
+ template<typename t_array>
+ bool has_owned_items(const t_array & p_source) {
+ if (array_size_t(p_source) == 0) return false;
+
+ //how the hell would we properly check if any of source items is owned by us, in case source array implements some weird mixing of references of items from different sources?
+ //the most obvious way means evil bottleneck here (whether it matters or not from caller's point of view which does something O(n) already is another question)
+ //at least this will work fine with all standard classes which don't crossreference anyhow and always use own storage
+ //perhaps we'll traitify this someday later
+ return is_owned(p_source[0]);
+ }
+
+ template<typename t_source>
+ bool is_owned(const t_source & p_item) {
+ return m_alloc.is_ptr_owned(&p_item);
+ }
+
+ template<typename t_item>
+ void set_single(const t_item & p_item) {
+ set_size(1);
+ (*this)[0] = p_item;
+ }
+
+ template<typename t_callback>
+ void enumerate(t_callback & p_callback) const {
+ for(t_size n = 0; n < get_size(); n++ ) {
+ p_callback((*this)[n]);
+ }
+ }
+
+ private:
+ t_alloc<t_item> m_alloc;
+ };
+
+ template<typename t_item,t_size p_width,template<typename> class t_alloc = alloc_standard >
+ class array_hybrid_t : public array_t<t_item, pfc::alloc_hybrid<p_width,t_alloc>::template alloc >
+ {};
+
+
+ template<typename t_item> class traits_t<array_staticsize_t<t_item> > : public traits_default_movable {};
+ template<typename t_item,template<typename> class t_alloc> class traits_t<array_t<t_item,t_alloc> > : public pfc::traits_t<t_alloc<t_item> > {};
+
+
+ template<typename t_comparator = comparator_default>
+ class comparator_array {
+ public:
+ template<typename t_array1, typename t_array2>
+ static int compare(const t_array1 & p_array1, const t_array2 & p_array2) {
+ t_size walk = 0;
+ for(;;) {
+ if (walk >= p_array1.get_size() && walk >= p_array2.get_size()) return 0;
+ else if (walk >= p_array1.get_size()) return -1;
+ else if (walk >= p_array2.get_size()) return 1;
+ else {
+ int state = t_comparator::compare(p_array1[walk],p_array2[walk]);
+ if (state != 0) return state;
+ }
+ ++walk;
+ }
+ }
+ };
+}
+
+
+#endif //_PFC_ARRAY_H_
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/avltree.h b/Plugins/listeningto/players/foo_mlt/pfc/avltree.h
new file mode 100644
index 0000000..083ef3a
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/avltree.h
@@ -0,0 +1,374 @@
+#ifndef _AVLTREE_T_H_INCLUDED_
+#define _AVLTREE_T_H_INCLUDED_
+
+namespace pfc {
+
+ template<typename t_storage,typename t_comparator = comparator_default>
+ class avltree_t {
+ typedef avltree_t<t_storage,t_comparator> t_self;
+
+ template<typename t_item1,typename t_item2>
+ inline static int compare(const t_item1 & p_item1, const t_item2 & p_item2) {
+ return t_comparator::compare(p_item1,p_item2);
+ }
+
+ struct t_node {
+ t_node *m_left,*m_right;
+ t_size m_depth;
+ t_storage m_data;
+
+ template<bool p_which> t_node * & child() {return p_which ? m_right : m_left;}
+ template<bool p_which> t_node * child() const {return p_which ? m_right : m_left;}
+
+ ~t_node() {
+ if (m_left != NULL) delete m_left;
+ if (m_right != NULL) delete m_right;
+ }
+
+ template<typename T>
+ t_node(T const & p_param) : m_data(p_param), m_left(NULL), m_right(NULL), m_depth(0) {}
+ };
+
+ t_node * m_root;
+
+ static t_size calc_depth(const t_node * ptr)
+ {
+ return ptr ? 1+ptr->m_depth : 0;
+ }
+
+ static void recalc_depth(t_node * ptr) {
+ ptr->m_depth = pfc::max_t(calc_depth(ptr->m_left), calc_depth(ptr->m_right));
+ }
+
+ static void assert_children(t_node * ptr)
+ {
+ #ifdef _DEBUG
+ PFC_ASSERT(ptr->m_depth == pfc::max_t(calc_depth(ptr->m_left),calc_depth(ptr->m_right)) );
+ #endif
+ }
+
+ static int test_depth(t_node * ptr)
+ {
+ if (ptr==0) return 0;
+ else return calc_depth(ptr->m_right) - calc_depth(ptr->m_left);
+ }
+
+ static t_node * extract_left_leaf(t_node * & p_base) {
+ if (p_base->m_left != NULL) {
+ t_node * ret = extract_left_leaf(p_base->m_left);
+ recalc_depth(p_base);
+ g_rebalance(p_base);
+ return ret;
+ } else {
+ t_node * node = p_base;
+ p_base = node->m_right;
+ node->m_right = 0;
+ node->m_depth = 0;
+ return node;
+ }
+ }
+
+ static t_node * extract_right_leaf(t_node ** p_base) {
+ t_node * node = *p_base;
+ if (node->m_right != NULL) {
+ t_node * ret = extract_right_leaf(&node->m_right);
+ recalc_depth(node);
+ g_rebalance(p_base);
+ return ret;
+ } else {
+ *p_base = node->m_left;
+ node->m_left = 0;
+ node->m_depth = 0;
+ return node;
+ }
+ }
+
+ static void remove_internal(t_node* & p_node) {
+ t_node * deleteme = p_node;
+ if (p_node->m_left==0)
+ p_node = p_node->m_right;
+ else if (p_node->m_right==0)
+ p_node = p_node->m_left;
+ else {
+ t_node * swap = extract_left_leaf(p_node->m_right);
+ swap->m_left = deleteme->m_left;
+ swap->m_right = deleteme->m_right;
+ recalc_depth(swap);
+ p_node = swap;
+ }
+ deleteme->m_left = deleteme->m_right = NULL;
+ deleteme->m_depth = 0;
+ delete deleteme;
+ }
+
+ template<typename t_nodewalk,typename t_callback>
+ static void __enum_items_recur(t_nodewalk * p_node,t_callback & p_callback) {
+ if (p_node != NULL) {
+ __enum_items_recur<t_nodewalk>(p_node->m_left,p_callback);
+ p_callback (p_node->m_data);
+ __enum_items_recur<t_nodewalk>(p_node->m_right,p_callback);
+ }
+ }
+
+ template<typename t_search>
+ static t_storage * g_find_or_add(t_node * & p_base,t_search const & p_search,bool & p_new)
+ {
+ if (p_base == NULL) {
+ p_base = new t_node(p_search);
+ p_new = true;
+ return &p_base->m_data;
+ }
+
+ int result = compare(p_base->m_data,p_search);
+ if (result > 0) {
+ t_storage * ret = g_find_or_add<t_search>(p_base->m_left,p_search,p_new);
+ if (p_new) {
+ recalc_depth(p_base);
+ g_rebalance(p_base);
+ }
+ return ret;
+ } else if (result < 0) {
+ t_storage * ret = g_find_or_add<t_search>(p_base->m_right,p_search,p_new);
+ if (p_new) {
+ recalc_depth(p_base);
+ g_rebalance(p_base);
+ }
+ return ret;
+ } else {
+ p_new = false;
+ return &p_base->m_data;
+ }
+ }
+
+
+ static void g_rotate_right(t_node * & p_node) {
+ t_node * oldroot = p_node;
+ t_node * newroot = oldroot->m_right;
+ PFC_ASSERT(newroot != NULL);
+ oldroot->m_right = newroot->m_left;
+ newroot->m_left = oldroot;
+ recalc_depth(oldroot);
+ recalc_depth(newroot);
+ p_node = newroot;
+ }
+
+ static void g_rotate_left(t_node * & p_node) {
+ t_node * oldroot = p_node;
+ t_node * newroot = oldroot->m_left;
+ PFC_ASSERT(newroot != NULL);
+ oldroot->m_left = newroot->m_right;
+ newroot->m_right = oldroot;
+ recalc_depth(oldroot);
+ recalc_depth(newroot);
+ p_node = newroot;
+ }
+
+ static void g_rebalance(t_node * & p_node) {
+ int balance = test_depth(p_node);
+ if (balance > 1) {
+ //right becomes root
+ if (test_depth((p_node)->m_right) < 0) {
+ g_rotate_left((p_node)->m_right);
+ }
+ g_rotate_right(p_node);
+ } else if (balance < -1) {
+ //left becomes root
+ if (test_depth((p_node)->m_left) > 0) {
+ g_rotate_right((p_node)->m_left);
+ }
+ g_rotate_left(p_node);
+ }
+ }
+
+ template<typename t_search>
+ static bool g_remove(t_node * & p_node,t_search const & p_search) {
+ if (p_node == NULL) return false;
+
+ int result = compare(p_node->m_data,p_search);
+ if (result == 0) {
+ remove_internal(p_node);
+ if (p_node != NULL) {
+ recalc_depth(p_node);
+ g_rebalance(p_node);
+ selftest(p_node);
+ }
+ return true;
+ } else {
+ if (g_remove<t_search>(result > 0 ? p_node->m_left : p_node->m_right,p_search)) {
+ recalc_depth(p_node);
+ g_rebalance(p_node);
+ selftest(p_node);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ static void selftest(t_node * p_node) {
+ #if 0 //def _DEBUG
+ if (p_node != NULL) {
+ selftest(p_node->m_left);
+ selftest(p_node->m_right);
+ assert_children(p_node);
+ int delta = test_depth(p_node);
+ assert(delta >= -1 && delta <= 1);
+ }
+ #endif
+ }
+
+
+ static t_size calc_count(const t_node * p_node) {
+ if (p_node != NULL) {
+ return 1 + calc_count(p_node->m_left) + calc_count(p_node->m_right);
+ } else {
+ return 0;
+ }
+ }
+
+ template<typename t_item>
+ t_storage * __find_item_ptr(t_item const & p_item) const {
+ t_node* ptr = m_root;
+ while(ptr != NULL) {
+ int result = compare(ptr->m_data,p_item);
+ if (result > 0) ptr=ptr->m_left;
+ else if (result < 0) ptr=ptr->m_right;
+ else return &ptr->m_data;
+ }
+ return NULL;
+ }
+
+ template<bool inclusive,bool above,typename t_search> t_storage * __find_nearest(const t_search & p_search) const {
+ t_node * ptr = m_root;
+ t_storage * found = NULL;
+ while(ptr != NULL) {
+ int result = compare(ptr->m_data,p_search);
+ if (above) result = -result;
+ if (inclusive && result == 0) {
+ //direct hit
+ found = &ptr->m_data;
+ break;
+ } else if (result < 0) {
+ //match
+ found = &ptr->m_data;
+ ptr = ptr->child<!above>();
+ } else {
+ //mismatch
+ ptr = ptr->child<above>();
+ }
+ }
+ return found;
+ }
+ public:
+ avltree_t() : m_root(NULL) {}
+ ~avltree_t() {reset();}
+ const t_self & operator=(const t_self & p_other) {__copy(p_other);return *this;}
+ avltree_t(const t_self & p_other) : m_root(NULL) {__copy(p_other);}
+
+ template<typename t_other> const t_self & operator=(const t_other & p_other) {copy_list_enumerated(*this,p_other);return *this;}
+ template<typename t_other> avltree_t(const t_other & p_other) : m_root(NULL) {copy_list_enumerated(*this,p_other);}
+
+
+ template<bool inclusive,bool above,typename t_search> const t_storage * find_nearest_item(const t_search & p_search) const {
+ return __find_nearest<inclusive,above>(p_search);
+ }
+
+ template<bool inclusive,bool above,typename t_search> t_storage * find_nearest_item(const t_search & p_search) {
+ return __find_nearest<inclusive,above>(p_search);
+ }
+
+ template<typename t_item>
+ t_storage & add_item(t_item const & p_item) {
+ bool dummy;
+ return add_item_ex(p_item,dummy);
+ }
+
+ template<typename t_item>
+ t_storage & add_item_ex(t_item const & p_item,bool & p_isnew) {
+ t_storage * ret = g_find_or_add(m_root,p_item,p_isnew);
+ selftest(m_root);
+ return *ret;
+ }
+
+ template<typename t_item>
+ void set_item(const t_item & p_item) {
+ bool isnew;
+ t_storage & found = add_item_ex(p_item,isnew);
+ if (isnew) found = p_item;
+ }
+
+ template<typename t_item>
+ const t_storage * find_item_ptr(t_item const & p_item) const {
+ return __find_item_ptr(p_item);
+ }
+
+ //! WARNING: caller must not alter the item in a way that changes the sort order.
+ template<typename t_item>
+ t_storage * find_item_ptr(t_item const & p_item) {
+ return __find_item_ptr(p_item);
+ }
+
+ template<typename t_item>
+ bool have_item(const t_item & p_item) const {
+ return find_item_ptr(p_item) != NULL;
+ }
+
+ void remove_all() {
+ delete pfc::replace_null_t(m_root);
+ }
+
+ template<typename t_item>
+ void remove_item(t_item const & p_item) {
+ g_remove<t_item>(m_root,p_item);
+ selftest(m_root);
+ }
+
+ t_size get_count() const {
+ return calc_count(m_root);
+ }
+
+ template<typename t_callback>
+ void enumerate(t_callback & p_callback) const {
+ __enum_items_recur<const t_node>(m_root,p_callback);
+ }
+
+ //! Allows callback to modify the tree content.
+ //! WARNING: items must not be altered in a way that changes their sort order.
+ template<typename t_callback>
+ void __enumerate(t_callback & p_callback) {
+ __enum_items_recur<t_node>(m_root,p_callback);
+ }
+
+ //deprecated backwards compatibility method wrappers
+ template<typename t_item> t_storage & add(const t_item & p_item) {return add_item(p_item);}
+ template<typename t_item> t_storage & add_ex(const t_item & p_item,bool & p_isnew) {return add_item_ex(p_item,p_isnew);}
+ template<typename t_item> const t_storage * find_ptr(t_item const & p_item) const {return find_item_ptr(p_item);}
+ template<typename t_item> t_storage * find_ptr(t_item const & p_item) {return find_item_ptr(p_item);}
+ template<typename t_item> bool exists(t_item const & p_item) const {return have_item(p_item);}
+ void reset() {remove_all();}
+ template<typename t_item> void remove(t_item const & p_item) {remove_item(p_item);}
+
+ private:
+ static t_node * __copy_recur(const t_node * p_source) {
+ if (p_source == NULL) {
+ return NULL;
+ } else {
+ pfc::ptrholder_t<t_node> newnode = new t_node(p_source->m_data);
+ newnode->m_depth = p_source->m_depth;
+ newnode->m_left = __copy_recur(p_source->m_left);
+ newnode->m_right = __copy_recur(p_source->m_right);
+ return newnode.detach();
+ }
+ }
+
+ void __copy(const t_self & p_other) {
+ reset();
+ m_root = __copy_recur(p_other.m_root);
+ }
+ };
+
+
+ template<typename t_storage,typename t_comparator>
+ class traits_t<avltree_t<t_storage,t_comparator> > : public traits_default_movable {};
+}
+#endif //_AVLTREE_T_H_INCLUDED_
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/bit_array.h b/Plugins/listeningto/players/foo_mlt/pfc/bit_array.h
new file mode 100644
index 0000000..3dcc13f
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/bit_array.h
@@ -0,0 +1,44 @@
+#ifndef _PFC_BIT_ARRAY_H_
+#define _PFC_BIT_ARRAY_H_
+
+class NOVTABLE bit_array {
+public:
+ virtual bool get(t_size n) const = 0;
+ virtual t_size find(bool val,t_size start,t_ssize count) const//can be overridden for improved speed; returns first occurance of val between start and start+count (excluding start+count), or start+count if not found; count may be negative if we're searching back
+ {
+ t_ssize d, todo, ptr = start;
+ if (count==0) return start;
+ else if (count<0) {d = -1; todo = -count;}
+ else {d = 1; todo = count;}
+ while(todo>0 && get(ptr)!=val) {ptr+=d;todo--;}
+ return ptr;
+ }
+ inline bool operator[](t_size n) const {return get(n);}
+
+ t_size calc_count(bool val,t_size start,t_size count,t_size count_max = ~0) const//counts number of vals for start<=n<start+count
+ {
+ t_size found = 0;
+ t_size max = start+count;
+ t_size ptr;
+ for(ptr=find(val,start,count);found<count_max && ptr<max;ptr=find(val,ptr+1,max-ptr-1)) found++;
+ return found;
+ }
+
+ inline t_size find_first(bool val,t_size start,t_size max) const {return find(val,start,max-start);}
+ inline t_size find_next(bool val,t_size previous,t_size max) const {return find(val,previous+1,max-(previous+1));}
+ //for(n = mask.find_first(true,0,m); n < m; n = mask.find_next(true,n,m) )
+protected:
+ bit_array() {}
+ ~bit_array() {}
+};
+
+class NOVTABLE bit_array_var : public bit_array {
+public:
+ virtual void set(t_size n,bool val)=0;
+protected:
+ bit_array_var() {}
+ ~bit_array_var() {}
+};
+
+
+#endif
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/bit_array_impl.h b/Plugins/listeningto/players/foo_mlt/pfc/bit_array_impl.h
new file mode 100644
index 0000000..828761d
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/bit_array_impl.h
@@ -0,0 +1,222 @@
+#ifndef _PFC_BIT_ARRAY_IMPL_H_
+#define _PFC_BIT_ARRAY_IMPL_H_
+
+template<class T>
+class bit_array_table_t : public bit_array
+{
+ const T * data;
+ t_size count;
+ bool after;
+public:
+ inline bit_array_table_t(const T * p_data,t_size p_count,bool p_after = false)
+ : data(p_data), count(p_count), after(p_after)
+ {
+ }
+
+ bool get(t_size n) const
+ {
+ if (n<count) return !!data[n];
+ else return after;
+ }
+};
+
+template<class T>
+class bit_array_var_table_t : public bit_array_var
+{
+ T * data;
+ t_size count;
+ bool after;
+public:
+ inline bit_array_var_table_t(T * p_data,t_size p_count,bool p_after = false)
+ : data(p_data), count(p_count), after(p_after)
+ {
+ }
+
+ bool get(t_size n) const {
+ if (n<count) return !!data[n];
+ else return after;
+ }
+
+ void set(t_size n,bool val) {
+ if (n<count) data[n] = !!val;
+ }
+};
+
+
+typedef bit_array_table_t<bool> bit_array_table;
+typedef bit_array_var_table_t<bool> bit_array_var_table;
+
+class bit_array_range : public bit_array
+{
+ t_size begin,end;
+ bool state;
+public:
+ bit_array_range(t_size first,t_size count,bool p_state = true) : begin(first), end(first+count), state(p_state) {}
+
+ bool get(t_size n) const
+ {
+ bool rv = n>=begin && n<end;
+ if (!state) rv = !rv;
+ return rv;
+ }
+};
+
+class bit_array_and : public bit_array
+{
+ const bit_array & a1, & a2;
+public:
+ bit_array_and(const bit_array & p_a1, const bit_array & p_a2) : a1(p_a1), a2(p_a2) {}
+ bool get(t_size n) const {return a1.get(n) && a2.get(n);}
+};
+
+class bit_array_or : public bit_array
+{
+ const bit_array & a1, & a2;
+public:
+ bit_array_or(const bit_array & p_a1, const bit_array & p_a2) : a1(p_a1), a2(p_a2) {}
+ bool get(t_size n) const {return a1.get(n) || a2.get(n);}
+};
+
+class bit_array_xor : public bit_array
+{
+ const bit_array & a1, & a2;
+public:
+ bit_array_xor(const bit_array & p_a1, const bit_array & p_a2) : a1(p_a1), a2(p_a2) {}
+ bool get(t_size n) const
+ {
+ bool v1 = a1.get(n), v2 = a2.get(n);
+ return (v1 && !v2) || (!v1 && v2);
+ }
+};
+
+class bit_array_not : public bit_array
+{
+ const bit_array & a1;
+public:
+ bit_array_not(const bit_array & p_a1) : a1(p_a1) {}
+ bool get(t_size n) const {return !a1.get(n);}
+ t_size find(bool val,t_size start,t_ssize count) const
+ {return a1.find(!val,start,count);}
+
+};
+
+class bit_array_true : public bit_array
+{
+public:
+ bool get(t_size n) const {return true;}
+ t_size find(bool val,t_size start,t_ssize count) const
+ {return val ? start : start+count;}
+};
+
+class bit_array_false : public bit_array
+{
+public:
+ bool get(t_size n) const {return false;}
+ t_size find(bool val,t_size start,t_ssize count) const
+ {return val ? start+count : start;}
+};
+
+class bit_array_val : public bit_array
+{
+ bool val;
+public:
+ bit_array_val(bool v) : val(v) {}
+ bool get(t_size n) const {return val;}
+ t_size find(bool p_val,t_size start,t_ssize count) const
+ {return val==p_val ? start : start+count;}
+};
+
+class bit_array_one : public bit_array
+{
+ t_size val;
+public:
+ bit_array_one(t_size p_val) : val(p_val) {}
+ virtual bool get(t_size n) const {return n==val;}
+
+ virtual t_size find(bool p_val,t_size start,t_ssize count) const
+ {
+ if (count==0) return start;
+ else if (p_val)
+ {
+ if (count>0)
+ return (val>=start && val<start+count) ? val : start+count;
+ else
+ return (val<=start && val>start+count) ? val : start+count;
+ }
+ else
+ {
+ if (start == val) return count>0 ? start+1 : start-1;
+ else return start;
+ }
+ }
+};
+
+class bit_array_bittable : public bit_array_var
+{
+ pfc::array_t<t_uint8> m_data;
+ t_size m_count;
+public:
+ //helpers
+ template<typename t_array>
+ inline static bool g_get(const t_array & p_array,t_size idx)
+ {
+ return !! (p_array[idx>>3] & (1<<(idx&7)));
+ }
+
+ template<typename t_array>
+ inline static void g_set(t_array & p_array,t_size idx,bool val)
+ {
+ unsigned char & dst = p_array[idx>>3];
+ unsigned char mask = 1<<(idx&7);
+ dst = val ? dst|mask : dst&~mask;
+ }
+
+ inline static t_size g_estimate_size(t_size p_count) {return (p_count+7)>>3;}
+
+ void resize(t_size p_count)
+ {
+ t_size old_bytes = g_estimate_size(m_count);
+ m_count = p_count;
+ t_size bytes = g_estimate_size(m_count);
+ m_data.set_size(bytes);
+ if (bytes > old_bytes) pfc::memset_null_t(m_data.get_ptr()+old_bytes,bytes-old_bytes);
+ }
+
+ bit_array_bittable(t_size p_count) : m_count(0) {resize(p_count);}
+
+ void set(t_size n,bool val)
+ {
+ if (n<m_count)
+ {
+ g_set(m_data,n,val);
+ }
+ }
+
+ bool get(t_size n) const
+ {
+ bool rv = false;
+ if (n<m_count) {
+ rv = g_get(m_data,n);
+ }
+ return rv;
+ }
+};
+
+
+class bit_array_order_changed : public bit_array
+{
+public:
+ bit_array_order_changed(const t_size * p_order) : m_order(p_order) {}
+ bool get(t_size n) const
+ {
+ return m_order[n] != n;
+ }
+
+private:
+ const t_size * m_order;
+};
+
+#define for_each_bit_array(var,mask,val,start,count) for(var = mask.find(val,start,count);var<start+count;var=mask.find(val,var+1,count-(var+1-start)))
+
+
+#endif //_PFC_BIT_ARRAY_IMPL_H_
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/bsearch.cpp b/Plugins/listeningto/players/foo_mlt/pfc/bsearch.cpp
new file mode 100644
index 0000000..29718e5
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/bsearch.cpp
@@ -0,0 +1,19 @@
+#include "pfc.h"
+
+
+
+/*
+class NOVTABLE bsearch_callback
+{
+public:
+ virtual int test(t_size p_index) const = 0;
+};
+*/
+
+namespace pfc {
+
+ bool pfc::bsearch(t_size p_count, bsearch_callback const & p_callback,t_size & p_result) {
+ return bsearch_inline_t(p_count,p_callback,p_result);
+ }
+
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/bsearch.h b/Plugins/listeningto/players/foo_mlt/pfc/bsearch.h
new file mode 100644
index 0000000..9b3f77d
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/bsearch.h
@@ -0,0 +1,85 @@
+namespace pfc {
+
+ class NOVTABLE bsearch_callback
+ {
+ public:
+ virtual int test(t_size n) const = 0;
+ };
+
+ PFC_DLL_EXPORT bool bsearch(t_size p_count, bsearch_callback const & p_callback,t_size & p_result);
+
+ template<typename t_container,typename t_compare, typename t_param>
+ class bsearch_callback_impl_simple_t : public bsearch_callback {
+ public:
+ int test(t_size p_index) const {
+ return m_compare(m_container[p_index],m_param);
+ }
+ bsearch_callback_impl_simple_t(const t_container & p_container,t_compare p_compare,const t_param & p_param)
+ : m_container(p_container), m_compare(p_compare), m_param(p_param)
+ {
+ }
+ private:
+ const t_container & m_container;
+ t_compare m_compare;
+ const t_param & m_param;
+ };
+
+ template<typename t_container,typename t_compare, typename t_param,typename t_permutation>
+ class bsearch_callback_impl_permutation_t : public bsearch_callback {
+ public:
+ int test(t_size p_index) const {
+ return m_compare(m_container[m_permutation[p_index]],m_param);
+ }
+ bsearch_callback_impl_permutation_t(const t_container & p_container,t_compare p_compare,const t_param & p_param,const t_permutation & p_permutation)
+ : m_container(p_container), m_compare(p_compare), m_param(p_param), m_permutation(p_permutation)
+ {
+ }
+ private:
+ const t_container & m_container;
+ t_compare m_compare;
+ const t_param & m_param;
+ const t_permutation & m_permutation;
+ };
+
+
+ template<typename t_container,typename t_compare, typename t_param>
+ bool bsearch_t(t_size p_count,const t_container & p_container,t_compare p_compare,const t_param & p_param,t_size & p_index) {
+ return bsearch(
+ p_count,
+ bsearch_callback_impl_simple_t<t_container,t_compare,t_param>(p_container,p_compare,p_param),
+ p_index);
+ }
+
+ template<typename t_container,typename t_compare,typename t_param,typename t_permutation>
+ bool bsearch_permutation_t(t_size p_count,const t_container & p_container,t_compare p_compare,const t_param & p_param,const t_permutation & p_permutation,t_size & p_index) {
+ t_size index;
+ if (bsearch(
+ p_count,
+ bsearch_callback_impl_permutation_t<t_container,t_compare,t_param,t_permutation>(p_container,p_compare,p_param,p_permutation),
+ index))
+ {
+ p_index = p_permutation[index];
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ template<typename t_container,typename t_compare, typename t_param>
+ bool bsearch_range_t(const t_size p_count,const t_container & p_container,t_compare p_compare,const t_param & p_param,t_size & p_range_base,t_size & p_range_count)
+ {
+ t_size probe;
+ if (!bsearch(
+ p_count,
+ bsearch_callback_impl_simple_t<t_container,t_compare,t_param>(p_container,p_compare,p_param),
+ probe)) return false;
+
+ t_size base = probe, count = 1;
+ while(base > 0 && p_compare(p_container[base-1],p_param) == 0) {base--; count++;}
+ while(base + count < p_count && p_compare(p_container[base+count],p_param) == 0) {count++;}
+ p_range_base = base;
+ p_range_count = count;
+ return true;
+ }
+
+}
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/bsearch_inline.h b/Plugins/listeningto/players/foo_mlt/pfc/bsearch_inline.h
new file mode 100644
index 0000000..4358bde
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/bsearch_inline.h
@@ -0,0 +1,46 @@
+namespace pfc {
+
+template<typename t_callback>
+inline bool bsearch_inline_t(t_size p_count, const t_callback & p_callback,t_size & p_result)
+{
+ t_size max = p_count;
+ t_size min = 0;
+ t_size ptr;
+ while(min<max)
+ {
+ ptr = min + ( (max-min) >> 1);
+ int result = p_callback.test(ptr);
+ if (result<0) min = ptr + 1;
+ else if (result>0) max = ptr;
+ else
+ {
+ p_result = ptr;
+ return true;
+ }
+ }
+ p_result = min;
+ return false;
+}
+
+template<typename t_buffer,typename t_value>
+inline bool bsearch_simple_inline_t(const t_buffer & p_buffer,t_size p_count,t_value const & p_value,t_size & p_result)
+{
+ t_size max = p_count;
+ t_size min = 0;
+ t_size ptr;
+ while(min<max)
+ {
+ ptr = min + ( (max-min) >> 1);
+ if (p_value > p_buffer[ptr]) min = ptr + 1;
+ else if (p_value < p_buffer[ptr]) max = ptr;
+ else
+ {
+ p_result = ptr;
+ return true;
+ }
+ }
+ p_result = min;
+ return false;
+}
+
+}
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/byte_order_helper.h b/Plugins/listeningto/players/foo_mlt/pfc/byte_order_helper.h
new file mode 100644
index 0000000..75f3a18
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/byte_order_helper.h
@@ -0,0 +1,209 @@
+#ifndef _PFC_BYTE_ORDER_HELPER_
+#define _PFC_BYTE_ORDER_HELPER_
+
+namespace pfc {
+ void byteswap_raw(void * p_buffer,t_size p_bytes);
+
+ template<typename T> T byteswap_t(T p_source);
+
+ template<> inline char byteswap_t<char>(char p_source) {return p_source;}
+ template<> inline unsigned char byteswap_t<unsigned char>(unsigned char p_source) {return p_source;}
+
+#ifdef _MSC_VER//does this even help with performance/size?
+ template<> inline wchar_t byteswap_t<wchar_t>(wchar_t p_source) {return _byteswap_ushort(p_source);}
+
+ template<> inline short byteswap_t<short>(short p_source) {return _byteswap_ushort(p_source);}
+ template<> inline unsigned short byteswap_t<unsigned short>(unsigned short p_source) {return _byteswap_ushort(p_source);}
+
+ template<> inline int byteswap_t<int>(int p_source) {return _byteswap_ulong(p_source);}
+ template<> inline unsigned int byteswap_t<unsigned int>(unsigned int p_source) {return _byteswap_ulong(p_source);}
+
+ template<> inline long byteswap_t<long>(long p_source) {return _byteswap_ulong(p_source);}
+ template<> inline unsigned long byteswap_t<unsigned long>(unsigned long p_source) {return _byteswap_ulong(p_source);}
+
+ template<> inline long long byteswap_t<long long>(long long p_source) {return _byteswap_uint64(p_source);}
+ template<> inline unsigned long long byteswap_t<unsigned long long>(unsigned long long p_source) {return _byteswap_uint64(p_source);}
+#else
+ template<> inline t_uint16 byteswap_t<t_uint16>(t_uint16 p_source) {return ((p_source & 0xFF00) >> 8) | ((p_source & 0x00FF) << 8);}
+ template<> inline t_int16 byteswap_t<t_int16>(t_int16 p_source) {return byteswap_t<t_uint16>(p_source);}
+
+ template<> inline t_uint32 byteswap_t<t_uint32>(t_uint32 p_source) {return ((p_source & 0xFF000000) >> 24) | ((p_source & 0x00FF0000) >> 8) | ((p_source & 0x0000FF00) << 8) | ((p_source & 0x000000FF) << 24);}
+ template<> inline t_int32 byteswap_t<t_int32>(t_int32 p_source) {return byteswap_t<t_uint32>(p_source);}
+
+ template<> inline t_uint64 byteswap_t<t_uint64>(t_uint64 p_source) {
+ //optimizeme
+ byteswap_raw(&p_source,sizeof(p_source));
+ return p_source;
+ }
+ template<> inline t_int64 byteswap_t<t_int64>(t_int64 p_source) {return byteswap_t<t_uint64>(p_source);}
+
+ template<> inline wchar_t byteswap_t<wchar_t>(wchar_t p_source) {
+ return byteswap_t<pfc::sized_int_t<sizeof(wchar_t)>::t_unsigned>(p_source);
+ }
+#endif
+
+ template<> inline float byteswap_t<float>(float p_source) {
+ float ret;
+ *(t_uint32*) &ret = byteswap_t(*(const t_uint32*)&p_source );
+ return ret;
+ }
+
+ template<> inline double byteswap_t<double>(double p_source) {
+ double ret;
+ *(t_uint64*) &ret = byteswap_t(*(const t_uint64*)&p_source );
+ return ret;
+ }
+
+ //blargh at GUID byteswap issue
+ template<> inline GUID byteswap_t<GUID>(GUID p_guid) {
+ GUID ret;
+ ret.Data1 = pfc::byteswap_t(p_guid.Data1);
+ ret.Data2 = pfc::byteswap_t(p_guid.Data2);
+ ret.Data3 = pfc::byteswap_t(p_guid.Data3);
+ ret.Data4[0] = p_guid.Data4[0];
+ ret.Data4[1] = p_guid.Data4[1];
+ ret.Data4[2] = p_guid.Data4[2];
+ ret.Data4[3] = p_guid.Data4[3];
+ ret.Data4[4] = p_guid.Data4[4];
+ ret.Data4[5] = p_guid.Data4[5];
+ ret.Data4[6] = p_guid.Data4[6];
+ ret.Data4[7] = p_guid.Data4[7];
+ return ret;
+ }
+
+
+
+};
+
+#ifdef _MSC_VER
+
+#if defined(_M_IX86) || defined(_M_X64)
+#define PFC_BYTE_ORDER_IS_BIG_ENDIAN 0
+#endif
+
+#else//_MSC_VER
+
+#include <endian.h>
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define PFC_BYTE_ORDER_IS_BIG_ENDIAN 1
+#else
+#define PFC_BYTE_ORDER_IS_BIG_ENDIAN 0
+#endif
+
+#endif//_MSC_VER
+
+#ifdef PFC_BYTE_ORDER_IS_BIG_ENDIAN
+#define PFC_BYTE_ORDER_IS_LITTLE_ENDIAN (!(PFC_BYTE_ORDER_IS_BIG_ENDIAN))
+#else
+#error please update byte order #defines
+#endif
+
+
+namespace pfc {
+ enum {
+ byte_order_is_big_endian = PFC_BYTE_ORDER_IS_BIG_ENDIAN,
+ byte_order_is_little_endian = PFC_BYTE_ORDER_IS_LITTLE_ENDIAN,
+ };
+
+ template<typename T> T byteswap_if_be_t(T p_param) {return byte_order_is_big_endian ? byteswap_t(p_param) : p_param;}
+ template<typename T> T byteswap_if_le_t(T p_param) {return byte_order_is_little_endian ? byteswap_t(p_param) : p_param;}
+}
+
+namespace byte_order {
+
+#if PFC_BYTE_ORDER_IS_BIG_ENDIAN//big endian
+ template<typename T> inline void order_native_to_le_t(T& param) {param = pfc::byteswap_t(param);}
+ template<typename T> inline void order_native_to_be_t(T& param) {}
+ template<typename T> inline void order_le_to_native_t(T& param) {param = pfc::byteswap_t(param);}
+ template<typename T> inline void order_be_to_native_t(T& param) {}
+#else//little endian
+ template<typename T> inline void order_native_to_le_t(T& param) {}
+ template<typename T> inline void order_native_to_be_t(T& param) {param = pfc::byteswap_t(param);}
+ template<typename T> inline void order_le_to_native_t(T& param) {}
+ template<typename T> inline void order_be_to_native_t(T& param) {param = pfc::byteswap_t(param);}
+#endif
+};
+
+
+
+namespace pfc {
+ template<typename TInt,unsigned width,bool IsBigEndian>
+ class __EncodeIntHelper {
+ public:
+ inline static void Run(TInt p_value,t_uint8 * p_out) {
+ *p_out = (t_uint8)(p_value);
+ __EncodeIntHelper<TInt,width-1,IsBigEndian>::Run(p_value >> 8,p_out + (IsBigEndian ? -1 : 1));
+ }
+ };
+
+ template<typename TInt,bool IsBigEndian>
+ class __EncodeIntHelper<TInt,1,IsBigEndian> {
+ public:
+ inline static void Run(TInt p_value,t_uint8* p_out) {
+ *p_out = (t_uint8)(p_value);
+ }
+ };
+ template<typename TInt,bool IsBigEndian>
+ class __EncodeIntHelper<TInt,0,IsBigEndian> {
+ public:
+ inline static void Run(TInt,t_uint8*) {}
+ };
+
+ template<typename TInt>
+ inline void encode_little_endian(t_uint8 * p_buffer,TInt p_value) {
+ __EncodeIntHelper<TInt,sizeof(TInt),false>::Run(p_value,p_buffer);
+ }
+ template<typename TInt>
+ inline void encode_big_endian(t_uint8 * p_buffer,TInt p_value) {
+ __EncodeIntHelper<TInt,sizeof(TInt),true>::Run(p_value,p_buffer + (sizeof(TInt) - 1));
+ }
+
+
+ template<typename TInt,unsigned width,bool IsBigEndian>
+ class __DecodeIntHelper {
+ public:
+ inline static TInt Run(const t_uint8 * p_in) {
+ return (__DecodeIntHelper<TInt,width-1,IsBigEndian>::Run(p_in + (IsBigEndian ? -1 : 1)) << 8) + *p_in;
+ }
+ };
+
+ template<typename TInt,bool IsBigEndian>
+ class __DecodeIntHelper<TInt,1,IsBigEndian> {
+ public:
+ inline static TInt Run(const t_uint8* p_in) {return *p_in;}
+ };
+
+ template<typename TInt,bool IsBigEndian>
+ class __DecodeIntHelper<TInt,0,IsBigEndian> {
+ public:
+ inline static TInt Run(const t_uint8*) {return 0;}
+ };
+
+ template<typename TInt>
+ inline void decode_little_endian(TInt & p_out,const t_uint8 * p_buffer) {
+ p_out = __DecodeIntHelper<TInt,sizeof(TInt),false>::Run(p_buffer);
+ }
+
+ template<typename TInt>
+ inline void decode_big_endian(TInt & p_out,const t_uint8 * p_buffer) {
+ p_out = __DecodeIntHelper<TInt,sizeof(TInt),true>::Run(p_buffer + (sizeof(TInt) - 1));
+ }
+
+ template<typename TInt>
+ inline TInt decode_little_endian(const t_uint8 * p_buffer) {
+ TInt temp;
+ decode_little_endian(temp,p_buffer);
+ return temp;
+ }
+
+ template<typename TInt>
+ inline TInt decode_big_endian(const t_uint8 * p_buffer) {
+ TInt temp;
+ decode_big_endian(temp,p_buffer);
+ return temp;
+ }
+}
+
+
+
+#endif
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/chainlist.h b/Plugins/listeningto/players/foo_mlt/pfc/chainlist.h
new file mode 100644
index 0000000..024f79e
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/chainlist.h
@@ -0,0 +1,581 @@
+#ifndef _PFC_CHAINLIST_H_
+#define _PFC_CHAINLIST_H_
+
+namespace pfc {
+
+ template<typename T>
+ class chain_list_simple_t {
+ private:
+ typedef chain_list_simple_t<T> t_self;
+ public:
+ chain_list_simple_t() : m_first(0), m_last(0), m_count(0) {}
+ chain_list_simple_t(const t_self & p_source) : m_first(0), m_last(0), m_count(0) {
+ t_iter iter;
+ for(iter = p_source.first();iter;iter = p_source.next(iter))
+ insert_last(p_source.get_item(iter));
+ }
+
+ t_self const & operator=(t_self const & p_source) {
+ remove_all();
+ for(t_iter iter = p_source.first();iter;iter = p_source.next(iter))
+ insert_last(p_source.get_item(iter));
+ return *this;
+ }
+
+
+ typedef void* t_iter;
+
+ inline t_size get_count() const {return m_count;}
+ inline t_iter first() const {return reinterpret_cast<t_iter>(m_first);}
+ inline t_iter last () const {return reinterpret_cast<t_iter>(m_last );}
+ inline t_iter next(t_iter param) {return reinterpret_cast<elem*>(param)->m_next;}
+ inline t_iter prev(t_iter param) {return reinterpret_cast<elem*>(param)->m_prev;}
+ inline T & get_item(t_iter param) {return reinterpret_cast<elem*>(param)->m_data;}
+ inline const T & get_item(t_iter param) const {return reinterpret_cast<elem*>(param)->m_data;}
+ inline t_iter insert_first() {return _insert_first(new elem());}
+ inline t_iter insert_first(const T& param) {return _insert_first(new elem(param));}
+ inline t_iter insert_last() {return _insert_last(new elem());}
+ inline t_iter insert_last(const T& param) {return _insert_last(new elem(param));}
+ inline t_iter insert_before(t_iter p_iter) {return _insert_before(p_iter,new elem());}
+ inline t_iter insert_before(t_iter p_iter,const T& param) {return _insert_before(p_iter,new elem(param));}
+ inline t_iter insert_after(t_iter p_iter) {return _insert_after(p_iter,new elem());}
+ inline t_iter insert_after(t_iter p_iter,const T& param) {return _insert_after(p_iter,new elem(param));}
+ inline void remove(t_iter p_iter) {elem * item = reinterpret_cast<elem*>(p_iter); _unlink(item); delete item;}
+
+ inline void unlink(t_iter p_iter) {_unlink(reinterpret_cast<elem*>(p_iter));}
+ inline void link_first(t_iter p_iter) {_insert_first(reinterpret_cast<elem*>(p_iter));}
+ inline void link_last(t_iter p_iter) {_insert_last(reinterpret_cast<elem*>(p_iter));}
+ inline void link_before(t_iter p_next,t_iter p_iter) {_insert_before(p_next,reinterpret_cast<elem*>(p_iter));}
+ inline void link_after(t_iter p_prev,t_iter p_iter) {_insert_after(p_prev,reinterpret_cast<elem*>(p_iter));}
+
+ void remove_all() {while(m_count > 0) remove(first());}
+
+ ~chain_list_simple_t() {remove_all();}
+ private:
+ struct elem;
+
+ t_iter _insert_first(elem * p_elem)
+ {
+ p_elem->m_prev = 0;
+ p_elem->m_next = m_first;
+ (m_first ? m_first->m_prev : m_last) = p_elem;
+ m_first = p_elem;
+ m_count++;
+ return reinterpret_cast<t_iter>(p_elem);
+ }
+
+ t_iter _insert_last(elem * p_elem)
+ {
+ p_elem->m_prev = m_last;
+ p_elem->m_next = 0;
+ (m_last ? m_last->m_next : m_first) = p_elem;
+ m_last = p_elem;
+ m_count++;
+ return reinterpret_cast<t_iter>(p_elem);
+ }
+
+ t_iter _insert_before(t_iter p_iter,elem * p_elem)
+ {
+ elem * p_next = reinterpret_cast<elem*>(p_iter);
+ p_elem->m_next = p_next;
+ p_elem->m_prev = p_next->m_prev;
+ (p_next->m_prev ? p_next->m_prev->m_next : m_first) = p_elem;
+ p_next->m_prev = p_elem;
+ m_count++;
+ return reinterpret_cast<t_iter>(p_elem);
+ }
+
+ t_iter _insert_after(t_iter p_iter,elem * p_elem)
+ {
+ elem * p_prev = reinterpret_cast<elem*>(p_iter);
+ p_elem->m_next = p_prev->m_next;
+ p_elem->m_prev = p_prev;
+ (p_prev->m_next ? p_prev->m_next->m_prev : m_last) = p_elem;
+ p_prev->m_next = p_elem;
+ m_count++;
+ return reinterpret_cast<t_iter>(p_elem);
+ }
+
+ void _unlink(elem * p_elem)
+ {
+ (p_elem->m_prev ? p_elem->m_prev->m_next : m_first) = p_elem->m_next;
+ (p_elem->m_next ? p_elem->m_next->m_prev : m_last) = p_elem->m_prev;
+ p_elem->m_next = p_elem->m_prev = 0;
+ m_count--;
+ }
+
+ struct elem {
+ elem() : m_prev(0), m_next(0) {}
+ elem(const elem & p_src) {*this = p_src;}
+ elem(const T& p_src) : m_data(p_src), m_prev(NULL), m_next(NULL) {}
+
+ T m_data;
+ elem * m_prev, * m_next;
+ };
+ elem * m_first, * m_last;
+ t_size m_count;
+ };
+
+
+ template<typename t_comparator = comparator_default>
+ class comparator_chainlist {
+ public:
+ template<typename t_list1, typename t_list2>
+ static int compare(const t_list1 & p_list1, const t_list2 p_list2) {
+ typename t_list1::const_iterator iter1 = p_list1.first();
+ typename t_list2::const_iterator iter2 = p_list2.first();
+ for(;;) {
+ if (iter1.is_empty() && iter2.is_empty()) return 0;
+ else if (iter1.is_empty()) return -1;
+ else if (iter2.is_empty()) return 1;
+ else {
+ int state = t_comparator::compare(*iter1,*iter2);
+ if (state != 0) return state;
+ }
+ ++iter1; ++iter2;
+ }
+ }
+ };
+
+ template<typename T>
+ class chain_list_t
+ {
+ public:
+ class const_iterator;
+ class iterator;
+ friend class const_iterator;
+ friend class iterator;
+
+ private:
+ class elem;
+
+ typedef chain_list_t<T> t_self;
+ public:
+
+ class const_iterator
+ {
+ public:
+ friend class chain_list_t<T>;
+
+ inline const T & operator*() const {return m_ptr->m_data;}
+ inline const T * operator->() const {return &m_ptr->m_data;}
+ inline const_iterator() : m_owner(0), m_ptr(0) {}
+ inline const_iterator(const const_iterator & p_source) : m_owner(0), m_ptr(0) {*this = p_source;}
+ inline ~const_iterator() {if (m_owner) m_owner->_remove_iterator(this);}
+
+ inline const_iterator(const chain_list_t<T> * p_owner,elem * p_ptr) : m_owner(p_owner), m_ptr(p_ptr)
+ {
+ if (m_owner != NULL) m_owner->_add_iterator(this);
+ }
+
+
+ inline const const_iterator & operator=(const const_iterator & p_source)
+ {
+ if (m_owner != NULL) m_owner->_remove_iterator(this);
+ m_owner = p_source.m_owner;
+ m_ptr = p_source.m_ptr;
+ if (m_owner != NULL) m_owner->_add_iterator(this);
+ return *this;
+ }
+
+ inline void next() {if (m_ptr != NULL) m_ptr = m_ptr->m_next;}
+ inline void prev() {if (m_ptr != NULL) m_ptr = m_ptr->m_prev;}
+
+ inline const const_iterator & operator++() {next();return *this;}
+ inline const_iterator operator++(int) {const_iterator old = *this; next(); return old;}
+ inline const const_iterator & operator--() {prev();return *this;}
+ inline const_iterator operator--(int) {const_iterator old = *this; prev(); return old;}
+
+ inline bool is_valid() const {return m_ptr != NULL;}
+ inline bool is_empty() const {return m_ptr == NULL;}
+
+ inline bool operator==(const const_iterator & p_iter) const {return m_ptr == p_iter.m_ptr;}
+ inline bool operator!=(const const_iterator & p_iter) const {return m_ptr != p_iter.m_ptr;}
+
+ protected:
+ const chain_list_t<T> * m_owner;
+ elem * m_ptr;
+
+ void orphan() {m_ptr = 0;m_owner=0;}
+ };
+
+ class iterator : public const_iterator
+ {
+ public:
+ inline iterator() {}
+ inline iterator(const iterator & p_source) : const_iterator(p_source) {}
+ inline iterator(const chain_list_t<T> * p_owner,elem * p_ptr) : const_iterator(p_owner,p_ptr) {}
+ inline const iterator & operator=(const iterator & p_source) { *(const_iterator*)this = *(const const_iterator*) & p_source; return *this;}
+ inline T & operator*() const {return this->m_ptr->m_data;}
+ inline T * operator->() const {return &this->m_ptr->m_data;}
+ inline bool operator==(const iterator & p_iter) const {return this->m_ptr == p_iter.m_ptr;}
+ inline bool operator!=(const iterator & p_iter) const {return this->m_ptr != p_iter.m_ptr;}
+ inline const iterator & operator++() {this->next();return *this;}
+ inline iterator operator++(int) {iterator old = *this; this->next(); return old;}
+ inline const iterator & operator--() {this->prev();return *this;}
+ inline iterator operator--(int) {iterator old = *this; this->prev(); return old;}
+ };
+
+
+ inline iterator first() {return iterator(this,m_first);}
+ inline iterator last() {return iterator(this,m_last);}
+
+ inline const_iterator first() const {return const_iterator(this,m_first);}
+ inline const_iterator last() const {return const_iterator(this,m_last);}
+
+ inline t_size get_count() const {return m_count;}
+
+ inline chain_list_t() {_init();}
+ inline chain_list_t(const t_self & p_other) { _init(); *this = p_other; }
+ template<typename t_other> inline chain_list_t(const t_other & p_other) { _init(); *this = p_other; }
+ inline ~chain_list_t()
+ {
+ remove_all();
+ }
+
+ inline const t_self & operator=(const t_self & p_other) {
+ copy_list_enumerated(*this,p_other);
+ return *this;
+ }
+ template<typename t_other> inline const t_self & operator=(const t_other & p_other) {
+ copy_list_enumerated(*this,p_other);
+ return *this;
+ }
+
+
+ template<typename t_insert> iterator insert_after(iterator const & p_iter,const t_insert & p_item) {
+ dynamic_assert(p_iter.is_valid() && p_iter.m_owner == this);
+ elem * new_elem = new elem(p_item,0);
+ __link_after(p_iter,new_elem);
+ return iterator(this,new_elem);
+ }
+
+ template<typename t_insert> iterator insert_before(iterator const & p_iter,const t_insert & p_item) {
+ dynamic_assert(p_iter.is_valid() && p_iter.m_owner == this);
+ elem * new_elem = new elem(p_item,0);
+ __link_before(p_iter,new_elem);
+ return iterator(this,new_elem);
+ }
+
+ template<typename t_insert> iterator insert_last(const t_insert & p_item) {
+ elem * new_elem = new elem(p_item,0);
+ __link_last(new_elem);
+ return iterator(this,new_elem);
+ }
+
+ template<typename t_insert> iterator insert_first(const t_insert & p_item) {
+ elem * new_elem = new elem(p_item,0);
+ __link_first(new_elem);
+ return iterator(this,new_elem);
+ }
+
+ iterator insert_after(iterator const & p_iter) {
+ dynamic_assert(p_iter.is_valid() && p_iter.m_owner == this);
+ elem * new_elem = new elem();
+ __link_after(p_iter,new_elem);
+ return iterator(this,new_elem);
+ }
+
+ iterator insert_before(iterator const & p_iter) {
+ dynamic_assert(p_iter.is_valid() && p_iter.m_owner == this);
+ elem * new_elem = new elem();
+ __link_before(p_iter,new_elem);
+ return iterator(this,new_elem);
+ }
+
+ iterator insert_last() {
+ elem * new_elem = new elem();
+ __link_last(new_elem);
+ return iterator(this,new_elem);
+ }
+
+ iterator insert_first() {
+ elem * new_elem = new elem();
+ __link_first(new_elem);
+ return iterator(this,new_elem);
+ }
+
+
+ template<typename t_insert> void insert_last_multi(const chain_list_t<t_insert> & p_list) {
+ typename chain_list_t<t_insert>::const_iterator iter;
+ for(iter = p_list.first(); iter.is_valid(); ++iter) {
+ __link_last(new elem(*iter,0));
+ }
+ }
+
+ template<typename t_insert> void insert_first_multi(const chain_list_t<t_insert> & p_list) {
+ typename chain_list_t<t_insert>::const_iterator iter;
+ for(iter = p_list.last(); iter.is_valid(); --iter) {
+ __link_first(new elem(*iter,0));
+ }
+ }
+
+ void remove_single(iterator const & p_iter);
+ void remove_range(iterator const & p_from,iterator const & p_to);
+ void remove_all();
+
+ inline iterator find_forward(iterator const & p_iter,const T & p_item) const {return iterator(this,_find_forward(p_iter.m_ptr,p_item));}
+ inline const_iterator find_forward(const_iterator const & p_iter,const T & p_item) const {return const_iterator(this,_find_forward(p_iter.m_ptr,p_item));}
+ inline iterator find_back(iterator const & p_iter,const T & p_item) const {return iterator(this,_find_back(p_iter.m_ptr,p_item));}
+ inline const_iterator find_back(const_iterator const & p_iter,const T & p_item) const {return const_iterator(this,_find_back(p_iter.m_ptr,p_item));}
+
+ inline iterator find_first(const T & p_item) {return find_forward(first(),p_item);}
+ inline const_iterator find_first(const T & p_item) const {return find_forward(first(),p_item);}
+ inline iterator find_next(iterator p_iter,const T & p_item) const {p_iter++; return find_forward(p_iter,p_item);}
+ inline const_iterator find_next(const_iterator p_iter,const T & p_item) const {p_iter++; return find_forward(p_iter,p_item);}
+
+ inline iterator find_last(const T & p_item) {return find_back(last(),p_item);}
+ inline const_iterator find_last(const T & p_item) const {return find_back(last(),p_item);}
+ inline iterator find_prev(iterator p_iter,const T & p_item) const {p_iter++; return find_back(p_iter,p_item);}
+ inline const_iterator find_prev(const_iterator p_iter,const T & p_item) const {p_iter++; return find_back(p_iter,p_item);}
+
+ inline bool find_first_and_remove(const T & p_item) {
+ iterator iter = find_first(p_item);
+ if (iter.is_valid()) {remove_single(iter); return true;}
+ else return false;
+ }
+
+ const_iterator by_index(unsigned p_idx) const
+ {
+ const_iterator iter = first();
+ while(iter.is_valid() && p_idx)
+ {
+ ++iter;
+ p_idx--;
+ }
+ return iter;
+ }
+
+ iterator by_index(unsigned p_idx)
+ {
+ iterator iter = first();
+ while(iter.is_valid() && p_idx)
+ {
+ ++iter;
+ p_idx--;
+ }
+ return iter;
+ }
+
+ bool operator==(const t_self & p_other) const {return comparator_chainlist::compare(*this,p_other) == 0;}
+ bool operator!=(const t_self & p_other) const {return comparator_chainlist::compare(*this,p_other) != 0;}
+
+ bool operator<(const t_self & p_other) const {return comparator_chainlist::compare(*this,p_ohter) < 0;}
+ bool operator>(const t_self & p_other) const {return comparator_chainlist::compare(*this,p_ohter) > 0;}
+ bool operator<=(const t_self & p_other) const {return comparator_chainlist::compare(*this,p_ohter) <= 0;}
+ bool operator>=(const t_self & p_other) const {return comparator_chainlist::compare(*this,p_ohter) >= 0;}
+
+ template<typename t_callback>
+ void enumerate(t_callback & p_callback) const {
+ __enumerate_chain<const elem>(m_first,p_callback);
+ }
+
+ template<typename t_callback>
+ void enumerate(t_callback & p_callback) {
+ __enumerate_chain<elem>(m_first,p_callback);
+ }
+
+ template<typename t_value>
+ iterator set_single(const t_value & p_value) {
+ remove_all();
+ return insert_last(p_value);
+ }
+
+ template<typename t_value>
+ iterator set_single() {
+ remove_all();
+ return insert_last();
+ }
+
+ template<typename t_value>
+ void add_item(const t_value & p_value) {
+ __link_last(new elem(p_value,0));
+ }
+
+ private:
+ struct elem {
+ elem() : m_prev(NULL), m_next(NULL) {}
+ template<typename t_param>
+ elem(const t_param & p_source,int) : m_data(p_source), m_prev(0), m_next(0) {}
+
+ T m_data;
+ elem * m_prev, * m_next;
+ };
+
+ void __link_after(iterator const & p_iter,elem * new_elem) {
+ elem * ptr = p_iter.m_ptr;
+ new_elem->m_prev = ptr;
+ new_elem->m_next = ptr->m_next;
+ (ptr->m_next ? ptr->m_next->m_prev : m_last) = new_elem;
+ ptr->m_next = new_elem;
+ m_count++;
+ }
+
+ void __link_before(iterator const & p_iter,elem * new_elem) {
+ elem * ptr = p_iter.m_ptr;
+ new_elem->m_next = ptr;
+ new_elem->m_prev = ptr->m_prev;
+ (ptr->m_prev ? ptr->m_prev->m_next : m_first) = new_elem;
+ ptr->m_prev = new_elem;
+ m_count++;
+ }
+
+ void __link_last(elem * new_elem) {
+ new_elem->m_prev = m_last;
+ (m_last ? m_last->m_next : m_first) = new_elem;
+ m_last = new_elem;
+ m_count++;
+ }
+
+ void __link_first(elem * new_elem) {
+ new_elem->m_next = m_first;
+ (m_first ? m_first->m_prev : m_last) = new_elem;
+ m_first = new_elem;
+ m_count++;
+ }
+
+ template<typename t_elemwalk,typename t_callback>
+ static void __enumerate_chain(t_elemwalk * p_elem,t_callback & p_callback) {
+ t_elemwalk * walk = p_elem;
+ while(walk != NULL) {
+ p_callback(walk->m_data);
+ walk = walk->m_next;
+ }
+ }
+
+
+ elem * m_first, * m_last;
+
+ t_size m_count;
+
+ typedef typename chain_list_simple_t<const_iterator*>::t_iter t_iter_entry;
+
+ mutable chain_list_simple_t<const_iterator*> m_iterators,m_iterators_recycle;
+ enum {iterators_recycle_max = 32};
+
+ elem * _find_forward(elem * p_base,const T & p_item) const
+ {
+ elem * walk = p_base;
+ while(walk)
+ {
+ if (walk->m_data == p_item) return walk;
+ walk = walk->m_next;
+ }
+ return 0;
+ }
+
+ elem * _find_back(elem * p_base,const T & p_item) const
+ {
+ elem * walk = p_base;
+ while(walk)
+ {
+ if (walk->m_data == p_item) return walk;
+ walk = walk->m_prev;
+ }
+ return 0;
+ }
+
+ void _init()
+ {
+ m_first = m_last = 0;
+ m_count = 0;
+ }
+
+ void _delete_iter_entry(t_iter_entry p_iter) const
+ {
+ if (m_iterators_recycle.get_count() < iterators_recycle_max)
+ {
+ m_iterators.unlink(p_iter);
+ m_iterators_recycle.link_last(p_iter);
+ }
+ else
+ {
+ m_iterators.remove(p_iter);
+ }
+ }
+
+ void _add_iterator(const_iterator * p_iter) const
+ {
+ if (m_iterators_recycle.get_count() > 0)
+ {
+ t_iter_entry temp = m_iterators_recycle.first();
+ m_iterators_recycle.unlink(temp);
+ m_iterators.link_last(temp);
+ m_iterators.get_item(temp) = p_iter;
+ }
+ else
+ {
+ m_iterators.insert_last(p_iter);
+ }
+ }
+
+ void _remove_iterator(const_iterator * p_iter) const
+ {
+ t_iter_entry entry = m_iterators.first();
+ while(entry)
+ {
+ if (m_iterators.get_item(entry) == p_iter)
+ {
+ _delete_iter_entry(entry);
+ break;
+ }
+ entry = m_iterators.next(entry);
+ }
+ }
+
+ void _update_iterators_on_removed(const elem * ptr)
+ {
+ t_iter_entry entry = m_iterators.first();
+ while(entry)
+ {
+ t_iter_entry entry_next = m_iterators.next(entry);
+ const_iterator * iter = m_iterators.get_item(entry);
+ if (iter->m_ptr == ptr)
+ {
+ iter->orphan();
+ _delete_iter_entry(entry);
+ }
+ entry = entry_next;
+ }
+ }
+
+ };//chain_list_t
+
+ template<typename T>
+ void chain_list_t<T>::remove_single(iterator const & p_iter)
+ {
+ elem * ptr = p_iter.m_ptr;
+ (ptr->m_prev ? ptr->m_prev->m_next : m_first) = ptr->m_next;
+ (ptr->m_next ? ptr->m_next->m_prev : m_last) = ptr->m_prev;
+
+ m_count--;
+
+ _update_iterators_on_removed(ptr);
+
+ delete ptr;
+ }
+
+ template<typename T>
+ void chain_list_t<T>::remove_range(iterator const & p_from,iterator const & p_to)
+ {
+ if (p_from.is_valid() && p_to.is_valid())
+ {
+ bug_check_assert(p_from.m_owner == this && p_to.m_owner == this);
+
+ iterator walk = p_from;
+ while(walk != p_to)
+ {
+ iterator axeme = walk;
+ walk.next();
+ bug_check_assert(walk.is_valid());
+ remove_single(axeme);
+ }
+
+ remove_single(walk);
+ }
+ }
+ template<typename T>
+ void chain_list_t<T>::remove_all() {remove_range(first(),last());}
+}
+
+#endif //_PFC_CHAINLIST_H_
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/com_ptr_t.h b/Plugins/listeningto/players/foo_mlt/pfc/com_ptr_t.h
new file mode 100644
index 0000000..6f4b58b
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/com_ptr_t.h
@@ -0,0 +1,75 @@
+namespace pfc {
+
+
+//this is windows-only
+//update me to new conventions
+template<class T>
+class com_ptr_t
+{
+public:
+ inline com_ptr_t() : m_ptr(0) {}
+ inline com_ptr_t(T* p_ptr) : m_ptr(p_ptr) {if (m_ptr) m_ptr->AddRef();}
+ inline com_ptr_t(const com_ptr_t<T> & p_source) : m_ptr(p_source.m_ptr) {if (m_ptr) m_ptr->AddRef();}
+
+ inline ~com_ptr_t() {if (m_ptr) m_ptr->Release();}
+
+ inline void copy(T * p_ptr)
+ {
+ if (m_ptr) m_ptr->Release();
+ m_ptr = p_ptr;
+ if (m_ptr) m_ptr->AddRef();
+ }
+
+ inline void copy(const com_ptr_t<T> & p_source) {copy(p_source.m_ptr);}
+
+ inline void set(T * p_ptr)//should not be used ! temporary !
+ {
+ if (m_ptr) m_ptr->Release();
+ m_ptr = p_ptr;
+ }
+
+ inline const com_ptr_t<T> & operator=(const com_ptr_t<T> & p_source) {copy(p_source); return *this;}
+ inline const com_ptr_t<T> & operator=(T * p_ptr) {copy(p_ptr); return *this;}
+
+ inline void release()
+ {
+ if (m_ptr) m_ptr->Release();
+ m_ptr = 0;
+ }
+
+
+ inline T* operator->() const {assert(m_ptr);return m_ptr;}
+
+ inline T* get_ptr() const {return m_ptr;}
+
+ inline T* duplicate_ptr() const//should not be used ! temporary !
+ {
+ if (m_ptr) m_ptr->AddRef();
+ return m_ptr;
+ }
+
+ inline T* duplicate_ptr_release() {
+ T* ret = m_ptr;
+ m_ptr = 0;
+ return ret;
+ }
+
+ inline bool is_valid() const {return m_ptr != 0;}
+ inline bool is_empty() const {return m_ptr == 0;}
+
+ inline bool operator==(const com_ptr_t<T> & p_item) const {return m_ptr == p_item.m_ptr;}
+ inline bool operator!=(const com_ptr_t<T> & p_item) const {return m_ptr != p_item.m_ptr;}
+ inline bool operator>(const com_ptr_t<T> & p_item) const {return m_ptr > p_item.m_ptr;}
+ inline bool operator<(const com_ptr_t<T> & p_item) const {return m_ptr < p_item.m_ptr;}
+
+ inline static void g_swap(com_ptr_t<T> & item1, com_ptr_t<T> & item2) {
+ pfc::swap_t(item1.m_ptr,item2.m_ptr);
+ }
+
+ inline T** receive_ptr() {release();return &m_ptr;}
+
+private:
+ T* m_ptr;
+};
+
+}
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/guid.cpp b/Plugins/listeningto/players/foo_mlt/pfc/guid.cpp
new file mode 100644
index 0000000..54e5938
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/guid.cpp
@@ -0,0 +1,144 @@
+#include "pfc.h"
+
+namespace pfc {
+/*
+6B29FC40-CA47-1067-B31D-00DD010662DA
+.
+typedef struct _GUID { // size is 16
+ DWORD Data1;
+ WORD Data2;
+ WORD Data3;
+ BYTE Data4[8];
+} GUID;
+
+// {B296CF59-4D51-466f-8E0B-E57D3F91D908}
+static const GUID <<name>> =
+{ 0xb296cf59, 0x4d51, 0x466f, { 0x8e, 0xb, 0xe5, 0x7d, 0x3f, 0x91, 0xd9, 0x8 } };
+
+*/
+
+unsigned GUID_from_text::read_hex(char c)
+{
+ if (c>='0' && c<='9') return (unsigned)c - '0';
+ else if (c>='a' && c<='f') return 0xa + (unsigned)c - 'a';
+ else if (c>='A' && c<='F') return 0xa + (unsigned)c - 'A';
+ else return 0;
+}
+
+unsigned GUID_from_text::read_byte(const char * ptr)
+{
+ return (read_hex(ptr[0])<<4) | read_hex(ptr[1]);
+}
+unsigned GUID_from_text::read_word(const char * ptr)
+{
+ return (read_byte(ptr)<<8) | read_byte(ptr+2);
+}
+
+unsigned GUID_from_text::read_dword(const char * ptr)
+{
+ return (read_word(ptr)<<16) | read_word(ptr+4);
+}
+
+void GUID_from_text::read_bytes(BYTE * out,unsigned num,const char * ptr)
+{
+ for(;num;num--)
+ {
+ *out = read_byte(ptr);
+ out++;ptr+=2;
+ }
+}
+
+
+GUID_from_text::GUID_from_text(const char * text)
+{
+ if (*text=='{') text++;
+ const char * max;
+
+ {
+ const char * t = strchr(text,'}');
+ if (t) max = t;
+ else max = text + strlen(text);
+ }
+
+ (GUID)*this = pfc::guid_null;
+
+
+ do {
+ if (text+8>max) break;
+ Data1 = read_dword(text);
+ text += 8;
+ while(*text=='-') text++;
+ if (text+4>max) break;
+ Data2 = read_word(text);
+ text += 4;
+ while(*text=='-') text++;
+ if (text+4>max) break;
+ Data3 = read_word(text);
+ text += 4;
+ while(*text=='-') text++;
+ if (text+4>max) break;
+ read_bytes(Data4,2,text);
+ text += 4;
+ while(*text=='-') text++;
+ if (text+12>max) break;
+ read_bytes(Data4+2,6,text);
+ } while(false);
+}
+
+
+static inline char print_hex_digit(unsigned val)
+{
+ static const char table[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+ assert((val & ~0xF) == 0);
+ return table[val];
+}
+
+static void print_hex(unsigned val,char * &out,unsigned bytes)
+{
+ unsigned n;
+ for(n=0;n<bytes;n++)
+ {
+ unsigned char c = (unsigned char)((val >> ((bytes - 1 - n) << 3)) & 0xFF);
+ *(out++) = print_hex_digit( c >> 4 );
+ *(out++) = print_hex_digit( c & 0xF );
+ }
+ *out = 0;
+}
+
+
+print_guid::print_guid(const GUID & p_guid)
+{
+ char * out = m_data;
+ print_hex(p_guid.Data1,out,4);
+ *(out++) = '-';
+ print_hex(p_guid.Data2,out,2);
+ *(out++) = '-';
+ print_hex(p_guid.Data3,out,2);
+ *(out++) = '-';
+ print_hex(p_guid.Data4[0],out,1);
+ print_hex(p_guid.Data4[1],out,1);
+ *(out++) = '-';
+ print_hex(p_guid.Data4[2],out,1);
+ print_hex(p_guid.Data4[3],out,1);
+ print_hex(p_guid.Data4[4],out,1);
+ print_hex(p_guid.Data4[5],out,1);
+ print_hex(p_guid.Data4[6],out,1);
+ print_hex(p_guid.Data4[7],out,1);
+ *out = 0;
+}
+
+
+PFC_DLL_EXPORT void print_hex_raw(const void * buffer,unsigned bytes,char * p_out)
+{
+ char * out = p_out;
+ const unsigned char * in = (const unsigned char *) buffer;
+ unsigned n;
+ for(n=0;n<bytes;n++)
+ print_hex(in[n],out,1);
+}
+
+}
+
+
+
+const GUID pfc::guid_null = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } }; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/guid.h b/Plugins/listeningto/players/foo_mlt/pfc/guid.h
new file mode 100644
index 0000000..f2b3d77
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/guid.h
@@ -0,0 +1,39 @@
+#ifndef _PFC_GUID_H_
+#define _PFC_GUID_H_
+
+namespace pfc {
+
+ class GUID_from_text : public GUID
+ {
+ unsigned read_hex(char c);
+ unsigned read_byte(const char * ptr);
+ unsigned read_word(const char * ptr);
+ unsigned read_dword(const char * ptr);
+ void read_bytes(unsigned char * out,unsigned num,const char * ptr);
+
+ public:
+ GUID_from_text(const char * text);
+ };
+
+ class print_guid
+ {
+ public:
+ print_guid(const GUID & p_guid);
+ inline operator const char * () const {return m_data;}
+ inline const char * get_ptr() {return m_data;}
+ private:
+ char m_data[64];
+ };
+
+ inline int guid_compare(const GUID & g1,const GUID & g2) {return memcmp(&g1,&g2,sizeof(GUID));}
+
+ inline bool guid_equal(const GUID & g1,const GUID & g2) {return (g1 == g2) ? true : false;}
+ template<> inline int compare_t<GUID,GUID>(const GUID & p_item1,const GUID & p_item2) {return guid_compare(p_item1,p_item2);}
+
+ extern const GUID guid_null;
+
+ PFC_DLL_EXPORT void print_hex_raw(const void * buffer,unsigned bytes,char * p_out);
+}
+
+
+#endif
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/instance_tracker.h b/Plugins/listeningto/players/foo_mlt/pfc/instance_tracker.h
new file mode 100644
index 0000000..fb3bb3b
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/instance_tracker.h
@@ -0,0 +1,49 @@
+namespace pfc {
+ template<typename t_object>
+ class instance_tracker_server_t {
+ public:
+ void add(t_object * p_object) {
+ m_list.add_item(p_object);
+ }
+ void remove(t_object * p_object) {
+ m_list.remove_item(p_object);
+ }
+
+ t_size get_count() const {return m_list.get_count();}
+ t_object * get_item(t_size p_index) {return m_list[p_index];}
+ t_object * operator[](t_size p_index) {return m_list[p_index];}
+
+ private:
+ ptr_list_hybrid_t<t_object,4> m_list;
+ };
+
+
+ template<typename t_object,instance_tracker_server_t<t_object> & p_server>
+ class instance_tracker_client_t {
+ public:
+ instance_tracker_client_t(t_object* p_ptr) : m_ptr(NULL), m_added(false) {initialize(p_ptr);}
+ instance_tracker_client_t() : m_ptr(NULL), m_added(false) {}
+
+ void initialize(t_object * p_ptr) {
+ uninitialize();
+ p_server.add(p_ptr);
+ m_ptr = p_ptr;
+ m_added = true;
+ }
+
+ void uninitialize() {
+ if (m_added) {
+ p_server.remove(m_ptr);
+ m_ptr = NULL;
+ m_added = false;
+ }
+ }
+
+ ~instance_tracker_client_t() {
+ uninitialize();
+ }
+ private:
+ bool m_added;
+ t_object * m_ptr;
+ };
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/int_types.h b/Plugins/listeningto/players/foo_mlt/pfc/int_types.h
new file mode 100644
index 0000000..4d2c4af
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/int_types.h
@@ -0,0 +1,120 @@
+#if !defined(_MSC_VER) && !defined(_EVC_VER)
+#include <stdint.h>
+typedef int64_t t_int64;
+typedef uint64_t t_uint64;
+typedef int32_t t_int32;
+typedef uint32_t t_uint32;
+typedef int16_t t_int16;
+typedef uint16_t t_uint16;
+typedef int8_t t_int8;
+typedef uint8_t t_uint8;
+#else
+typedef __int64 t_int64;
+typedef unsigned __int64 t_uint64;
+typedef __int32 t_int32;
+typedef unsigned __int32 t_uint32;
+typedef __int16 t_int16;
+typedef unsigned __int16 t_uint16;
+typedef __int8 t_int8;
+typedef unsigned __int8 t_uint8;
+#endif
+
+typedef int t_int;
+typedef unsigned int t_uint;
+
+typedef float t_float32;
+typedef double t_float64;
+
+
+
+#if defined(_WIN32) && !defined(_WIN64)
+#define __PFC_WP64 __w64
+#else
+#define __PFC_WP64
+#endif
+
+
+namespace pfc {
+ template<unsigned t_bytes>
+ class sized_int_t;
+
+ template<> class sized_int_t<1> {
+ public:
+ typedef t_uint8 t_unsigned;
+ typedef t_int8 t_signed;
+ };
+
+ template<> class sized_int_t<2> {
+ public:
+ typedef t_uint16 t_unsigned;
+ typedef t_int16 t_signed;
+ };
+
+ template<> class sized_int_t<4> {
+ public:
+ typedef t_uint32 t_unsigned;
+ typedef t_int32 t_signed;
+ };
+
+ template<> class sized_int_t<8> {
+ public:
+ typedef t_uint64 t_unsigned;
+ typedef t_int64 t_signed;
+ };
+}
+
+
+typedef pfc::sized_int_t<sizeof(void*)>::t_unsigned __PFC_WP64 t_size;
+typedef pfc::sized_int_t<sizeof(void*)>::t_signed __PFC_WP64 t_ssize;
+
+
+#define infinite (~0)
+
+const t_uint16 infinite16 = (t_uint16)(~0);
+const t_uint32 infinite32 = (t_uint32)(~0);
+const t_uint64 infinite64 = (t_uint64)(~0);
+const t_size infinite_size = (t_size)(~0);
+
+
+#if defined(_WIN32) && !defined(_WIN64)
+inline t_size MulDiv_Size(t_size x,t_size y,t_size z) {return (t_size) ( ((t_uint64)x * (t_uint64)y) / (t_uint64)z );}
+#elif defined(_WIN64)
+inline t_size MulDiv_Size(t_size x,t_size y,t_size z) {return (x*y)/z;}
+#else
+#error portme
+#endif
+
+
+namespace pfc {
+ template<typename T> class int_specs_t;
+
+ template<typename T>
+ class int_specs_signed_t {
+ public:
+ inline static T get_min() {return ((T)1<<(sizeof(T)*8-1));}
+ inline static T get_max() {return ~((T)1<<(sizeof(T)*8-1));}
+ enum {is_signed = true};
+ };
+
+ template<typename T>
+ class int_specs_unsigned_t {
+ public:
+ inline static T get_min() {return (T)0;}
+ inline static T get_max() {return (T)~0;}
+ enum {is_signed = false};
+ };
+
+ template<> class int_specs_t<char> : public int_specs_signed_t<char> {};
+ template<> class int_specs_t<unsigned char> : public int_specs_unsigned_t<unsigned char> {};
+ template<> class int_specs_t<short> : public int_specs_signed_t<short> {};
+ template<> class int_specs_t<unsigned short> : public int_specs_unsigned_t<unsigned short> {};
+ template<> class int_specs_t<int> : public int_specs_signed_t<int> {};
+ template<> class int_specs_t<unsigned int> : public int_specs_unsigned_t<unsigned int> {};
+ template<> class int_specs_t<long> : public int_specs_signed_t<long> {};
+ template<> class int_specs_t<unsigned long> : public int_specs_unsigned_t<unsigned long> {};
+ template<> class int_specs_t<long long> : public int_specs_signed_t<long long> {};
+ template<> class int_specs_t<unsigned long long> : public int_specs_unsigned_t<unsigned long long> {};
+
+ template<> class int_specs_t<wchar_t> : public int_specs_unsigned_t<wchar_t> {};
+
+};
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/license.txt b/Plugins/listeningto/players/foo_mlt/pfc/license.txt
new file mode 100644
index 0000000..6046d8f
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/license.txt
@@ -0,0 +1,10 @@
+Copyright (c) 2001-2006, Peter Pawlowski
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/list.h b/Plugins/listeningto/players/foo_mlt/pfc/list.h
new file mode 100644
index 0000000..a89f6a4
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/list.h
@@ -0,0 +1,577 @@
+#ifndef _PFC_LIST_H_
+#define _PFC_LIST_H_
+
+namespace pfc {
+
+template<typename T>
+class NOVTABLE list_base_const_t {
+private: typedef list_base_const_t<T> t_self;
+public:
+ virtual t_size get_count() const = 0;
+ virtual void get_item_ex(T& p_out, t_size n) const = 0;
+
+ inline t_size get_size() const {return get_count();}
+
+ inline T get_item(t_size n) const {T temp; get_item_ex(temp,n); return temp;}
+ inline T operator[](t_size n) const {T temp; get_item_ex(temp,n); return temp;}
+
+ template<typename t_compare>
+ t_size find_duplicates_sorted_t(t_compare p_compare,bit_array_var & p_out) const
+ {
+ return pfc::find_duplicates_sorted_t<list_base_const_t<T> const &,t_compare>(*this,get_count(),p_compare,p_out);
+ }
+
+ template<typename t_compare,typename t_permutation>
+ t_size find_duplicates_sorted_permutation_t(t_compare p_compare,t_permutation const & p_permutation,bit_array_var & p_out)
+ {
+ return pfc::find_duplicates_sorted_permutation_t<list_base_const_t<T> const &,t_compare,t_permutation>(*this,get_count(),p_compare,p_permutation,p_out);
+ }
+
+ template<typename t_search>
+ t_size find_item(const t_search & p_item) const//returns index of first occurance, infinite if not found
+ {
+ t_size n,max = get_count();
+ for(n=0;n<max;n++)
+ if (get_item(n)==p_item) return n;
+ return ~0;
+ }
+
+ template<typename t_search>
+ inline bool have_item(const t_search & p_item) const {return find_item<t_search>(p_item)!=~0;}
+
+
+ template<typename t_compare, typename t_param>
+ bool bsearch_t(t_compare p_compare,t_param const & p_param,t_size &p_index) const {
+ return pfc::bsearch_t(get_count(),*this,p_compare,p_param,p_index);
+ }
+
+ template<typename t_compare,typename t_param,typename t_permutation>
+ bool bsearch_permutation_t(t_compare p_compare,t_param const & p_param,const t_permutation & p_permutation,t_size & p_index) {
+ return pfc::bsearch_permutation_t(get_count(),*this,p_compare,p_param,p_permutation,p_index);
+ }
+
+ template<typename t_compare,typename t_permutation>
+ void sort_get_permutation_t(t_compare p_compare,t_permutation const & p_permutation) const {
+ pfc::sort_get_permutation_t<list_base_const_t<T>,t_compare,t_permutation>(*this,p_compare,get_count(),p_permutation);
+ }
+
+ template<typename t_compare,typename t_permutation>
+ void sort_stable_get_permutation_t(t_compare p_compare,t_permutation const & p_permutation) const {
+ pfc::sort_stable_get_permutation_t<list_base_const_t<T>,t_compare,t_permutation>(*this,p_compare,get_count(),p_permutation);
+ }
+
+ template<typename t_callback>
+ void enumerate(t_callback & p_callback) const {
+ for(t_size n = 0, m = get_count(); n < m; ++n ) {
+ p_callback( (*this)[n] );
+ }
+ }
+
+protected:
+ list_base_const_t() {}
+ ~list_base_const_t() {}
+private:
+ const t_self & operator=(const t_self &) {throw pfc::exception_not_implemented();}
+};
+
+
+template<typename T>
+class list_single_ref_t : public list_base_const_t<T>
+{
+public:
+ list_single_ref_t(const T & p_item,t_size p_count = 1) : m_item(p_item), m_count(p_count) {}
+ t_size get_count() const {return m_count;}
+ void get_item_ex(T& p_out,t_size n) const {PFC_ASSERT(n<m_count); p_out = m_item;}
+private:
+ const T & m_item;
+ t_size m_count;
+};
+
+template<typename T>
+class list_partial_ref_t : public list_base_const_t<T>
+{
+public:
+ list_partial_ref_t(const list_base_const_t<T> & p_list,t_size p_base,t_size p_count)
+ : m_list(p_list), m_base(p_base), m_count(p_count)
+ {
+ PFC_ASSERT(m_base + m_count <= m_list.get_count());
+ }
+
+private:
+ const list_base_const_t<T> & m_list;
+ t_size m_base,m_count;
+
+ t_size get_count() const {return m_count;}
+ void get_item_ex(T & p_out,t_size n) const {m_list.get_item_ex(p_out,n+m_base);}
+};
+
+template<typename T,typename A>
+class list_const_array_t : public list_base_const_t<T>
+{
+public:
+ inline list_const_array_t(A p_data,t_size p_count) : m_data(p_data), m_count(p_count) {}
+ t_size get_count() const {return m_count;}
+ void get_item_ex(T & p_out,t_size n) const {p_out = m_data[n];}
+private:
+ A m_data;
+ t_size m_count;
+};
+
+template<typename to,typename from>
+class list_const_cast_t : public list_base_const_t<to>
+{
+public:
+ list_const_cast_t(const list_base_const_t<from> & p_from) : m_from(p_from) {}
+ t_size get_count() const {return m_from.get_count();}
+ void get_item_ex(to & p_out,t_size n) const
+ {
+ from temp;
+ m_from.get_item_ex(temp,n);
+ p_out = temp;
+ }
+private:
+ const list_base_const_t<from> & m_from;
+};
+
+template<typename T,typename A>
+class ptr_list_const_array_t : public list_base_const_t<T*>
+{
+public:
+ inline ptr_list_const_array_t(A p_data,t_size p_count) : m_data(p_data), m_count(p_count) {}
+ t_size get_count() const {return m_count;}
+ void get_item_ex(T* & p_out,t_size n) const {p_out = &m_data[n];}
+private:
+ A m_data;
+ t_size m_count;
+};
+template<typename T>
+class list_const_ptr_t : public list_base_const_t<T>
+{
+public:
+ inline list_const_ptr_t(const T * p_data,t_size p_count) : m_data(p_data), m_count(p_count) {}
+ t_size get_count() const {return m_count;}
+ void get_item_ex(T & p_out,t_size n) const {p_out = m_data[n];}
+private:
+ const T * m_data;
+ t_size m_count;
+};
+
+template<typename T>
+class NOVTABLE list_base_t : public list_base_const_t<T> {
+private:
+ typedef list_base_t<T> t_self;
+public:
+ class NOVTABLE sort_callback
+ {
+ public:
+ virtual int compare(const T& p_item1,const T& p_item2) = 0;
+ };
+
+ virtual void filter_mask(const bit_array & mask) = 0;
+ virtual t_size insert_items(const list_base_const_t<T> & items,t_size base) = 0;
+ virtual void reorder_partial(t_size p_base,const t_size * p_data,t_size p_count) = 0;
+ virtual void sort(sort_callback & p_callback) = 0;
+ virtual void sort_stable(sort_callback & p_callback) = 0;
+ virtual void replace_item(t_size p_index,const T& p_item) = 0;
+ virtual void swap_item_with(t_size p_index,T & p_item) = 0;
+ virtual void swap_items(t_size p_index1,t_size p_index2) = 0;
+
+ inline void reorder(const t_size * p_data) {reorder_partial(0,p_data,this->get_count());}
+
+ inline t_size insert_item(const T & item,t_size base) {return insert_items(list_single_ref_t<T>(item),base);}
+ t_size insert_items_repeat(const T & item,t_size num,t_size base) {return insert_items(list_single_ref_t<T>(item,num),base);}
+ inline t_size add_items_repeat(T item,t_size num) {return insert_items_repeat(item,num,this->get_count());}
+ t_size insert_items_fromptr(const T* source,t_size num,t_size base) {return insert_items(list_const_ptr_t<T>(source,num),base);}
+ inline t_size add_items_fromptr(const T* source,t_size num) {return insert_items_fromptr(source,num,this->get_count());}
+
+ inline t_size add_items(const list_base_const_t<T> & items) {return insert_items(items,this->get_count());}
+ inline t_size add_item(const T& item) {return insert_item(item,this->get_count());}
+
+ inline void remove_mask(const bit_array & mask) {filter_mask(bit_array_not(mask));}
+ inline void remove_all() {filter_mask(bit_array_false());}
+ inline void truncate(t_size val) {if (val < this->get_count()) remove_mask(bit_array_range(val,this->get_count()-val,true));}
+
+ inline T replace_item_ex(t_size p_index,const T & p_item) {T ret = p_item;swap_item_with(p_index,ret);return ret;}
+
+ inline T operator[](t_size n) const {return this->get_item(n);}
+
+ template<typename t_compare>
+ class sort_callback_impl_t : public sort_callback
+ {
+ public:
+ sort_callback_impl_t(t_compare p_compare) : m_compare(p_compare) {}
+ int compare(const T& p_item1,const T& p_item2) {return m_compare(p_item1,p_item2);}
+ private:
+ t_compare m_compare;
+ };
+
+ class sort_callback_auto : public sort_callback
+ {
+ public:
+ int compare(const T& p_item1,const T& p_item2) {return pfc::compare_t(p_item1,p_item2);}
+ };
+
+ void sort() {sort(sort_callback_auto());}
+ template<typename t_compare> void sort_t(t_compare p_compare) {sort(sort_callback_impl_t<t_compare>(p_compare));}
+ template<typename t_compare> void sort_stable_t(t_compare p_compare) {sort_stable(sort_callback_impl_t<t_compare>(p_compare));}
+
+ template<typename t_compare> void sort_remove_duplicates_t(t_compare p_compare)
+ {
+ sort_t<t_compare>(p_compare);
+ bit_array_bittable array(this->get_count());
+ if (this->template find_duplicates_sorted_t<t_compare>(p_compare,array) > 0)
+ remove_mask(array);
+ }
+
+ template<typename t_compare> void sort_stable_remove_duplicates_t(t_compare p_compare)
+ {
+ sort_stable_t<t_compare>(p_compare);
+ bit_array_bittable array(this->get_count());
+ if (this->template find_duplicates_sorted_t<t_compare>(p_compare,array) > 0)
+ remove_mask(array);
+ }
+
+
+ template<typename t_compare> void remove_duplicates_t(t_compare p_compare)
+ {
+ order_helper order(this->get_count());
+ sort_get_permutation_t<t_compare,order_helper&>(p_compare,order);
+ bit_array_bittable array(this->get_count());
+ if (this->template find_duplicates_sorted_permutation_t<t_compare,order_helper const&>(p_compare,order,array) > 0)
+ remove_mask(array);
+ }
+
+ template<typename t_func>
+ void for_each(t_func p_func) {
+ t_size n,max=this->get_count();
+ for(n=0;n<max;n++) p_func(this->get_item(n));
+ }
+
+ template<typename t_func>
+ void for_each(t_func p_func,const bit_array & p_mask) {
+ t_size n,max=this->get_count();
+ for(n=p_mask.find(true,0,max);n<max;n=p_mask.find(true,n+1,max-n-1)) {
+ p_func(this->get_item(n));
+ }
+ }
+
+ template<typename t_releasefunc>
+ void remove_mask_ex(const bit_array & p_mask,t_releasefunc p_func) {
+ this->template for_each<t_releasefunc>(p_func,p_mask);
+ remove_mask(p_mask);
+ }
+
+ template<typename t_releasefunc>
+ void remove_all_ex(t_releasefunc p_func) {
+ this->template for_each<t_releasefunc>(p_func);
+ remove_all();
+ }
+
+ const t_self & operator=(const t_self & p_source) {remove_all(); add_items(p_source);return *this;}
+protected:
+ list_base_t() {}
+ ~list_base_t() {}
+};
+
+
+template<typename T,typename t_storage>
+class list_impl_t : public list_base_t<T>
+{
+public:
+ list_impl_t() {}
+ list_impl_t(const list_impl_t<T,t_storage> & p_source) { *this = p_source; }
+
+ void prealloc(t_size count) {m_buffer.prealloc(count);}
+
+ void set_count(t_size p_count) {m_buffer.set_size(p_count);}
+ void set_size(t_size p_count) {m_buffer.set_size(p_count);}
+
+ t_size insert_item(const T& item,t_size idx)
+ {
+ t_size max = m_buffer.get_size();
+ if (idx > max) idx = max;
+ max++;
+ m_buffer.set_size(max);
+ t_size n;
+ for(n=max-1;n>idx;n--)
+ m_buffer[n]=m_buffer[n-1];
+ m_buffer[idx]=item;
+ return idx;
+ }
+
+ T remove_by_idx(t_size idx)
+ {
+ T ret = m_buffer[idx];
+ t_size n;
+ t_size max = m_buffer.get_size();
+ for(n=idx+1;n<max;n++)
+ {
+ pfc::swap_t(m_buffer[n-1],m_buffer[n]);
+ }
+ m_buffer.set_size(max-1);
+ return ret;
+ }
+
+
+ inline void get_item_ex(T& p_out,t_size n) const
+ {
+ PFC_ASSERT(n>=0);
+ PFC_ASSERT(n<get_count());
+ p_out = m_buffer[n];
+ }
+
+ inline const T& get_item_ref(t_size n) const
+ {
+ PFC_ASSERT(n>=0);
+ PFC_ASSERT(n<get_count());
+ return m_buffer[n];
+ }
+
+ inline T get_item(t_size n) const
+ {
+ PFC_ASSERT(n >= 0);
+ PFC_ASSERT(n < get_count() );
+ return m_buffer[n];
+ };
+
+ inline t_size get_count() const {return m_buffer.get_size();}
+ inline t_size get_size() const {return get_count();}
+
+ inline const T & operator[](t_size n) const
+ {
+ PFC_ASSERT(n>=0);
+ PFC_ASSERT(n<get_count());
+ return m_buffer[n];
+ }
+
+ inline const T* get_ptr() const {return m_buffer.get_ptr();}
+ inline T* get_ptr() {return m_buffer.get_ptr();}
+
+ inline T& operator[](t_size n) {return m_buffer[n];}
+
+ inline void remove_from_idx(t_size idx,t_size num)
+ {
+ remove_mask(bit_array_range(idx,num));
+ }
+
+ t_size insert_items(const list_base_const_t<T> & source,t_size base)
+ {
+ t_size count = get_count();
+ if (base>count) base = count;
+ t_size num = source.get_count();
+ m_buffer.set_size(count+num);
+ if (count > base)
+ {
+ t_size n;
+ for(n=count-1;(int)n>=(int)base;n--)
+ {
+ pfc::swap_t(m_buffer[n+num],m_buffer[n]);
+ }
+ }
+
+ {
+ t_size n;
+ for(n=0;n<num;n++)
+ {
+ source.get_item_ex(m_buffer[n+base],n);
+ }
+ }
+ return base;
+
+ }
+
+ void get_items_mask(list_impl_t<T,t_storage> & out,const bit_array & mask)
+ {
+ t_size n,count = get_count();
+ for_each_bit_array(n,mask,true,0,count)
+ out.add_item(m_buffer[n]);
+ }
+
+ void filter_mask(const bit_array & mask)
+ {
+ t_size n,count = get_count(), total = 0;
+
+ n = total = mask.find(false,0,count);
+
+ if (n<count)
+ {
+ for(n=mask.find(true,n+1,count-n-1);n<count;n=mask.find(true,n+1,count-n-1))
+ pfc::swap_t(m_buffer[total++],m_buffer[n]);
+
+ m_buffer.set_size(total);
+ }
+ }
+
+ void replace_item(t_size idx,const T& item)
+ {
+ PFC_ASSERT(idx>=0);
+ PFC_ASSERT(idx<get_count());
+ m_buffer[idx] = item;
+ }
+
+ void sort()
+ {
+ pfc::sort_callback_impl_auto_wrap_t<t_storage> wrapper(m_buffer);
+ pfc::sort(wrapper,get_count());
+ }
+
+ template<typename t_compare>
+ void sort_t(t_compare p_compare)
+ {
+ pfc::sort_callback_impl_simple_wrap_t<t_storage,t_compare> wrapper(m_buffer,p_compare);
+ pfc::sort(wrapper,get_count());
+ }
+
+ template<typename t_compare>
+ void sort_stable_t(t_compare p_compare)
+ {
+ pfc::sort_callback_impl_simple_wrap_t<t_storage,t_compare> wrapper(m_buffer,p_compare);
+ pfc::sort_stable(wrapper,get_count());
+ }
+ inline void reorder_partial(t_size p_base,const t_size * p_order,t_size p_count)
+ {
+ PFC_ASSERT(p_base+p_count<=get_count());
+ pfc::reorder_partial_t(m_buffer,p_base,p_order,p_count);
+ }
+
+ template<typename t_compare>
+ t_size find_duplicates_sorted_t(t_compare p_compare,bit_array_var & p_out) const
+ {
+ return pfc::find_duplicates_sorted_t<list_impl_t<T,t_storage> const &,t_compare>(*this,get_count(),p_compare,p_out);
+ }
+
+ template<typename t_compare,typename t_permutation>
+ t_size find_duplicates_sorted_permutation_t(t_compare p_compare,t_permutation p_permutation,bit_array_var & p_out)
+ {
+ return pfc::find_duplicates_sorted_permutation_t<list_impl_t<T,t_storage> const &,t_compare,t_permutation>(*this,get_count(),p_compare,p_permutation,p_out);
+ }
+
+
+private:
+ class sort_callback_wrapper
+ {
+ public:
+ explicit inline sort_callback_wrapper(sort_callback & p_callback) : m_callback(p_callback) {}
+ inline int operator()(const T& item1,const T& item2) const {return m_callback.compare(item1,item2);}
+ private:
+ sort_callback & m_callback;
+ };
+public:
+ void sort(sort_callback & p_callback)
+ {
+ sort_t(sort_callback_wrapper(p_callback));
+ }
+
+ void sort_stable(sort_callback & p_callback)
+ {
+ sort_stable_t(sort_callback_wrapper(p_callback));
+ }
+
+ void remove_mask(const bit_array & mask) {filter_mask(bit_array_not(mask));}
+
+ void remove_mask(const bool * mask) {remove_mask(bit_array_table(mask,get_count()));}
+ void filter_mask(const bool * mask) {filter_mask(bit_array_table(mask,get_count()));}
+
+ t_size add_item(const T& item)
+ {
+ t_size idx = get_count();
+ insert_item(item,idx);
+ return idx;
+ }
+
+ void remove_all() {remove_mask(bit_array_true());}
+
+ void remove_item(const T& item)
+ {
+ t_size n,max = get_count();
+ bit_array_bittable mask(max);
+ for(n=0;n<max;n++)
+ mask.set(n,get_item(n)==item);
+ remove_mask(mask);
+ }
+
+ void swap_item_with(t_size p_index,T & p_item)
+ {
+ PFC_ASSERT(p_index < get_count());
+ pfc::swap_t(m_buffer[p_index],p_item);
+ }
+
+ void swap_items(t_size p_index1,t_size p_index2)
+ {
+ PFC_ASSERT(p_index1 < get_count());
+ PFC_ASSERT(p_index1 < get_count());
+ pfc::swap_t(m_buffer[p_index1],m_buffer[p_index2]);
+ }
+
+ inline static void g_swap(list_impl_t<T,t_storage> & p_item1,list_impl_t<T,t_storage> & p_item2)
+ {
+ pfc::swap_t(p_item1.m_buffer,p_item2.m_buffer);
+ }
+
+ template<typename t_search>
+ t_size find_item(const t_search & p_item) const//returns index of first occurance, infinite if not found
+ {
+ t_size n,max = get_count();
+ for(n=0;n<max;n++)
+ if (m_buffer[n]==p_item) return n;
+ return ~0;
+ }
+
+ template<typename t_search>
+ inline bool have_item(const t_search & p_item) const {return this->template find_item<t_search>(p_item)!=~0;}
+
+protected:
+ t_storage m_buffer;
+};
+
+template<typename t_item, template<typename> class t_alloc = pfc::alloc_fast >
+class list_t : public list_impl_t<t_item,pfc::array_t<t_item,t_alloc> > { };
+
+template<typename t_item, t_size p_fixed_count, template<typename> class t_alloc = pfc::alloc_fast >
+class list_hybrid_t : public list_impl_t<t_item,pfc::array_hybrid_t<t_item,p_fixed_count,t_alloc> > {};
+
+template<typename T>
+class ptr_list_const_cast_t : public list_base_const_t<const T *>
+{
+public:
+ inline ptr_list_const_cast_t(const list_base_const_t<T*> & p_param) : m_param(p_param) {}
+ t_size get_count() const {return m_param.get_count();}
+ void get_item_ex(const T * & p_out,t_size n) const {T* temp; m_param.get_item_ex(temp,n); p_out = temp;}
+private:
+ const list_base_const_t<T*> & m_param;
+
+};
+
+
+template<typename T,typename P>
+class list_const_permutation_t : public list_base_const_t<T>
+{
+public:
+ inline list_const_permutation_t(const list_base_const_t<T> & p_list,P p_permutation) : m_list(p_list), m_permutation(p_permutation) {}
+ t_size get_count() const {return m_list.get_count();}
+ void get_item_ex(T & p_out,t_size n) const {m_list.get_item_ex(p_out,m_permutation[n]);}
+private:
+ P m_permutation;
+ const list_base_const_t<T> & m_list;
+};
+
+
+template<class T>
+class list_permutation_t : public list_base_const_t<T>
+{
+public:
+ t_size get_count() const {return m_count;}
+ void get_item_ex(T & p_out,t_size n) const {m_base.get_item_ex(p_out,m_order[n]);}
+ list_permutation_t(const list_base_const_t<T> & p_base,const t_size * p_order,t_size p_count)
+ : m_base(p_base), m_order(p_order), m_count(p_count)
+ {
+ PFC_ASSERT(m_base.get_count() >= m_count);
+ }
+private:
+ const list_base_const_t<T> & m_base;
+ const t_size * m_order;
+ t_size m_count;
+};
+
+}
+#endif //_PFC_LIST_H_
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/map.h b/Plugins/listeningto/players/foo_mlt/pfc/map.h
new file mode 100644
index 0000000..e37025b
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/map.h
@@ -0,0 +1,183 @@
+#ifndef _MAP_T_H_INCLUDED_
+#define _MAP_T_H_INCLUDED_
+
+namespace pfc {
+
+ template<typename t_destination> class __map_overwrite_wrapper {
+ public:
+ __map_overwrite_wrapper(t_destination & p_destination) : m_destination(p_destination) {}
+ template<typename t_from,typename t_to> void operator() (const t_from & p_from,const t_to & p_to) {m_destination.set(p_from,p_to);}
+ private:
+ t_destination & m_destination;
+ };
+
+ template<typename t_storage_from, typename t_storage_to, typename t_comparator = comparator_default>
+ class map_t {
+ private:
+ typedef map_t<t_storage_from,t_storage_to,t_comparator> t_self;
+ public:
+ template<typename t_from,typename t_to>
+ void set(const t_from & p_from, const t_to & p_to) {
+ bool isnew;
+ t_storage & storage = m_data.add_ex(t_search_set<t_from,t_to>(p_from,p_to), isnew);
+ if (!isnew) storage.m_to = p_to;
+ }
+
+ template<typename t_from>
+ t_storage_to & find_or_add(t_from const & p_from) {
+ return m_data.add(t_search_query<t_from>(p_from)).m_to;
+ }
+
+ template<typename t_from>
+ t_storage_to & find_or_add_ex(t_from const & p_from,bool & p_isnew) {
+ return m_data.add_ex(t_search_query<t_from>(p_from),p_isnew).m_to;
+ }
+
+ template<typename t_from>
+ bool have_item(const t_from & p_from) const {
+ return m_data.have_item(t_search_query<t_from>(p_from));
+ }
+
+ template<typename t_from,typename t_to>
+ bool query(const t_from & p_from,t_to & p_to) const {
+ const t_storage * storage = m_data.find_ptr(t_search_query<t_from>(p_from));
+ if (storage == NULL) return false;
+ p_to = storage->m_to;
+ return true;
+ }
+
+ template<typename t_from>
+ const t_storage_to * query_ptr(const t_from & p_from) const {
+ const t_storage * storage = m_data.find_ptr(t_search_query<t_from>(p_from));
+ if (storage == NULL) return NULL;
+ return &storage->m_to;
+ }
+
+ template<typename t_from>
+ t_storage_to * query_ptr(const t_from & p_from) {
+ t_storage * storage = m_data.find_ptr(t_search_query<t_from>(p_from));
+ if (storage == NULL) return NULL;
+ return &storage->m_to;
+ }
+
+ template<bool inclusive,bool above,typename t_from>
+ const t_storage_to * query_nearest_ptr(t_from & p_from) const {
+ const t_storage * storage = m_data.find_nearest_item<inclusive,above>(t_search_query<t_from>(p_from));
+ if (storage == NULL) return NULL;
+ p_from = storage->m_from;
+ return &storage->m_to;
+ }
+
+ template<bool inclusive,bool above,typename t_from>
+ t_storage_to * query_nearest_ptr(t_from & p_from) {
+ t_storage * storage = m_data.find_nearest_item<inclusive,above>(t_search_query<t_from>(p_from));
+ if (storage == NULL) return NULL;
+ p_from = storage->m_from;
+ return &storage->m_to;
+ }
+
+ template<bool inclusive,bool above,typename t_from,typename t_to>
+ bool query_nearest(t_from & p_from,t_to & p_to) const {
+ const t_storage * storage = m_data.find_nearest_item<inclusive,above>(t_search_query<t_from>(p_from));
+ if (storage == NULL) return false;
+ p_from = storage->m_from;
+ p_to = storage->m_to;
+ return true;
+ }
+
+ template<typename t_from>
+ void remove(const t_from & p_from) {
+ m_data.remove_item(t_search_query<t_from>(p_from));
+ }
+
+ template<typename t_callback>
+ void enumerate(t_callback & p_callback) const {
+ m_data.enumerate(enumeration_wrapper<t_callback>(p_callback));
+ }
+
+ template<typename t_callback>
+ void enumerate(t_callback & p_callback) {
+ m_data.__enumerate(enumeration_wrapper_var<t_callback>(p_callback));
+ }
+
+
+ t_size get_count() const {return m_data.get_count();}
+
+ void remove_all() {m_data.remove_all();}
+
+ template<typename t_source>
+ void overwrite(const t_source & p_source) {
+ __map_overwrite_wrapper<t_self> wrapper(*this);
+ p_source.enumerate(wrapper);
+ }
+
+ //backwards compatibility method wrappers
+ template<typename t_from> bool exists(const t_from & p_from) const {return have_item(p_from);}
+
+ private:
+ template<typename t_from>
+ struct t_search_query {
+ t_search_query(const t_from & p_from) : m_from(p_from) {}
+ t_from const & m_from;
+ };
+ template<typename t_from,typename t_to>
+ struct t_search_set {
+ t_search_set(const t_from & p_from, const t_to & p_to) : m_from(p_from), m_to(p_to) {}
+
+ t_from const & m_from;
+ t_to const & m_to;
+ };
+
+ struct t_storage {
+ t_storage_from m_from;
+ t_storage_to m_to;
+
+
+
+ template<typename t_from>
+ t_storage(t_search_query<t_from> const & p_source) : m_from(p_source.m_from), m_to() {}
+
+ template<typename t_from,typename t_to>
+ t_storage(t_search_set<t_from,t_to> const & p_source) : m_from(p_source.m_from), m_to(p_source.m_to) {}
+ };
+
+ class comparator_wrapper {
+ public:
+ template<typename t_other>
+ inline static int compare(const t_storage & p_item1,const t_other & p_item2) {
+ return t_comparator::compare(p_item1.m_from,p_item2.m_from);
+ }
+ };
+
+ template<typename t_callback>
+ class enumeration_wrapper {
+ public:
+ enumeration_wrapper(t_callback & p_callback) : m_callback(p_callback) {}
+ void operator()(const t_storage & p_item) {m_callback(p_item.m_from,p_item.m_to);}
+ private:
+ t_callback & m_callback;
+ };
+
+ template<typename t_callback>
+ class enumeration_wrapper_var {
+ public:
+ enumeration_wrapper_var(t_callback & p_callback) : m_callback(p_callback) {}
+ void operator()(t_storage & p_item) {m_callback(safe_cast<t_storage_from const&>(p_item.m_from),p_item.m_to);}
+ private:
+ t_callback & m_callback;
+ };
+
+ typedef avltree_t<t_storage,comparator_wrapper> t_content;
+
+ t_content m_data;
+ public:
+ typedef traits_t<t_content> traits;
+ };
+
+ template<typename t_storage_from, typename t_storage_to, typename t_comparator>
+ class traits_t<map_t<t_storage_from,t_storage_to,t_comparator> > : public map_t<t_storage_from,t_storage_to,t_comparator>::traits {};
+
+
+}
+
+#endif //_MAP_T_H_INCLUDED_
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/mem_block_mgr.h b/Plugins/listeningto/players/foo_mlt/pfc/mem_block_mgr.h
new file mode 100644
index 0000000..daaead0
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/mem_block_mgr.h
@@ -0,0 +1,71 @@
+#ifndef _MEM_BLOCK_MGR_H_
+#define _MEM_BLOCK_MGR_H_
+
+#error DEPRECATED
+
+
+template<class T>
+class mem_block_manager
+{
+ struct entry
+ {
+ mem_block_t<T> block;
+ bool used;
+ };
+ ptr_list_t<entry> list;
+public:
+ T * copy(const T* ptr,int size)
+ {
+ int n;
+ int found_size = -1,found_index = -1;
+ for(n=0;n<list.get_count();n++)
+ {
+ if (!list[n]->used)
+ {
+ int block_size = list[n]->block.get_size();
+ if (found_size<0)
+ {
+ found_index=n; found_size = block_size;
+ }
+ else if (found_size<size)
+ {
+ if (block_size>found_size)
+ {
+ found_index=n; found_size = block_size;
+ }
+ }
+ else if (found_size>size)
+ {
+ if (block_size>=size && block_size<found_size)
+ {
+ found_index=n; found_size = block_size;
+ }
+ }
+
+ if (found_size==size) break;
+ }
+ }
+ if (found_index>=0)
+ {
+ list[found_index]->used = true;
+ return list[found_index]->block.copy(ptr,size);
+ }
+ entry * new_entry = new entry;
+ new_entry->used = true;
+ list.add_item(new_entry);
+ return new_entry->block.copy(ptr,size);
+ }
+
+ void mark_as_free()
+ {
+ int n;
+ for(n=0;n<list.get_count();n++)
+ {
+ list[n]->used = false;
+ }
+ }
+
+ ~mem_block_manager() {list.delete_all();}
+};
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/order_helper.h b/Plugins/listeningto/players/foo_mlt/pfc/order_helper.h
new file mode 100644
index 0000000..019f8ba
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/order_helper.h
@@ -0,0 +1,42 @@
+class order_helper
+{
+ pfc::array_t<t_size> m_data;
+public:
+ order_helper(t_size p_size) {
+ m_data.set_size(p_size);
+ for(t_size n=0;n<p_size;n++) m_data[n]=n;
+ }
+
+ order_helper(const order_helper & p_order) {*this = p_order;}
+
+
+ template<typename t_int>
+ static void g_fill(t_int * p_order,const t_size p_count) {
+ t_size n; for(n=0;n<p_count;n++) p_order[n] = (t_int)n;
+ }
+
+ template<typename t_array>
+ static void g_fill(t_array & p_array) {
+ t_size n; const t_size max = pfc::array_size_t(p_array);
+ for(n=0;n<max;n++) p_array[n] = n;
+ }
+
+
+ t_size get_item(t_size ptr) const {return m_data[ptr];}
+
+ t_size & operator[](t_size ptr) {return m_data[ptr];}
+ t_size operator[](t_size ptr) const {return m_data[ptr];}
+
+ static void g_swap(t_size * p_data,t_size ptr1,t_size ptr2);
+ inline void swap(t_size ptr1,t_size ptr2) {pfc::swap_t(m_data[ptr1],m_data[ptr2]);}
+
+ const t_size * get_ptr() const {return m_data.get_ptr();}
+
+ static t_size g_find_reverse(const t_size * order,t_size val);
+ inline t_size find_reverse(t_size val) {return g_find_reverse(m_data.get_ptr(),val);}
+
+ static void g_reverse(t_size * order,t_size base,t_size count);
+ inline void reverse(t_size base,t_size count) {g_reverse(m_data.get_ptr(),base,count);}
+
+ t_size get_count() const {return m_data.get_size();}
+};
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/other.cpp b/Plugins/listeningto/players/foo_mlt/pfc/other.cpp
new file mode 100644
index 0000000..c883002
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/other.cpp
@@ -0,0 +1,56 @@
+#include "pfc.h"
+
+#include <intrin.h>
+
+
+void order_helper::g_swap(t_size * data,t_size ptr1,t_size ptr2)
+{
+ t_size temp = data[ptr1];
+ data[ptr1] = data[ptr2];
+ data[ptr2] = temp;
+}
+
+
+t_size order_helper::g_find_reverse(const t_size * order,t_size val)
+{
+ t_size prev = val, next = order[val];
+ while(next != val)
+ {
+ prev = next;
+ next = order[next];
+ }
+ return prev;
+}
+
+
+void order_helper::g_reverse(t_size * order,t_size base,t_size count)
+{
+ t_size max = count>>1;
+ t_size n;
+ t_size base2 = base+count-1;
+ for(n=0;n<max;n++)
+ g_swap(order,base+n,base2-n);
+}
+
+
+void pfc::crash() {
+#if 0 //def _MSC_VER
+ __debugbreak();
+#else
+ *(char*)NULL = 0;
+#endif
+}
+
+
+void pfc::byteswap_raw(void * p_buffer,const t_size p_bytes) {
+ t_uint8 * ptr = (t_uint8*)p_buffer;
+ t_size n;
+ for(n=0;n<p_bytes>>1;n++) swap_t(ptr[n],ptr[p_bytes-n-1]);
+}
+
+#if defined(_DEBUG) && defined(_WIN32)
+void pfc::myassert(const wchar_t * _Message, const wchar_t *_File, unsigned _Line) {
+ if (IsDebuggerPresent()) pfc::crash();
+ _wassert(_Message,_File,_Line);
+}
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/other.h b/Plugins/listeningto/players/foo_mlt/pfc/other.h
new file mode 100644
index 0000000..d5dd877
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/other.h
@@ -0,0 +1,170 @@
+#ifndef _PFC_OTHER_H_
+#define _PFC_OTHER_H_
+
+namespace pfc {
+ template<class T>
+ class vartoggle_t {
+ T oldval; T & var;
+ public:
+ vartoggle_t(T & p_var,const T & val) : var(p_var) {
+ oldval = var;
+ var = val;
+ }
+ ~vartoggle_t() {var = oldval;}
+ };
+
+ typedef vartoggle_t<bool> booltoggle;
+};
+
+#ifdef _MSC_VER
+
+class fpu_control
+{
+ unsigned old_val;
+ unsigned mask;
+public:
+ inline fpu_control(unsigned p_mask,unsigned p_val)
+ {
+ mask = p_mask;
+ _controlfp_s(&old_val,p_val,mask);
+ }
+ inline ~fpu_control()
+ {
+ unsigned dummy;
+ _controlfp_s(&dummy,old_val,mask);
+ }
+};
+
+class fpu_control_roundnearest : private fpu_control
+{
+public:
+ fpu_control_roundnearest() : fpu_control(_MCW_RC,_RC_NEAR) {}
+};
+
+class fpu_control_flushdenormal : private fpu_control
+{
+public:
+ fpu_control_flushdenormal() : fpu_control(_MCW_DN,_DN_FLUSH) {}
+};
+
+class fpu_control_default : private fpu_control
+{
+public:
+ fpu_control_default() : fpu_control(_MCW_DN|_MCW_RC,_DN_FLUSH|_RC_NEAR) {}
+};
+
+#ifdef _M_IX86
+class sse_control {
+public:
+ sse_control(unsigned p_mask,unsigned p_val) : m_mask(p_mask) {
+ __control87_2(p_val,p_mask,NULL,&m_oldval);
+ }
+ ~sse_control() {
+ __control87_2(m_oldval,m_mask,NULL,&m_oldval);
+ }
+private:
+ unsigned m_mask,m_oldval;
+};
+class sse_control_flushdenormal : private sse_control {
+public:
+ sse_control_flushdenormal() : sse_control(_MCW_DN,_DN_FLUSH) {}
+};
+#endif
+
+#endif
+
+namespace pfc {
+ class refcounter {
+ public:
+ refcounter(long p_val = 0) : m_val(p_val) {}
+#ifdef _WINDOWS
+ long operator++() {return InterlockedIncrement(&m_val);}
+ long operator--() {return InterlockedDecrement(&m_val);}
+#else
+ long operator++() {return ++m_val;}
+ long operator--() {return --m_val;}
+#pragma message("PORTME")
+#endif
+ private:
+ long m_val;
+ };
+
+ class releaser_delete {
+ public:
+ template<typename T> static void release(T* p_ptr) {delete p_ptr;}
+ };
+ class releaser_delete_array {
+ public:
+ template<typename T> static void release(T* p_ptr) {delete[] p_ptr;}
+ };
+ class releaser_free {
+ public:
+ static void release(void * p_ptr) {free(p_ptr);}
+ };
+
+ //! Assumes t_freefunc to never throw exceptions.
+ template<typename T,typename t_releaser = releaser_delete >
+ class ptrholder_t {
+ private:
+ typedef ptrholder_t<T,t_releaser> t_self;
+ public:
+ inline ptrholder_t(T* p_ptr) : m_ptr(p_ptr) {}
+ inline ptrholder_t() : m_ptr(NULL) {}
+ inline ~ptrholder_t() {t_releaser::release(m_ptr);}
+ inline bool is_valid() const {return m_ptr != NULL;}
+ inline bool is_empty() const {return m_ptr == NULL;}
+ inline T* operator->() const {return m_ptr;}
+ inline T* get_ptr() const {return m_ptr;}
+ inline void release() {t_releaser::release(replace_null_t(m_ptr));;}
+ inline void attach(T * p_ptr) {release(); m_ptr = p_ptr;}
+ inline const t_self & operator=(T * p_ptr) {set(p_ptr);return *this;}
+ inline T* detach() {return pfc::replace_null_t(m_ptr);}
+ inline T& operator*() const {return *m_ptr;}
+
+ inline t_self & operator<<(t_self & p_source) {attach(p_source.detach());return *this;}
+ inline t_self & operator>>(t_self & p_dest) {p_dest.attach(detach());return *this;}
+
+ //deprecated
+ inline void set(T * p_ptr) {attach(p_ptr);}
+ private:
+ ptrholder_t(const t_self &) {throw pfc::exception_not_implemented();}
+ const t_self & operator=(const t_self & ) {throw pfc::exception_not_implemented();}
+
+ T* m_ptr;
+ };
+
+ //avoid "void&" breakage
+ template<typename t_releaser>
+ class ptrholder_t<void,t_releaser> {
+ private:
+ typedef void T;
+ typedef ptrholder_t<T,t_releaser> t_self;
+ public:
+ inline ptrholder_t(T* p_ptr) : m_ptr(p_ptr) {}
+ inline ptrholder_t() : m_ptr(NULL) {}
+ inline ~ptrholder_t() {t_releaser::release(m_ptr);}
+ inline bool is_valid() const {return m_ptr != NULL;}
+ inline bool is_empty() const {return m_ptr == NULL;}
+ inline T* operator->() const {return m_ptr;}
+ inline T* get_ptr() const {return m_ptr;}
+ inline void release() {t_releaser::release(replace_null_t(m_ptr));;}
+ inline void attach(T * p_ptr) {release(); m_ptr = p_ptr;}
+ inline const t_self & operator=(T * p_ptr) {set(p_ptr);return *this;}
+ inline T* detach() {return pfc::replace_null_t(m_ptr);}
+
+ inline t_self & operator<<(t_self & p_source) {attach(p_source.detach());return *this;}
+ inline t_self & operator>>(t_self & p_dest) {p_dest.attach(detach());return *this;}
+
+ //deprecated
+ inline void set(T * p_ptr) {attach(p_ptr);}
+ private:
+ ptrholder_t(const t_self &) {throw pfc::exception_not_implemented();}
+ const t_self & operator=(const t_self & ) {throw pfc::exception_not_implemented();}
+
+ T* m_ptr;
+ };
+
+ void crash();
+}
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/pfc.h b/Plugins/listeningto/players/foo_mlt/pfc/pfc.h
new file mode 100644
index 0000000..3f6a7c0
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/pfc.h
@@ -0,0 +1,151 @@
+#ifndef ___PFC_H___
+#define ___PFC_H___
+
+#if !defined(_WINDOWS) && (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) || defined(_WIN32_WCE))
+#define _WINDOWS
+#endif
+
+
+#define PFC_DLL_EXPORT
+
+#if defined(_WIN32) || defined(_WIN32_WCE)
+
+#ifndef STRICT
+#define STRICT
+#endif
+
+#ifndef _SYS_GUID_OPERATOR_EQ_
+#define _NO_SYS_GUID_OPERATOR_EQ_ //fix retarded warning with operator== on GUID returning int
+#endif
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x500
+#endif
+
+#include <windows.h>
+
+#ifndef _SYS_GUID_OPERATOR_EQ_
+__inline bool __InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2)
+{
+ return (
+ ((unsigned long *) &rguid1)[0] == ((unsigned long *) &rguid2)[0] &&
+ ((unsigned long *) &rguid1)[1] == ((unsigned long *) &rguid2)[1] &&
+ ((unsigned long *) &rguid1)[2] == ((unsigned long *) &rguid2)[2] &&
+ ((unsigned long *) &rguid1)[3] == ((unsigned long *) &rguid2)[3]);
+}
+
+inline bool operator==(REFGUID guidOne, REFGUID guidOther) {return __InlineIsEqualGUID(guidOne,guidOther);}
+inline bool operator!=(REFGUID guidOne, REFGUID guidOther) {return !__InlineIsEqualGUID(guidOne,guidOther);}
+#endif
+
+#include <tchar.h>
+
+#elif defined(__GNUC__) && (defined __unix__ || defined __POSIX__)
+#include <stdint.h>
+#include <memory.h>
+typedef struct {
+ uint32_t Data1;
+ uint16_t Data2;
+ uint16_t Data3;
+ uint8_t Data4[ 8 ];
+ } GUID; //same as win32 GUID
+
+inline bool operator==(const GUID & p_item1,const GUID & p_item2) {
+ return memcmp(&p_item1,&p_item2,sizeof(GUID)) == 0;
+}
+
+inline bool operator!=(const GUID & p_item1,const GUID & p_item2) {
+ return memcmp(&p_item1,&p_item2,sizeof(GUID)) != 0;
+}
+
+#else
+
+#error Only win32 or unix target supported.
+
+#endif
+
+
+
+#define PFC_MEMORY_SPACE_LIMIT ((t_uint64)1<<(sizeof(void*)*8-1))
+
+#define PFC_ALLOCA_LIMIT (4096)
+
+#define INDEX_INVALID ((unsigned)(-1))
+
+
+#include <exception>
+#include <stdexcept>
+#include <new>
+
+#include <malloc.h>
+
+#include <stdio.h>
+
+#include <assert.h>
+
+#include <math.h>
+#include <float.h>
+
+
+#ifndef _DEBUG
+#define PFC_ASSERT(_Expression) ((void)0)
+#else
+#ifdef _WIN32
+namespace pfc { void myassert(const wchar_t * _Message, const wchar_t *_File, unsigned _Line); }
+#define PFC_ASSERT(_Expression) (void)( (!!(_Expression)) || (pfc::myassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
+#else
+#define PFC_ASSERT(_Expression) assert(_Expression)
+#endif
+#endif
+
+#ifdef _MSC_VER
+
+#ifdef _DEBUG
+#define NOVTABLE
+#else
+#define NOVTABLE _declspec(novtable)
+#endif
+
+#ifdef _DEBUG
+#define ASSUME(X) PFC_ASSERT(X)
+#else
+#define ASSUME(X) __assume(X)
+#endif
+
+#define PFC_DEPRECATE(X) __declspec(deprecated(X))
+#else
+
+#define NOVTABLE
+#define ASSUME(X) assert(X)
+#define PFC_DEPRECATE(X)
+
+#endif
+
+#include "int_types.h"
+#include "traits.h"
+#include "bit_array.h"
+#include "primitives.h"
+#include "alloc.h"
+#include "array.h"
+#include "bit_array_impl.h"
+#include "bsearch_inline.h"
+#include "bsearch.h"
+#include "sort.h"
+#include "order_helper.h"
+#include "list.h"
+#include "ptr_list.h"
+#include "string.h"
+#include "string_list.h"
+#include "avltree.h"
+#include "map.h"
+#include "profiler.h"
+#include "guid.h"
+#include "byte_order_helper.h"
+#include "other.h"
+#include "chainlist.h"
+#include "ref_counter.h"
+#include "rcptr.h"
+#include "com_ptr_t.h"
+#include "string_conv.h"
+#include "instance_tracker.h"
+#endif //___PFC_H___ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/pfc.vcproj b/Plugins/listeningto/players/foo_mlt/pfc/pfc.vcproj
new file mode 100644
index 0000000..2e09a74
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/pfc.vcproj
@@ -0,0 +1,766 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="pfc"
+ ProjectGUID="{EBFFFB4E-261D-44D3-B89C-957B31A0BF9C}"
+ RootNamespace="pfc"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS,PFC_DLL_EXPORTS"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="pfc.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS,PFC_DLL_EXPORTS"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="pfc.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;PFC_DLL_EXPORTS"
+ StringPooling="true"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="pfc.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;PFC_DLL_EXPORTS"
+ StringPooling="true"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="pfc.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\alloc.h"
+ >
+ </File>
+ <File
+ RelativePath="array.h"
+ >
+ </File>
+ <File
+ RelativePath=".\avltree.h"
+ >
+ </File>
+ <File
+ RelativePath="bit_array.h"
+ >
+ </File>
+ <File
+ RelativePath=".\bit_array_impl.h"
+ >
+ </File>
+ <File
+ RelativePath="bsearch.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="bsearch.h"
+ >
+ </File>
+ <File
+ RelativePath=".\bsearch_inline.h"
+ >
+ </File>
+ <File
+ RelativePath="byte_order_helper.h"
+ >
+ </File>
+ <File
+ RelativePath="chainlist.h"
+ >
+ </File>
+ <File
+ RelativePath=".\com_ptr_t.h"
+ >
+ </File>
+ <File
+ RelativePath="guid.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="guid.h"
+ >
+ </File>
+ <File
+ RelativePath=".\instance_tracker.h"
+ >
+ </File>
+ <File
+ RelativePath=".\int_types.h"
+ >
+ </File>
+ <File
+ RelativePath="list.h"
+ >
+ </File>
+ <File
+ RelativePath=".\map.h"
+ >
+ </File>
+ <File
+ RelativePath=".\order_helper.h"
+ >
+ </File>
+ <File
+ RelativePath="other.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="other.h"
+ >
+ </File>
+ <File
+ RelativePath="pfc.h"
+ >
+ </File>
+ <File
+ RelativePath="primitives.h"
+ >
+ </File>
+ <File
+ RelativePath=".\printf.cpp"
+ >
+ </File>
+ <File
+ RelativePath="profiler.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="profiler.h"
+ >
+ </File>
+ <File
+ RelativePath="ptr_list.h"
+ >
+ </File>
+ <File
+ RelativePath=".\rcptr.h"
+ >
+ </File>
+ <File
+ RelativePath="ref_counter.h"
+ >
+ </File>
+ <File
+ RelativePath=".\selftest.cpp"
+ >
+ </File>
+ <File
+ RelativePath="sort.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="sort.h"
+ >
+ </File>
+ <File
+ RelativePath="stdafx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="string.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="string.h"
+ >
+ </File>
+ <File
+ RelativePath=".\string8_impl.h"
+ >
+ </File>
+ <File
+ RelativePath=".\string_conv.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\string_conv.h"
+ >
+ </File>
+ <File
+ RelativePath=".\string_list.h"
+ >
+ </File>
+ <File
+ RelativePath=".\traits.h"
+ >
+ </File>
+ <File
+ RelativePath="utf8.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/pfc.vcproj.NOTEBOOK.pescuma.user b/Plugins/listeningto/players/foo_mlt/pfc/pfc.vcproj.NOTEBOOK.pescuma.user
new file mode 100644
index 0000000..4494b4d
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/pfc.vcproj.NOTEBOOK.pescuma.user
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioUserFile
+ ProjectType="Visual C++"
+ Version="8,00"
+ ShowAllFiles="false"
+ >
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ >
+ <DebugSettings
+ Command=""
+ WorkingDirectory=""
+ CommandArguments=""
+ Attach="false"
+ DebuggerType="3"
+ Remote="1"
+ RemoteMachine="NOTEBOOK"
+ RemoteCommand=""
+ HttpUrl=""
+ PDBPath=""
+ SQLDebugging=""
+ Environment=""
+ EnvironmentMerge="true"
+ DebuggerFlavor=""
+ MPIRunCommand=""
+ MPIRunArguments=""
+ MPIRunWorkingDirectory=""
+ ApplicationCommand=""
+ ApplicationArguments=""
+ ShimCommand=""
+ MPIAcceptMode=""
+ MPIAcceptFilter=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ >
+ <DebugSettings
+ Command=""
+ WorkingDirectory=""
+ CommandArguments=""
+ Attach="false"
+ DebuggerType="3"
+ Remote="1"
+ RemoteMachine="NOTEBOOK"
+ RemoteCommand=""
+ HttpUrl=""
+ PDBPath=""
+ SQLDebugging=""
+ Environment=""
+ EnvironmentMerge="true"
+ DebuggerFlavor=""
+ MPIRunCommand=""
+ MPIRunArguments=""
+ MPIRunWorkingDirectory=""
+ ApplicationCommand=""
+ ApplicationArguments=""
+ ShimCommand=""
+ MPIAcceptMode=""
+ MPIAcceptFilter=""
+ />
+ </Configuration>
+ </Configurations>
+</VisualStudioUserFile>
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/primitives.h b/Plugins/listeningto/players/foo_mlt/pfc/primitives.h
new file mode 100644
index 0000000..d9fc8c2
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/primitives.h
@@ -0,0 +1,731 @@
+#define tabsize(x) ((size_t)(sizeof(x)/sizeof(*x)))
+
+#define TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD_WITH_INITIALIZER(THISCLASS,MEMBER,INITIALIZER) \
+ THISCLASS() INITIALIZER \
+ template<typename t_param1> THISCLASS(const t_param1 & p_param1) : MEMBER(p_param1) INITIALIZER \
+ template<typename t_param1,typename t_param2> THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2) : MEMBER(p_param1,p_param2) INITIALIZER \
+ template<typename t_param1,typename t_param2,typename t_param3> THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3) : MEMBER(p_param1,p_param2,p_param3) INITIALIZER \
+ template<typename t_param1,typename t_param2,typename t_param3,typename t_param4> THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4) : MEMBER(p_param1,p_param2,p_param3,p_param4) INITIALIZER \
+ template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5> THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4,const t_param5 & p_param5) : MEMBER(p_param1,p_param2,p_param3,p_param4,p_param5) INITIALIZER \
+ template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5,typename t_param6> THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4,const t_param5 & p_param5,const t_param6 & p_param6) : MEMBER(p_param1,p_param2,p_param3,p_param4,p_param5,p_param6) INITIALIZER \
+ template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5,typename t_param6, typename t_param7> THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4,const t_param5 & p_param5,const t_param6 & p_param6,const t_param7 & p_param7) : MEMBER(p_param1,p_param2,p_param3,p_param4,p_param5,p_param6,p_param7) INITIALIZER
+
+#define TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(THISCLASS,MEMBER) TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD_WITH_INITIALIZER(THISCLASS,MEMBER,{})
+
+
+#ifdef _MSC_VER
+
+//Bah. I noticed the fact that std::exception carrying a custom message is MS-specific *after* making exception classes a part of ABI. To be nuked next time fb2k component backwards compatibility is axed.
+
+#define PFC_DECLARE_EXCEPTION(NAME,BASECLASS,DEFAULTMSG) \
+class NAME : public BASECLASS { \
+public: \
+ static const char * g_what() {return DEFAULTMSG;} \
+ NAME() : BASECLASS(DEFAULTMSG,0) {} \
+ NAME(const char * p_msg) : BASECLASS(p_msg) {} \
+ NAME(const char * p_msg,int) : BASECLASS(p_msg,0) {} \
+ NAME(const NAME & p_source) : BASECLASS(p_source) {} \
+};
+
+namespace pfc {
+ template<typename t_exception> inline void throw_exception_with_message(const char * p_message) {
+ throw t_exception(p_message);
+ }
+}
+
+#else
+
+#define PFC_DECLARE_EXCEPTION(NAME,BASECLASS,DEFAULTMSG) \
+class NAME : public BASECLASS { \
+public: \
+ static const char * g_what() {return DEFAULTMSG;} \
+ const char* what() const throw() {return DEFAULTMSG;} \
+};
+
+namespace pfc {
+ template<typename t_base> class __exception_with_message_t : public t_base {
+ private: typedef __exception_with_message_t<t_base> t_self;
+ public:
+ __exception_with_message_t(const char * p_message) : m_message(NULL) {
+ set_message(p_message);
+ }
+ __exception_with_message_t() : m_message(NULL) {}
+ __exception_with_message_t(const t_self & p_source) : m_message(NULL) {set_message(p_source.m_message);}
+
+ const char* what() const throw() {return m_message != NULL ? m_message : "unnamed exception";}
+
+ const t_self & operator=(const t_self & p_source) {set_message(p_source.m_message);}
+
+ ~__exception_with_message_t() throw() {cleanup();}
+
+ private:
+ void set_message(const char * p_message) throw() {
+ cleanup();
+ if (p_message != NULL) m_message = strdup(p_message);
+ }
+ void cleanup() throw() {
+ if (m_message != NULL) {free(m_message); m_message = NULL;}
+ }
+ char * m_message;
+ };
+ template<typename t_exception> void throw_exception_with_message(const char * p_message) {
+ throw __exception_with_message_t<t_exception>(p_message);
+ }
+}
+#endif
+
+namespace pfc {
+
+ template<typename p_type1,typename p_type2> class assert_same_type;
+ template<typename p_type> class assert_same_type<p_type,p_type> {};
+
+ template<typename p_type1,typename p_type2>
+ class is_same_type { public: enum {value = false}; };
+
+ template<typename p_type>
+ class is_same_type<p_type,p_type> { public: enum {value = true}; };
+
+ template<bool p_val> class __static_assert_switcher_t;
+ template<> class __static_assert_switcher_t<true> {
+ public:
+ typedef void t_assert_failed;
+ };
+
+ //depreacted
+ template<bool p_val> typename __static_assert_switcher_t<p_val>::t_assert_failed static_assert_t() {}
+
+ template<bool p_val> typename __static_assert_switcher_t<p_val>::t_assert_failed static_assert() {}
+
+ template<typename t_type>
+ void assert_raw_type() {static_assert_t< !traits_t<t_type>::needs_constructor && !traits_t<t_type>::needs_destructor >();}
+
+
+ template<typename t_type> void __unsafe__memcpy_t(t_type * p_dst,const t_type * p_src,t_size p_count) {
+ ::memcpy(reinterpret_cast<void*>(p_dst), reinterpret_cast<const void*>(p_src), p_count * sizeof(t_type));
+ }
+
+ template<typename t_type> void __unsafe__in_place_destructor_t(t_type & p_item) throw() {
+ if (traits_t<t_type>::needs_destructor) try{ p_item.~t_type(); } catch(...) {}
+ }
+
+ template<typename t_type> void __unsafe__in_place_constructor_t(t_type & p_item) {
+ if (traits_t<t_type>::needs_constructor) {
+ t_type * ret = new(&p_item) t_type;
+ PFC_ASSERT(ret == &p_item);
+ }
+ }
+
+ template<typename t_type> void __unsafe__in_place_destructor_array_t(t_type * p_items, t_size p_count) throw() {
+ if (traits_t<t_type>::needs_destructor) {
+ t_type * walk = p_items;
+ for(t_size n=p_count;n;--n) __unsafe__in_place_destructor_t(*(walk++));
+ }
+ }
+
+ template<typename t_type> t_type * __unsafe__in_place_constructor_array_t(t_type * p_items,t_size p_count) {
+ if (traits_t<t_type>::needs_constructor) {
+ t_size walkptr = 0;
+ try {
+ for(walkptr=0;walkptr<p_count;++walkptr) __unsafe__in_place_constructor_t(p_items[walkptr]);
+ } catch(...) {
+ __unsafe__in_place_destructor_array_t(p_items,walkptr);
+ throw;
+ }
+ }
+ return p_items;
+ }
+
+ template<typename t_type> t_type * __unsafe__in_place_resize_array_t(t_type * p_items,t_size p_from,t_size p_to) {
+ if (p_from < p_to) __unsafe__in_place_constructor_array_t(p_items + p_from, p_to - p_from);
+ else if (p_from > p_to) __unsafe__in_place_destructor_array_t(p_items + p_to, p_from - p_to);
+ return p_items;
+ }
+
+ template<typename t_type,typename t_copy> void __unsafe__in_place_constructor_copy_t(t_type & p_item,const t_copy & p_copyfrom) {
+ if (traits_t<t_type>::needs_constructor) {
+ t_type * ret = new(&p_item) t_type(p_copyfrom);
+ PFC_ASSERT(ret == &p_item);
+ } else {
+ p_item = p_copyfrom;
+ }
+ }
+
+ template<typename t_type,typename t_copy> t_type * __unsafe__in_place_constructor_array_copy_t(t_type * p_items,t_size p_count, const t_copy * p_copyfrom) {
+ t_size walkptr = 0;
+ try {
+ for(walkptr=0;walkptr<p_count;++walkptr) __unsafe__in_place_constructor_copy_t(p_items[walkptr],p_copyfrom[walkptr]);
+ } catch(...) {
+ __unsafe__in_place_destructor_array_t(p_items,walkptr);
+ throw;
+ }
+ return p_items;
+ }
+
+ template<typename t_type,typename t_copy> t_type * __unsafe__in_place_constructor_array_copy_partial_t(t_type * p_items,t_size p_count, const t_copy * p_copyfrom,t_size p_copyfrom_count) {
+ if (p_copyfrom_count > p_count) p_copyfrom_count = p_count;
+ __unsafe__in_place_constructor_array_copy_t(p_items,p_copyfrom_count,p_copyfrom);
+ try {
+ __unsafe__in_place_constructor_array_t(p_items + p_copyfrom_count,p_count - p_copyfrom_count);
+ } catch(...) {
+ __unsafe__in_place_destructor_array_t(p_items,p_copyfrom_count);
+ throw;
+ }
+ return p_items;
+ }
+
+ template<typename t_ret,typename t_param>
+ t_ret safe_cast(t_param const & p_param) {
+ return p_param;
+ }
+
+ template<typename t_ret,typename t_param>
+ t_ret * safe_ptr_cast(t_param * p_param) {
+ if (pfc::is_same_type<t_ret,t_param>::value) return p_param;
+ else {
+ if (p_param == NULL) return NULL;
+ else return p_param;
+ }
+ }
+
+ typedef std::exception exception;
+
+ PFC_DECLARE_EXCEPTION(exception_overflow,exception,"Overflow");
+ PFC_DECLARE_EXCEPTION(exception_bug_check,exception,"Bug check");
+ PFC_DECLARE_EXCEPTION(exception_unexpected_recursion,exception_bug_check,"Unexpected recursion");
+ PFC_DECLARE_EXCEPTION(exception_not_implemented,exception_bug_check,"Feature not implemented");
+ PFC_DECLARE_EXCEPTION(exception_dynamic_assert,exception_bug_check,"dynamic_assert failure");
+
+ template<typename t_ret,typename t_param>
+ t_ret downcast_guarded(const t_param & p_param) {
+ t_ret temp = (t_ret) p_param;
+ if ((t_param) temp != p_param) throw exception_overflow();
+ return temp;
+ }
+
+ template<typename t_exception,typename t_ret,typename t_param>
+ t_ret downcast_guarded_ex(const t_param & p_param) {
+ t_ret temp = (t_ret) p_param;
+ if ((t_param) temp != p_param) throw t_exception();
+ return temp;
+ }
+
+ template<typename t_acc,typename t_add>
+ void accumulate_guarded(t_acc & p_acc, const t_add & p_add) {
+ t_acc delta = downcast_guarded<t_acc>(p_add);
+ delta += p_acc;
+ if (delta < p_acc) throw exception_overflow();
+ p_acc = delta;
+ }
+
+ //deprecated
+ inline void bug_check_assert(bool p_condition, const char * p_msg) {
+ if (!p_condition) {
+ PFC_ASSERT(0);
+ throw_exception_with_message<exception_bug_check>(p_msg);
+ }
+ }
+ //deprecated
+ inline void bug_check_assert(bool p_condition) {
+ if (!p_condition) {
+ PFC_ASSERT(0);
+ throw exception_bug_check();
+ }
+ }
+
+ inline void dynamic_assert(bool p_condition, const char * p_msg) {
+ if (!p_condition) {
+ PFC_ASSERT(0);
+ throw_exception_with_message<exception_dynamic_assert>(p_msg);
+ }
+ }
+ inline void dynamic_assert(bool p_condition) {
+ if (!p_condition) {
+ PFC_ASSERT(0);
+ throw exception_dynamic_assert();
+ }
+ }
+
+ template<typename T>
+ inline void swap_multi_t(T * p_buffer1,T * p_buffer2,t_size p_size) {
+ T * walk1 = p_buffer1, * walk2 = p_buffer2;
+ for(t_size n=p_size;n;--n) {
+ T temp (* walk1);
+ *walk1 = *walk2;
+ *walk2 = temp;
+ walk1++; walk2++;
+ }
+ }
+
+ template<typename T,t_size p_size>
+ inline void swap_multi_t(T * p_buffer1,T * p_buffer2) {
+ T * walk1 = p_buffer1, * walk2 = p_buffer2;
+ for(t_size n=p_size;n;--n) {
+ T temp (* walk1);
+ *walk1 = *walk2;
+ *walk2 = temp;
+ walk1++; walk2++;
+ }
+ }
+
+
+ template<t_size p_size>
+ inline void __unsafe__swap_raw_t(void * p_object1, void * p_object2) {
+ if (p_size % sizeof(t_size) == 0) {
+ swap_multi_t<t_size,p_size/sizeof(t_size)>(reinterpret_cast<t_size*>(p_object1),reinterpret_cast<t_size*>(p_object2));
+ } else {
+ swap_multi_t<t_uint8,p_size>(reinterpret_cast<t_uint8*>(p_object1),reinterpret_cast<t_uint8*>(p_object2));
+ }
+ }
+
+ template<typename T>
+ inline void swap_t(T & p_item1, T & p_item2) {
+ if (traits_t<T>::realloc_safe) {
+ __unsafe__swap_raw_t<sizeof(T)>( reinterpret_cast<void*>( &p_item1 ), reinterpret_cast<void*>( &p_item2 ) );
+ } else {
+ T temp(p_item2);
+ p_item2 = p_item1;
+ p_item1 = temp;
+ }
+ }
+
+ template<typename t_array>
+ t_size array_size_t(const t_array & p_array) {return p_array.get_size();}
+
+ template<typename t_item, t_size p_width>
+ t_size array_size_t(const t_item (&p_array)[p_width]) {return p_width;}
+
+
+ template<typename t_array,typename t_filler>
+ inline void fill_t(t_array & p_buffer,const t_size p_count, const t_filler & p_filler) {
+ for(t_size n=0;n<p_count;n++)
+ p_buffer[n] = p_filler;
+ }
+
+ template<typename t_array,typename t_filler>
+ inline void fill_ptr_t(t_array * p_buffer,const t_size p_count, const t_filler & p_filler) {
+ for(t_size n=0;n<p_count;n++)
+ p_buffer[n] = p_filler;
+ }
+
+ template<typename t_item1, typename t_item2>
+ inline int compare_t(const t_item1 & p_item1, const t_item2 & p_item2) {
+ if (p_item1 < p_item2) return -1;
+ else if (p_item1 > p_item2) return 1;
+ else return 0;
+ }
+
+ //! For use with avltree/map etc.
+ class comparator_default {
+ public:
+ template<typename t_item1,typename t_item2>
+ inline static int compare(const t_item1 & p_item1,const t_item2 & p_item2) {return pfc::compare_t(p_item1,p_item2);}
+ };
+
+ class comparator_memcmp {
+ public:
+ template<typename t_item1,typename t_item2>
+ inline static int compare(const t_item1 & p_item1,const t_item2 & p_item2) {
+ static_assert<sizeof(t_item1) == sizeof(t_item2)>();
+ return memcmp(&p_item1,&p_item2,sizeof(t_item1));
+ }
+ };
+
+ template<typename t_source1, typename t_source2>
+ t_size subtract_sorted_lists_calculate_count(const t_source1 & p_source1, const t_source2 & p_source2) {
+ t_size walk1 = 0, walk2 = 0, walk_out = 0;
+ const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size();
+ for(;;) {
+ int state;
+ if (walk1 < max1 && walk2 < max2) {
+ state = pfc::compare_t(p_source1[walk1],p_source2[walk2]);
+ } else if (walk1 < max1) {
+ state = -1;
+ } else if (walk2 < max2) {
+ state = 1;
+ } else {
+ break;
+ }
+ if (state < 0) walk_out++;
+ if (state <= 0) walk1++;
+ if (state >= 0) walk2++;
+ }
+ return walk_out;
+ }
+
+ //! Subtracts p_source2 contents from p_source1 and stores result in p_destination. Both source lists must be sorted.
+ //! Note: duplicates will be carried over (and ignored for p_source2).
+ template<typename t_destination, typename t_source1, typename t_source2>
+ void subtract_sorted_lists(t_destination & p_destination,const t_source1 & p_source1, const t_source2 & p_source2) {
+ p_destination.set_size(subtract_sorted_lists_calculate_count(p_source1,p_source2));
+ t_size walk1 = 0, walk2 = 0, walk_out = 0;
+ const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size();
+ for(;;) {
+ int state;
+ if (walk1 < max1 && walk2 < max2) {
+ state = pfc::compare_t(p_source1[walk1],p_source2[walk2]);
+ } else if (walk1 < max1) {
+ state = -1;
+ } else if (walk2 < max2) {
+ state = 1;
+ } else {
+ break;
+ }
+
+
+ if (state < 0) p_destination[walk_out++] = p_source1[walk1];
+ if (state <= 0) walk1++;
+ if (state >= 0) walk2++;
+ }
+ }
+
+ template<typename t_source1, typename t_source2>
+ t_size merge_sorted_lists_calculate_count(const t_source1 & p_source1, const t_source2 & p_source2) {
+ t_size walk1 = 0, walk2 = 0, walk_out = 0;
+ const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size();
+ for(;;) {
+ int state;
+ if (walk1 < max1 && walk2 < max2) {
+ state = pfc::compare_t(p_source1[walk1],p_source2[walk2]);
+ } else if (walk1 < max1) {
+ state = -1;
+ } else if (walk2 < max2) {
+ state = 1;
+ } else {
+ break;
+ }
+ if (state <= 0) walk1++;
+ if (state >= 0) walk2++;
+ walk_out++;
+ }
+ return walk_out;
+ }
+
+ //! Merges p_source1 and p_source2, storing content in p_destination. Both source lists must be sorted.
+ //! Note: duplicates will be carried over.
+ template<typename t_destination, typename t_source1, typename t_source2>
+ void merge_sorted_lists(t_destination & p_destination,const t_source1 & p_source1, const t_source2 & p_source2) {
+ p_destination.set_size(merge_sorted_lists_calculate_count(p_source1,p_source2));
+ t_size walk1 = 0, walk2 = 0, walk_out = 0;
+ const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size();
+ for(;;) {
+ int state;
+ if (walk1 < max1 && walk2 < max2) {
+ state = pfc::compare_t(p_source1[walk1],p_source2[walk2]);
+ } else if (walk1 < max1) {
+ state = -1;
+ } else if (walk2 < max2) {
+ state = 1;
+ } else {
+ break;
+ }
+ if (state < 0) {
+ p_destination[walk_out] = p_source1[walk1++];
+ } else if (state > 0) {
+ p_destination[walk_out] = p_source2[walk2++];
+ } else {
+ p_destination[walk_out] = p_source1[walk1];
+ walk1++; walk2++;
+ }
+ walk_out++;
+ }
+ }
+
+
+
+ template<typename t_array,typename T>
+ inline t_size append_t(t_array & p_array,const T & p_item)
+ {
+ t_size old_count = p_array.get_size();
+ p_array.set_size(old_count + 1);
+ p_array[old_count] = p_item;
+ return old_count;
+ }
+
+ template<typename t_array,typename T>
+ inline t_size append_swap_t(t_array & p_array,T & p_item)
+ {
+ t_size old_count = p_array.get_size();
+ p_array.set_size(old_count + 1);
+ swap_t(p_array[old_count],p_item);
+ return old_count;
+ }
+
+ template<typename t_array,typename T>
+ inline t_size insert_t(t_array & p_array,const T & p_item,t_size p_index)
+ {
+ t_size old_count = p_array.get_size();
+ if (p_index > old_count) p_index = old_count;
+ p_array.set_size(old_count + 1);
+ for(t_size n=old_count;n>p_index;n--)
+ p_array[n] = p_array[n-1];
+ p_array[p_index] = p_item;
+ return p_index;
+ }
+
+ template<typename t_array,typename T>
+ inline t_size insert_swap_t(t_array & p_array,T & p_item,t_size p_index)
+ {
+ t_size old_count = p_array.get_size();
+ if (p_index > old_count) p_index = old_count;
+ p_array.set_size(old_count + 1);
+ for(t_size n=old_count;n>p_index;n--)
+ swap_t(p_array[n],p_array[n-1]);
+ swap_t(p_array[p_index],p_item);
+ return p_index;
+ }
+
+
+ template<typename T>
+ inline T max_t(const T & item1, const T & item2) {return item1 > item2 ? item1 : item2;};
+
+ template<typename T>
+ inline T min_t(const T & item1, const T & item2) {return item1 < item2 ? item1 : item2;};
+
+ template<typename T>
+ inline T abs_t(T item) {return item<0 ? -item : item;}
+
+ template<typename T>
+ inline T sqr_t(T item) {return item * item;}
+
+ template<typename T>
+ inline T clip_t(const T & p_item, const T & p_min, const T & p_max) {
+ if (p_item < p_min) return p_min;
+ else if (p_item <= p_max) return p_item;
+ else return p_max;
+ }
+
+
+
+
+
+ template<typename T>
+ inline void delete_t(T* ptr) {delete ptr;}
+
+ template<typename T>
+ inline void delete_array_t(T* ptr) {delete[] ptr;}
+
+ template<typename T>
+ inline T* clone_t(T* ptr) {return new T(*ptr);}
+
+
+ template<typename t_exception,typename t_int>
+ inline t_int mul_safe_t(t_int p_val1,t_int p_val2) {
+ if (p_val1 == 0 || p_val2 == 0) return 0;
+ t_int temp = (t_int) (p_val1 * p_val2);
+ if (temp < p_val1 || temp < p_val2) throw t_exception();
+ return temp;
+ }
+
+ template<typename t_src,typename t_dst>
+ void memcpy_t(t_dst* p_dst,const t_src* p_src,t_size p_count) {
+ for(t_size n=0;n<p_count;n++) p_dst[n] = p_src[n];
+ }
+
+ template<typename t_dst,typename t_src>
+ void copy_array_loop_t(t_dst & p_dst,const t_src & p_src,t_size p_count) {
+ for(t_size n=0;n<p_count;n++) p_dst[n] = p_src[n];
+ }
+
+ template<typename t_src,typename t_dst>
+ void memcpy_backwards_t(t_dst * p_dst,const t_src * p_src,t_size p_count) {
+ p_dst += p_count; p_src += p_count;
+ for(t_size n=0;n<p_count;n++) *(--p_dst) = *(--p_src);
+ }
+
+ template<typename T,typename t_val>
+ void memset_t(T * p_buffer,const t_val & p_val,t_size p_count) {
+ for(t_size n=0;n<p_count;n++) p_buffer[n] = p_val;
+ }
+
+ template<typename T,typename t_val>
+ void memset_t(T &p_buffer,const t_val & p_val) {
+ const t_size width = pfc::array_size_t(p_buffer);
+ for(t_size n=0;n<width;n++) p_buffer[n] = p_val;
+ }
+
+ template<typename T>
+ void memset_null_t(T * p_buffer,t_size p_count) {
+ for(t_size n=0;n<p_count;n++) p_buffer[n] = 0;
+ }
+
+ template<typename T>
+ void memset_null_t(T &p_buffer) {
+ const t_size width = pfc::array_size_t(p_buffer);
+ for(t_size n=0;n<width;n++) p_buffer[n] = 0;
+ }
+
+ template<typename T>
+ void memmove_t(T* p_dst,const T* p_src,t_size p_count) {
+ if (p_dst == p_src) {/*do nothing*/}
+ else if (p_dst > p_src && p_dst < p_src + p_count) memcpy_backwards_t<T>(p_dst,p_src,p_count);
+ else memcpy_t<T>(p_dst,p_src,p_count);
+ }
+
+ template<typename T>
+ T* new_ptr_check_t(T* p_ptr) {
+ if (p_ptr == NULL) throw std::bad_alloc();
+ return p_ptr;
+ }
+
+ template<typename T>
+ int sgn_t(const T & p_val) {
+ if (p_val < 0) return -1;
+ else if (p_val > 0) return 1;
+ else return 0;
+ }
+
+ template<typename T> const T* empty_string_t();
+
+ template<> inline const char * empty_string_t<char>() {return "";}
+ template<> inline const wchar_t * empty_string_t<wchar_t>() {return L"";}
+
+
+ template<typename t_type,typename t_newval>
+ t_type replace_t(t_type & p_var,const t_newval & p_newval) {
+ t_type oldval = p_var;
+ p_var = p_newval;
+ return oldval;
+ }
+ template<typename t_type>
+ t_type replace_null_t(t_type & p_var) {
+ t_type ret = p_var;
+ p_var = NULL;
+ return ret;
+ }
+
+ template<t_size p_size_pow2>
+ inline bool is_ptr_aligned_t(const void * p_ptr) {
+ static_assert_t< (p_size_pow2 & (p_size_pow2 - 1)) == 0 >();
+ return ( ((t_size)p_ptr) & (p_size_pow2-1) ) == 0;
+ }
+
+
+ template<typename t_array>
+ void array_rangecheck_t(const t_array & p_array,t_size p_index) {
+ if (p_index >= pfc::array_size_t(p_array)) throw pfc::exception_overflow();
+ }
+
+ template<typename t_array>
+ void array_rangecheck_t(const t_array & p_array,t_size p_from,t_size p_to) {
+ if (p_from > p_to) throw pfc::exception_overflow();
+ array_rangecheck_t(p_array,p_from); array_rangecheck_t(p_array,p_to);
+ }
+
+ inline t_int32 rint32(double p_val) {return (t_int32) floor(p_val + 0.5);}
+ inline t_int64 rint64(double p_val) {return (t_int64) floor(p_val + 0.5);}
+
+
+
+
+ template<typename t_array>
+ inline t_size remove_mask_t(t_array & p_array,const bit_array & p_mask)//returns amount of items left
+ {
+ t_size n,count = p_array.get_size(), total = 0;
+
+ n = total = p_mask.find(true,0,count);
+
+ if (n<count)
+ {
+ for(n=p_mask.find(false,n+1,count-n-1);n<count;n=p_mask.find(false,n+1,count-n-1))
+ swap_t(p_array[total++],p_array[n]);
+
+ p_array.set_size(total);
+
+ return total;
+ }
+ else return count;
+ }
+
+ template<typename t_array,typename t_compare>
+ t_size find_duplicates_sorted_t(t_array p_array,t_size p_count,t_compare p_compare,bit_array_var & p_out) {
+ t_size ret = 0;
+ t_size n;
+ if (p_count > 0)
+ {
+ p_out.set(0,false);
+ for(n=1;n<p_count;n++)
+ {
+ bool found = p_compare(p_array[n-1],p_array[n]) == 0;
+ if (found) ret++;
+ p_out.set(n,found);
+ }
+ }
+ return ret;
+ }
+
+ template<typename t_array,typename t_compare,typename t_permutation>
+ t_size find_duplicates_sorted_permutation_t(t_array p_array,t_size p_count,t_compare p_compare,t_permutation const & p_permutation,bit_array_var & p_out) {
+ t_size ret = 0;
+ t_size n;
+ if (p_count > 0) {
+ p_out.set(p_permutation[0],false);
+ for(n=1;n<p_count;n++)
+ {
+ bool found = p_compare(p_array[p_permutation[n-1]],p_array[p_permutation[n]]) == 0;
+ if (found) ret++;
+ p_out.set(p_permutation[n],found);
+ }
+ }
+ return ret;
+ }
+
+ template<typename t_char>
+ t_size strlen_t(const t_char * p_string,t_size p_length = infinite) {
+ for(t_size walk = 0;;walk++) {
+ if (walk >= p_length || p_string[walk] == 0) return walk;
+ }
+ }
+
+
+ template<typename t_array>
+ class __list_to_array_enumerator {
+ public:
+ __list_to_array_enumerator(t_array & p_array) : m_array(p_array), m_walk(0) {}
+ template<typename t_item>
+ void operator() (const t_item & p_item) {
+ PFC_ASSERT(m_walk < m_array.get_size());
+ m_array[m_walk++] = p_item;
+ }
+ void finalize() {
+ PFC_ASSERT(m_walk == m_array.get_size());
+ }
+ private:
+ t_size m_walk;
+ t_array & m_array;
+ };
+
+ template<typename t_list,typename t_array>
+ void list_to_array(t_array & p_array,const t_list & p_list) {
+ p_array.set_size(p_list.get_count());
+ __list_to_array_enumerator<t_array> enumerator(p_array);
+ p_list.enumerate(enumerator);
+ enumerator.finalize();
+ }
+
+ template<typename t_receiver>
+ class enumerator_add_item {
+ public:
+ enumerator_add_item(t_receiver & p_receiver) : m_receiver(p_receiver) {}
+ template<typename t_item> void operator() (const t_item & p_item) {m_receiver.add_item(p_item);}
+ private:
+ t_receiver & m_receiver;
+ };
+
+ template<typename t_receiver,typename t_giver>
+ void overwrite_list_enumerated(t_receiver & p_receiver,const t_giver & p_giver) {
+ enumerator_add_item<t_receiver> wrapper(p_receiver);
+ p_giver.enumerate(wrapper);
+ }
+
+ template<typename t_receiver,typename t_giver>
+ void copy_list_enumerated(t_receiver & p_receiver,const t_giver & p_giver) {
+ p_receiver.remove_all();
+ overwrite_list_enumerated(p_receiver,p_giver);
+ }
+};
+
+
+#define PFC_CLASS_NOT_COPYABLE(THISCLASSNAME,THISTYPE) \
+ private: \
+ THISCLASSNAME(const THISTYPE&) {throw pfc::exception_bug_check();} \
+ const THISTYPE & operator=(const THISTYPE &) {throw pfc::exception_bug_check();}
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/printf.cpp b/Plugins/listeningto/players/foo_mlt/pfc/printf.cpp
new file mode 100644
index 0000000..cdfa6a5
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/printf.cpp
@@ -0,0 +1,117 @@
+#include "pfc.h"
+
+//implementations of deprecated string_printf methods, with a pragma to disable warnings when they reference other deprecated methods.
+
+#pragma warning(disable:4996)
+
+namespace pfc {
+
+void string_printf::run(const char * fmt,va_list list) {g_run(*this,fmt,list);}
+
+string_printf_va::string_printf_va(const char * fmt,va_list list) {string_printf::g_run(*this,fmt,list);}
+
+void string_printf::g_run(string_base & out,const char * fmt,va_list list)
+{
+ out.reset();
+ while(*fmt)
+ {
+ if (*fmt=='%')
+ {
+ fmt++;
+ if (*fmt=='%')
+ {
+ out.add_char('%');
+ fmt++;
+ }
+ else
+ {
+ bool force_sign = false;
+ if (*fmt=='+')
+ {
+ force_sign = true;
+ fmt++;
+ }
+ char padchar = (*fmt == '0') ? '0' : ' ';
+ t_size pad = 0;
+ while(*fmt>='0' && *fmt<='9')
+ {
+ pad = pad * 10 + (*fmt - '0');
+ fmt++;
+ }
+
+ if (*fmt=='s' || *fmt=='S')
+ {
+ const char * ptr = va_arg(list,const char*);
+ t_size len = strlen(ptr);
+ if (pad>len) out.add_chars(padchar,pad-len);
+ out.add_string(ptr);
+ fmt++;
+
+ }
+ else if (*fmt=='i' || *fmt=='I' || *fmt=='d' || *fmt=='D')
+ {
+ char temp[8*sizeof(int)];
+ int val = va_arg(list,int);
+ if (force_sign && val>0) out.add_char('+');
+ _itoa_s(val,temp,10);
+ t_size len = strlen(temp);
+ if (pad>len) out.add_chars(padchar,pad-len);
+ out.add_string(temp);
+ fmt++;
+ }
+ else if (*fmt=='u' || *fmt=='U')
+ {
+ char temp[8*sizeof(int)];
+ int val = va_arg(list,int);
+ if (force_sign && val>0) out.add_char('+');
+ _ultoa_s(val,temp,10);
+ t_size len = strlen(temp);
+ if (pad>len) out.add_chars(padchar,pad-len);
+ out.add_string(temp);
+ fmt++;
+ }
+ else if (*fmt=='x' || *fmt=='X')
+ {
+ char temp[8*sizeof(int)];
+ int val = va_arg(list,int);
+ if (force_sign && val>0) out.add_char('+');
+ _ultoa_s(val,temp,16);
+ if (*fmt=='X')
+ {
+ char * t = temp;
+ while(*t)
+ {
+ if (*t>='a' && *t<='z')
+ *t += 'A' - 'a';
+ t++;
+ }
+ }
+ t_size len = strlen(temp);
+ if (pad>len) out.add_chars(padchar,pad-len);
+ out.add_string(temp);
+ fmt++;
+ }
+ else if (*fmt=='c' || *fmt=='C')
+ {
+ out.add_char(va_arg(list,char));
+ fmt++;
+ }
+ }
+ }
+ else
+ {
+ out.add_char(*(fmt++));
+ }
+ }
+}
+
+string_printf::string_printf(const char * fmt,...)
+{
+ va_list list;
+ va_start(list,fmt);
+ run(fmt,list);
+ va_end(list);
+}
+
+
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/profiler.cpp b/Plugins/listeningto/players/foo_mlt/pfc/profiler.cpp
new file mode 100644
index 0000000..3ec7ae5
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/profiler.cpp
@@ -0,0 +1,34 @@
+#include "pfc.h"
+
+#ifdef _WINDOWS
+namespace pfc {
+
+profiler_static::profiler_static(const char * p_name)
+{
+ name = p_name;
+ total_time = 0;
+ num_called = 0;
+}
+
+profiler_static::~profiler_static()
+{
+ try {
+ pfc::string_fixed_t<511> message;
+ message << "profiler: " << pfc::format_pad_left<pfc::string_fixed_t<127> >(48,' ',name) << " - " <<
+ pfc::format_pad_right<pfc::string_fixed_t<128> >(16,' ',pfc::format_uint(total_time) ) << " cycles";
+
+ if (num_called > 0) {
+ message << " (executed " << num_called << " times, " << (total_time / num_called) << " average)";
+ }
+ message << "\n";
+ OutputDebugStringA(message);
+ } catch(...) {
+ //should never happen
+ OutputDebugString(_T("unexpected profiler failure\n"));
+ }
+}
+
+}
+#else
+//PORTME
+#endif
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/profiler.h b/Plugins/listeningto/players/foo_mlt/pfc/profiler.h
new file mode 100644
index 0000000..11715d3
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/profiler.h
@@ -0,0 +1,100 @@
+#ifndef _PFC_PROFILER_H_
+#define _PFC_PROFILER_H_
+
+#ifdef _WINDOWS
+
+#include <intrin.h>
+namespace pfc {
+class profiler_static {
+public:
+ profiler_static(const char * p_name);
+ ~profiler_static();
+ void add_time(t_int64 delta) {total_time+=delta;num_called++;}
+private:
+ const char * name;
+ t_uint64 total_time,num_called;
+};
+
+class profiler_local {
+public:
+ profiler_local(profiler_static * p_owner) {
+ owner = p_owner;
+ start = __rdtsc();
+ }
+ ~profiler_local() {
+ t_int64 end = __rdtsc();
+ owner->add_time(end-start);
+ }
+private:
+ t_int64 start;
+ profiler_static * owner;
+};
+
+#define profiler(name) \
+ static pfc::profiler_static profiler_static_##name(#name); \
+ pfc::profiler_local profiler_local_##name(&profiler_static_##name);
+
+
+class hires_timer {
+public:
+ void start() {
+ m_start = g_query();
+ }
+ double query() const {
+ return _query( g_query() );
+ }
+ double query_reset() {
+ t_uint64 current = g_query();
+ double ret = _query(current);
+ m_start = current;
+ return ret;
+ }
+private:
+ double _query(t_uint64 p_val) const {
+ return (double)( p_val - m_start ) / (double) g_query_freq();
+ }
+ static t_uint64 g_query() {
+ LARGE_INTEGER val;
+ if (!QueryPerformanceCounter(&val)) throw pfc::exception_not_implemented();
+ return val.QuadPart;
+ }
+ static t_uint64 g_query_freq() {
+ LARGE_INTEGER val;
+ if (!QueryPerformanceFrequency(&val)) throw pfc::exception_not_implemented();
+ return val.QuadPart;
+ }
+ t_uint64 m_start;
+};
+
+class lores_timer {
+public:
+ void start() {
+ _start(GetTickCount());
+ }
+
+ double query() const {
+ return _query(GetTickCount());
+ }
+ double query_reset() {
+ t_uint32 time = GetTickCount();
+ double ret = _query(time);
+ _start(time);
+ return ret;
+ }
+private:
+ void _start(t_uint32 p_time) {m_last_seen = m_start = p_time;}
+ double _query(t_uint32 p_time) const {
+ t_uint64 time = p_time;
+ if (time < (m_last_seen & 0xFFFFFFFF)) time += 0x100000000;
+ m_last_seen = (m_last_seen & 0xFFFFFFFF00000000) + time;
+ return (double)(m_last_seen - m_start) / 1000.0;
+ }
+ t_uint64 m_start;
+ mutable t_uint64 m_last_seen;
+};
+}
+#else
+//PORTME
+#endif
+
+#endif
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/ptr_list.h b/Plugins/listeningto/players/foo_mlt/pfc/ptr_list.h
new file mode 100644
index 0000000..8762799
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/ptr_list.h
@@ -0,0 +1,45 @@
+#ifndef __PFC_PTR_LIST_H_
+#define __PFC_PTR_LIST_H_
+
+namespace pfc {
+
+ template<class T, class B = list_t<T*> >
+ class ptr_list_t : public B
+ {
+ public:
+ ptr_list_t() {}
+ ptr_list_t(const ptr_list_t<T> & p_source) {*this = p_source;}
+
+ void free_by_idx(t_size n) {free_mask(bit_array_one(n));}
+ void free_all() {this->remove_all_ex(free);}
+ void free_mask(const bit_array & p_mask) {this->remove_mask_ex(p_mask,free);}
+
+ void delete_item(T* ptr) {delete_by_idx(find_item(ptr));}
+
+ void delete_by_idx(t_size p_index) {
+ delete_mask(bit_array_one(p_index));
+ }
+
+ void delete_all() {
+ this->remove_all_ex(pfc::delete_t<T>);
+ }
+
+ void delete_mask(const bit_array & p_mask) {
+ this->remove_mask_ex(p_mask,pfc::delete_t<T>);
+ }
+
+ T * operator[](t_size n) const {return this->get_item(n);}
+ };
+
+ template<typename T,t_size N>
+ class ptr_list_hybrid_t : public ptr_list_t<T,list_hybrid_t<T*,N> > {
+ public:
+ ptr_list_hybrid_t() {}
+ ptr_list_hybrid_t(const ptr_list_hybrid_t<T,N> & p_source) {*this = p_source;}
+ };
+
+ typedef ptr_list_t<void> ptr_list;
+}
+
+
+#endif //__PFC_PTR_LIST_H_
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/rcptr.h b/Plugins/listeningto/players/foo_mlt/pfc/rcptr.h
new file mode 100644
index 0000000..f533745
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/rcptr.h
@@ -0,0 +1,274 @@
+namespace pfc {
+
+ class rc_container_base {
+ public:
+ long add_ref() {
+ return ++m_counter;
+ }
+ long release() {
+ long ret = --m_counter;
+ if (ret == 0) delete this;
+ return ret;
+ }
+ protected:
+ virtual ~rc_container_base() {}
+ private:
+ refcounter m_counter;
+ };
+
+ template<typename t_object>
+ class rc_container_t : public rc_container_base {
+ public:
+ TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(rc_container_t,m_object)
+
+ t_object m_object;
+ };
+
+ template<typename t_object>
+ class rcptr_const_t {
+ protected:
+ typedef rc_container_base t_container;
+ typedef rc_container_t<t_object> t_container_impl;
+ private:
+ typedef rcptr_const_t<t_object> t_self;
+ public:
+
+ rcptr_const_t() : m_container(NULL), m_ptr(NULL) {}
+ rcptr_const_t(const t_self & p_source) : m_container(NULL), m_ptr(NULL) {*this = p_source;}
+
+ void __set_from_cast(t_container * p_container,t_object * p_ptr) {
+ release();
+ p_container->add_ref();
+ m_container = p_container;
+ m_ptr = p_ptr;
+ }
+
+ bool is_valid() const {return m_container != NULL;}
+ bool is_empty() const {return m_container == NULL;}
+
+ t_self const & operator=(const t_self & p_source) {
+ release();
+ if (p_source.is_valid()) {
+ p_source.m_container->add_ref();
+ m_container = p_source.m_container;
+ m_ptr = p_source.m_ptr;
+ }
+ return *this;
+ }
+
+ ~rcptr_const_t() {release();}
+
+ void release() {
+ t_container * temp = m_container;
+ m_ptr = NULL;
+ m_container = NULL;
+ if (temp != NULL) temp->release();
+ }
+
+ const t_object & operator*() const {return *m_ptr;}
+ const t_object * operator->() const {return m_ptr;}
+
+ template<typename t_object_cast>
+ operator rcptr_const_t<t_object_cast>() const {
+ rcptr_const_t<t_object_cast> temp;
+ if (is_valid()) temp.__set_from_cast(m_container,m_ptr);
+ return temp;
+ }
+
+ template<typename t_object_cast>
+ rcptr_const_t<t_object_cast> static_cast_t() const {
+ rcptr_const_t<t_object_cast> temp;
+ if (is_valid()) temp.__set_from_cast(m_container,static_cast<t_object_cast*>(m_ptr));
+ return temp;
+ }
+
+ bool operator==(const t_self & p_other) const {
+ return m_container == p_other.m_container;
+ }
+
+ bool operator!=(const t_self & p_other) const {
+ return m_container != p_other.m_container;
+ }
+
+ protected:
+ t_container * m_container;
+ t_object * m_ptr;
+ };
+
+ template<typename t_object>
+ class rcptr_t : public rcptr_const_t<t_object> {
+ private:
+ typedef rcptr_t<t_object> t_self;
+ protected:
+ typedef rc_container_base t_container;
+ typedef rc_container_t<t_object> t_container_impl;
+ public:
+ t_self const & operator=(const t_self & p_source) {
+ this->release();
+ if (p_source.is_valid()) {
+ p_source.m_container->add_ref();
+ this->m_container = p_source.m_container;
+ this->m_ptr = p_source.m_ptr;
+ }
+ return *this;
+ }
+
+ template<typename t_object_cast>
+ operator rcptr_t<t_object_cast>() const {
+ rcptr_t<t_object_cast> temp;
+ if (is_valid()) temp.__set_from_cast(this->m_container,this->m_ptr);
+ return temp;
+ }
+
+ template<typename t_object_cast>
+ rcptr_t<t_object_cast> static_cast_t() const {
+ rcptr_t<t_object_cast> temp;
+ if (is_valid()) temp.__set_from_cast(this->m_container,static_cast<t_object_cast*>(this->m_ptr));
+ return temp;
+ }
+
+ void new_t() {
+ on_new(new t_container_impl());
+ }
+
+ template<typename t_param1>
+ void new_t(t_param1 const & p_param1) {
+ on_new(new t_container_impl(p_param1));
+ }
+
+ template<typename t_param1,typename t_param2>
+ void new_t(t_param1 const & p_param1, t_param2 const & p_param2) {
+ on_new(new t_container_impl(p_param1,p_param2));
+ }
+
+ template<typename t_param1,typename t_param2,typename t_param3>
+ void new_t(t_param1 const & p_param1, t_param2 const & p_param2,t_param3 const & p_param3) {
+ on_new(new t_container_impl(p_param1,p_param2,p_param3));
+ }
+
+ template<typename t_param1,typename t_param2,typename t_param3,typename t_param4>
+ void new_t(t_param1 const & p_param1, t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4) {
+ on_new(new t_container_impl(p_param1,p_param2,p_param3,p_param4));
+ }
+
+ template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5>
+ void new_t(t_param1 const & p_param1, t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4,t_param5 const & p_param5) {
+ on_new(new t_container_impl(p_param1,p_param2,p_param3,p_param4,p_param5));
+ }
+
+ template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5,typename t_param6>
+ void new_t(t_param1 const & p_param1, t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4,t_param5 const & p_param5,t_param6 const & p_param6) {
+ on_new(new t_container_impl(p_param1,p_param2,p_param3,p_param4,p_param5,p_param6));
+ }
+
+ static t_self g_new_t() {
+ t_self temp;
+ temp.new_t();
+ return temp;
+ }
+
+ template<typename t_param1>
+ static t_self g_new_t(t_param1 const & p_param1) {
+ t_self temp;
+ temp.new_t(p_param1);
+ return temp;
+ }
+
+ template<typename t_param1,typename t_param2>
+ static t_self g_new_t(t_param1 const & p_param1,t_param2 const & p_param2) {
+ t_self temp;
+ temp.new_t(p_param1,p_param2);
+ return temp;
+ }
+
+ template<typename t_param1,typename t_param2,typename t_param3>
+ static t_self g_new_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3) {
+ t_self temp;
+ temp.new_t(p_param1,p_param2,p_param3);
+ return temp;
+ }
+
+ template<typename t_param1,typename t_param2,typename t_param3,typename t_param4>
+ static t_self g_new_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4) {
+ t_self temp;
+ temp.new_t(p_param1,p_param2,p_param3,p_param4);
+ return temp;
+ }
+
+ template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5>
+ static t_self g_new_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4,t_param5 const & p_param5) {
+ t_self temp;
+ temp.new_t(p_param1,p_param2,p_param3,p_param4,p_param5);
+ return temp;
+ }
+
+ t_object & operator*() const {return *this->m_ptr;}
+
+ t_object * operator->() const {return this->m_ptr;}
+
+ private:
+ void on_new(t_container_impl * p_container) {
+ this->release();
+ p_container->add_ref();
+ this->m_ptr = &p_container->m_object;
+ this->m_container = p_container;
+ }
+ };
+
+ template<typename t_object>
+ rcptr_t<t_object> rcnew_t() {
+ rcptr_t<t_object> temp;
+ temp.new_t();
+ return temp;
+ }
+
+ template<typename t_object,typename t_param1>
+ rcptr_t<t_object> rcnew_t(t_param1 const & p_param1) {
+ rcptr_t<t_object> temp;
+ temp.new_t(p_param1);
+ return temp;
+ }
+
+ template<typename t_object,typename t_param1,typename t_param2>
+ rcptr_t<t_object> rcnew_t(t_param1 const & p_param1,t_param2 const & p_param2) {
+ rcptr_t<t_object> temp;
+ temp.new_t(p_param1,p_param2);
+ return temp;
+ }
+
+ template<typename t_object,typename t_param1,typename t_param2,typename t_param3>
+ rcptr_t<t_object> rcnew_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3) {
+ rcptr_t<t_object> temp;
+ temp.new_t(p_param1,p_param2,p_param3);
+ return temp;
+ }
+
+ template<typename t_object,typename t_param1,typename t_param2,typename t_param3,typename t_param4>
+ rcptr_t<t_object> rcnew_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4) {
+ rcptr_t<t_object> temp;
+ temp.new_t(p_param1,p_param2,p_param3,p_param4);
+ return temp;
+ }
+
+ template<typename t_object,typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5>
+ rcptr_t<t_object> rcnew_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4,t_param5 const & p_param5) {
+ rcptr_t<t_object> temp;
+ temp.new_t(p_param1,p_param2,p_param3,p_param4,p_param5);
+ return temp;
+ }
+
+ template<typename t_object,typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5,typename t_param6>
+ rcptr_t<t_object> rcnew_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4,t_param5 const & p_param5,t_param6 const & p_param6) {
+ rcptr_t<t_object> temp;
+ temp.new_t(p_param1,p_param2,p_param3,p_param4,p_param5,p_param6);
+ return temp;
+ }
+
+ class traits_rcptr : public traits_default {
+ public:
+ enum { realloc_safe = true, constructor_may_fail = false };
+ };
+
+ template<typename T> class traits_t<rcptr_const_t<T> > : public traits_rcptr {};
+ template<typename T> class traits_t<rcptr_t<T> > : public traits_rcptr {};
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/ref_counter.h b/Plugins/listeningto/players/foo_mlt/pfc/ref_counter.h
new file mode 100644
index 0000000..0cb65d6
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/ref_counter.h
@@ -0,0 +1,95 @@
+namespace pfc {
+
+ class NOVTABLE refcounted_object_root
+ {
+ public:
+ void refcount_add_ref() {++m_counter;}
+ void refcount_release() {if (--m_counter == 0) delete this;}
+ protected:
+ refcounted_object_root() {}
+ virtual ~refcounted_object_root() {}
+ private:
+ refcounter m_counter;
+ };
+
+ template<typename T>
+ class refcounted_object_ptr_t {
+ private:
+ typedef refcounted_object_ptr_t<T> t_self;
+ public:
+ inline refcounted_object_ptr_t() : m_ptr(NULL) {}
+ inline refcounted_object_ptr_t(T* p_ptr) : m_ptr(NULL) {copy(p_ptr);}
+ inline refcounted_object_ptr_t(const t_self & p_source) : m_ptr(NULL) {copy(p_source);}
+
+ template<typename t_source>
+ inline refcounted_object_ptr_t(t_source * p_ptr) : m_ptr(NULL) {copy(p_ptr);}
+
+ template<typename t_source>
+ inline refcounted_object_ptr_t(const refcounted_object_ptr_t<t_source> & p_source) : m_ptr(NULL) {copy(p_source);}
+
+ inline ~refcounted_object_ptr_t() {if (m_ptr != NULL) m_ptr->refcount_release();}
+
+ template<typename t_source>
+ inline void copy(t_source * p_ptr) {
+ T* torel = pfc::replace_t(m_ptr,pfc::safe_ptr_cast<T>(p_ptr));
+ if (m_ptr != NULL) m_ptr->refcount_add_ref();
+ if (torel != NULL) torel->refcount_release();
+
+ }
+
+ template<typename t_source>
+ inline void copy(const refcounted_object_ptr_t<t_source> & p_source) {copy(p_source.get_ptr());}
+
+
+ inline const t_self & operator=(const t_self & p_source) {copy(p_source); return *this;}
+ inline const t_self & operator=(T * p_ptr) {copy(p_ptr); return *this;}
+
+ template<typename t_source> inline t_self & operator=(const refcounted_object_ptr_t<t_source> & p_source) {copy(p_source); return *this;}
+ template<typename t_source> inline t_self & operator=(t_source * p_ptr) {copy(p_ptr); return *this;}
+
+ inline void release() {
+ T * temp = pfc::replace_t(m_ptr,(T*)NULL);
+ if (temp != NULL) temp->refcount_release();
+ }
+
+
+ inline T* operator->() const {PFC_ASSERT(m_ptr != NULL);return m_ptr;}
+
+ inline T* get_ptr() const {return m_ptr;}
+
+ inline bool is_valid() const {return m_ptr != NULL;}
+ inline bool is_empty() const {return m_ptr == NULL;}
+
+ inline bool operator==(const t_self & p_item) const {return m_ptr == p_item.get_ptr();}
+ inline bool operator!=(const t_self & p_item) const {return m_ptr != p_item.get_ptr();}
+ inline bool operator>(const t_self & p_item) const {return m_ptr > p_item.get_ptr();}
+ inline bool operator<(const t_self & p_item) const {return m_ptr < p_item.get_ptr();}
+
+
+ inline T* __unsafe_duplicate() const//should not be used ! temporary !
+ {
+ if (m_ptr) m_ptr->refcount_add_ref();
+ return m_ptr;
+ }
+
+ inline T* __unsafe_detach() {
+ T* ret = m_ptr;
+ m_ptr = 0;
+ return ret;
+ }
+
+ inline void __unsafe_set(T * p_ptr) {//should not be used ! temporary !
+ release();
+ m_ptr = p_ptr;
+ }
+ private:
+ T* m_ptr;
+ };
+
+ template<typename T>
+ class traits_t<refcounted_object_ptr_t<T> > : public traits_default {
+ public:
+ enum { realloc_safe = true, constructor_may_fail = false};
+ };
+
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/selftest.cpp b/Plugins/listeningto/players/foo_mlt/pfc/selftest.cpp
new file mode 100644
index 0000000..39b2c05
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/selftest.cpp
@@ -0,0 +1,25 @@
+#include "pfc.h"
+
+static void selftest() //never called, testing done at compile time
+{
+ pfc::static_assert_t<sizeof(t_uint8) == 1>();
+ pfc::static_assert_t<sizeof(t_uint16) == 2>();
+ pfc::static_assert_t<sizeof(t_uint32) == 4>();
+ pfc::static_assert_t<sizeof(t_uint64) == 8>();
+
+ pfc::static_assert_t<sizeof(t_int8) == 1>();
+ pfc::static_assert_t<sizeof(t_int16) == 2>();
+ pfc::static_assert_t<sizeof(t_int32) == 4>();
+ pfc::static_assert_t<sizeof(t_int64) == 8>();
+
+ pfc::static_assert_t<sizeof(t_float32) == 4>();
+ pfc::static_assert_t<sizeof(t_float64) == 8>();
+
+ pfc::static_assert_t<sizeof(t_size) == sizeof(void*)>();
+ pfc::static_assert_t<sizeof(t_ssize) == sizeof(void*)>();
+
+ pfc::static_assert_t<sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4>();
+
+ pfc::static_assert_t<sizeof(GUID) == 16>();
+
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/sort.cpp b/Plugins/listeningto/players/foo_mlt/pfc/sort.cpp
new file mode 100644
index 0000000..632c99f
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/sort.cpp
@@ -0,0 +1,230 @@
+#include "pfc.h"
+
+namespace pfc {
+
+PFC_DLL_EXPORT void swap_void(void * item1,void * item2,t_size width)
+{
+ unsigned char * ptr1 = (unsigned char*)item1, * ptr2 = (unsigned char*)item2;
+ t_size n;
+ unsigned char temp;
+ for(n=0;n<width;n++)
+ {
+ temp = *ptr2;
+ *ptr2 = *ptr1;
+ *ptr1 = temp;
+ ptr1++;
+ ptr2++;
+ }
+}
+
+PFC_DLL_EXPORT void reorder(reorder_callback & p_callback,const t_size * p_order,t_size p_count)
+{
+ t_size done_size = bit_array_bittable::g_estimate_size(p_count);
+ pfc::array_hybrid_t<unsigned char,1024> done;
+ done.set_size(done_size);
+ pfc::memset_t(done,(unsigned char)0);
+ t_size n;
+ for(n=0;n<p_count;n++)
+ {
+ t_size next = p_order[n];
+ if (next!=n && !bit_array_bittable::g_get(done,n))
+ {
+ t_size prev = n;
+ do
+ {
+ assert(!bit_array_bittable::g_get(done,next));
+ assert(next>n);
+ assert(n<p_count);
+ p_callback.swap(prev,next);
+ bit_array_bittable::g_set(done,next,true);
+ prev = next;
+ next = p_order[next];
+ } while(next!=n);
+ //bit_array_bittable::g_set(done,n,true);
+ }
+ }
+}
+
+PFC_DLL_EXPORT void reorder_void(void * data,t_size width,const t_size * order,t_size num,void (*swapfunc)(void * item1,void * item2,t_size width))
+{
+ unsigned char * base = (unsigned char *) data;
+ t_size done_size = bit_array_bittable::g_estimate_size(num);
+ pfc::array_hybrid_t<unsigned char,1024> done;
+ done.set_size(done_size);
+ pfc::memset_t(done,(unsigned char)0);
+ t_size n;
+ for(n=0;n<num;n++)
+ {
+ t_size next = order[n];
+ if (next!=n && !bit_array_bittable::g_get(done,n))
+ {
+ t_size prev = n;
+ do
+ {
+ assert(!bit_array_bittable::g_get(done,next));
+ assert(next>n);
+ assert(n<num);
+ swapfunc(base+width*prev,base+width*next,width);
+ bit_array_bittable::g_set(done,next,true);
+ prev = next;
+ next = order[next];
+ } while(next!=n);
+ //bit_array_bittable::g_set(done,n,true);
+ }
+ }
+}
+
+namespace {
+
+class sort_callback_impl_legacy : public sort_callback
+{
+public:
+ sort_callback_impl_legacy(
+ void * p_base,t_size p_width,
+ int (*p_comp)(const void *, const void *),
+ void (*p_swap)(void *, void *, t_size)
+ ) :
+ m_base((char*)p_base), m_width(p_width),
+ m_comp(p_comp), m_swap(p_swap)
+ {
+ }
+
+
+ int compare(t_size p_index1, t_size p_index2) const
+ {
+ return m_comp(m_base + p_index1 * m_width, m_base + p_index2 * m_width);
+ }
+
+ void swap(t_size p_index1, t_size p_index2)
+ {
+ m_swap(m_base + p_index1 * m_width, m_base + p_index2 * m_width, m_width);
+ }
+
+private:
+ char * m_base;
+ t_size m_width;
+ int (*m_comp)(const void *, const void *);
+ void (*m_swap)(void *, void *, t_size);
+};
+}
+
+PFC_DLL_EXPORT void sort_void_ex (
+ void *base,
+ t_size num,
+ t_size width,
+ int (*comp)(const void *, const void *),
+ void (*swap)(void *, void *, t_size) )
+{
+ sort(sort_callback_impl_legacy(base,width,comp,swap),num);
+}
+
+static void squaresort(pfc::sort_callback & p_callback,t_size const p_base,t_size const p_count) {
+ const t_size max = p_base + p_count;
+ for(t_size walk = p_base + 1; walk < max; ++walk) {
+ for(t_size prev = p_base; prev < walk; ++prev) {
+ p_callback.swap_check(prev,walk);
+ }
+ }
+}
+
+
+inline static void __sort_2elem_helper(pfc::sort_callback & p_callback,t_size & p_elem1,t_size & p_elem2) {
+ if (p_callback.compare(p_elem1,p_elem2) > 0) pfc::swap_t(p_elem1,p_elem2);
+}
+
+inline static t_size __pivot_helper(pfc::sort_callback & p_callback,t_size const p_base,t_size const p_count) {
+ PFC_ASSERT(p_count > 1);
+ //take middle element from lowest/middle/highest ones in original order. todo: try to come up with smarter approach?
+ t_size val1 = p_base, val2 = p_base + (p_count / 2), val3 = p_base + (p_count - 1);
+
+ __sort_2elem_helper(p_callback,val1,val2);
+ __sort_2elem_helper(p_callback,val1,val3);
+ __sort_2elem_helper(p_callback,val2,val3);
+
+ return val2;
+}
+
+static void newsort(pfc::sort_callback & p_callback,t_size const p_base,t_size const p_count) {
+ if (p_count <= 4) {
+ squaresort(p_callback,p_base,p_count);
+ return;
+ }
+
+ t_size pivot = __pivot_helper(p_callback,p_base,p_count);
+
+ {
+ const t_size target = p_base + p_count - 1;
+ if (pivot != target) {
+ p_callback.swap(pivot,target); pivot = target;
+ }
+ }
+
+
+ t_size partition = p_base;
+ {
+ bool asdf = false;
+ for(t_size walk = p_base; walk < pivot; ++walk) {
+ const int comp = p_callback.compare(walk,pivot);
+ bool trigger = false;
+ if (comp == 0) {
+ trigger = asdf;
+ asdf = !asdf;
+ } else if (comp < 0) {
+ trigger = true;
+ }
+ if (trigger) {
+ if (partition != walk) p_callback.swap(partition,walk);
+ partition++;
+ }
+ }
+ }
+ if (pivot != partition) {
+ p_callback.swap(pivot,partition); pivot = partition;
+ }
+
+ newsort(p_callback,p_base,pivot-p_base);
+ newsort(p_callback,pivot+1,p_count-(pivot+1-p_base));
+}
+
+void sort(pfc::sort_callback & p_callback,t_size p_num) {
+ newsort(p_callback,0,p_num);
+}
+
+
+PFC_DLL_EXPORT void sort_void(void * base,t_size num,t_size width,int (*comp)(const void *, const void *) )
+{
+ sort_void_ex(base,num,width,comp,swap_void);
+}
+
+
+
+
+sort_callback_stabilizer::sort_callback_stabilizer(sort_callback & p_chain,t_size p_count)
+: m_chain(p_chain)
+{
+ m_order.set_size(p_count);
+ t_size n;
+ for(n=0;n<p_count;n++) m_order[n] = n;
+}
+
+int sort_callback_stabilizer::compare(t_size p_index1, t_size p_index2) const
+{
+ int ret = m_chain.compare(p_index1,p_index2);
+ if (ret == 0) ret = pfc::sgn_t((t_ssize)m_order[p_index1] - (t_ssize)m_order[p_index2]);
+ return ret;
+}
+
+void sort_callback_stabilizer::swap(t_size p_index1, t_size p_index2)
+{
+ m_chain.swap(p_index1,p_index2);
+ pfc::swap_t(m_order[p_index1],m_order[p_index2]);
+}
+
+
+PFC_DLL_EXPORT void sort_stable(sort_callback & p_callback,t_size p_count)
+{
+ sort(sort_callback_stabilizer(p_callback,p_count),p_count);
+}
+
+}
+
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/sort.h b/Plugins/listeningto/players/foo_mlt/pfc/sort.h
new file mode 100644
index 0000000..53e06b4
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/sort.h
@@ -0,0 +1,181 @@
+namespace pfc {
+
+ PFC_DLL_EXPORT void swap_void(void * item1,void * item2,t_size width);
+
+ PFC_DLL_EXPORT void reorder_void(void * data,t_size width,const t_size * order,t_size num,void (*swapfunc)(void * item1,void * item2,t_size width) = swap_void);
+
+ class NOVTABLE reorder_callback
+ {
+ public:
+ virtual void swap(t_size p_index1,t_size p_index2) = 0;
+ };
+
+ PFC_DLL_EXPORT void reorder(reorder_callback & p_callback,const t_size * p_order,t_size p_count);
+
+ template<typename t_container>
+ class reorder_callback_impl_t : public reorder_callback
+ {
+ public:
+ reorder_callback_impl_t(t_container & p_data) : m_data(p_data) {}
+ void swap(t_size p_index1,t_size p_index2)
+ {
+ pfc::swap_t(m_data[p_index1],m_data[p_index2]);
+ }
+ private:
+ t_container & m_data;
+ };
+
+ class reorder_callback_impl_delta : public reorder_callback
+ {
+ public:
+ reorder_callback_impl_delta(reorder_callback & p_data,t_size p_delta) : m_data(p_data), m_delta(p_delta) {}
+ void swap(t_size p_index1,t_size p_index2)
+ {
+ m_data.swap(p_index1+m_delta,p_index2+m_delta);
+ }
+ private:
+ reorder_callback & m_data;
+ t_size m_delta;
+ };
+
+ template<typename t_container>
+ void reorder_t(t_container & p_data,const t_size * p_order,t_size p_count)
+ {
+ reorder(reorder_callback_impl_t<t_container>(p_data),p_order,p_count);
+ }
+
+ template<typename t_container>
+ void reorder_partial_t(t_container & p_data,t_size p_base,const t_size * p_order,t_size p_count)
+ {
+ reorder(reorder_callback_impl_delta(reorder_callback_impl_t<t_container>(p_data),p_base),p_order,p_count);
+ }
+
+ template<typename T>
+ class reorder_callback_impl_ptr_t : public reorder_callback
+ {
+ public:
+ reorder_callback_impl_ptr_t(T * p_data) : m_data(p_data) {}
+ void swap(t_size p_index1,t_size p_index2)
+ {
+ pfc::swap_t(m_data[p_index1],m_data[p_index2]);
+ }
+ private:
+ T* m_data;
+ };
+
+
+ template<typename T>
+ void reorder_ptr_t(T* p_data,const t_size * p_order,t_size p_count)
+ {
+ reorder(reorder_callback_impl_ptr_t<T>(p_data),p_order,p_count);
+ }
+
+
+
+ class NOVTABLE sort_callback
+ {
+ public:
+ virtual int compare(t_size p_index1, t_size p_index2) const = 0;
+ virtual void swap(t_size p_index1, t_size p_index2) = 0;
+ void swap_check(t_size p_index1, t_size p_index2) {if (compare(p_index1,p_index2) > 0) swap(p_index1,p_index2);}
+ };
+
+ class sort_callback_stabilizer : public sort_callback
+ {
+ public:
+ sort_callback_stabilizer(sort_callback & p_chain,t_size p_count);
+ virtual int compare(t_size p_index1, t_size p_index2) const;
+ virtual void swap(t_size p_index1, t_size p_index2);
+ private:
+ sort_callback & m_chain;
+ array_t<t_size> m_order;
+ };
+
+ PFC_DLL_EXPORT void sort(sort_callback & p_callback,t_size p_count);
+ PFC_DLL_EXPORT void sort_stable(sort_callback & p_callback,t_size p_count);
+
+ PFC_DLL_EXPORT void sort_void_ex(void *base,t_size num,t_size width, int (*comp)(const void *, const void *),void (*swap)(void *, void *, t_size) );
+ PFC_DLL_EXPORT void sort_void(void * base,t_size num,t_size width,int (*comp)(const void *, const void *) );
+
+ template<typename t_container,typename t_compare>
+ class sort_callback_impl_simple_wrap_t : public sort_callback
+ {
+ public:
+ sort_callback_impl_simple_wrap_t(t_container & p_data, t_compare p_compare) : m_data(p_data), m_compare(p_compare) {}
+ int compare(t_size p_index1, t_size p_index2) const
+ {
+ return m_compare(m_data[p_index1],m_data[p_index2]);
+ }
+
+ void swap(t_size p_index1, t_size p_index2)
+ {
+ swap_t(m_data[p_index1],m_data[p_index2]);
+ }
+ private:
+ t_container & m_data;
+ t_compare m_compare;
+ };
+
+ template<typename t_container>
+ class sort_callback_impl_auto_wrap_t : public sort_callback
+ {
+ public:
+ sort_callback_impl_auto_wrap_t(t_container & p_data) : m_data(p_data) {}
+ int compare(t_size p_index1, t_size p_index2) const
+ {
+ return compare_t(m_data[p_index1],m_data[p_index2]);
+ }
+
+ void swap(t_size p_index1, t_size p_index2)
+ {
+ swap_t(m_data[p_index1],m_data[p_index2]);
+ }
+ private:
+ t_container & m_data;
+ };
+
+ template<typename t_container,typename t_compare,typename t_permutation>
+ class sort_callback_impl_permutation_wrap_t : public sort_callback
+ {
+ public:
+ sort_callback_impl_permutation_wrap_t(const t_container & p_data, t_compare p_compare,t_permutation const & p_permutation) : m_data(p_data), m_compare(p_compare), m_permutation(p_permutation) {}
+ int compare(t_size p_index1, t_size p_index2) const
+ {
+ return m_compare(m_data[m_permutation[p_index1]],m_data[m_permutation[p_index2]]);
+ }
+
+ void swap(t_size p_index1, t_size p_index2)
+ {
+ swap_t(m_permutation[p_index1],m_permutation[p_index2]);
+ }
+ private:
+ const t_container & m_data;
+ t_compare m_compare;
+ t_permutation const & m_permutation;
+ };
+
+ template<typename t_container,typename t_compare>
+ static void sort_t(t_container & p_data,t_compare p_compare,t_size p_count)
+ {
+ sort(sort_callback_impl_simple_wrap_t<t_container,t_compare>(p_data,p_compare),p_count);
+ }
+
+ template<typename t_container,typename t_compare>
+ static void sort_stable_t(t_container & p_data,t_compare p_compare,t_size p_count)
+ {
+ sort_stable(sort_callback_impl_simple_wrap_t<t_container,t_compare>(p_data,p_compare),p_count);
+ }
+
+ template<typename t_container,typename t_compare,typename t_permutation>
+ static void sort_get_permutation_t(const t_container & p_data,t_compare p_compare,t_size p_count,t_permutation const & p_permutation)
+ {
+ sort(sort_callback_impl_permutation_wrap_t<t_container,t_compare,t_permutation>(p_data,p_compare,p_permutation),p_count);
+ }
+
+ template<typename t_container,typename t_compare,typename t_permutation>
+ static void sort_stable_get_permutation_t(const t_container & p_data,t_compare p_compare,t_size p_count,t_permutation const & p_permutation)
+ {
+ sort_stable(sort_callback_impl_permutation_wrap_t<t_container,t_compare,t_permutation>(p_data,p_compare,p_permutation),p_count);
+ }
+
+}
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/stdafx.cpp b/Plugins/listeningto/players/foo_mlt/pfc/stdafx.cpp
new file mode 100644
index 0000000..72044fc
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/stdafx.cpp
@@ -0,0 +1,2 @@
+//cpp used to generate precompiled header
+#include "pfc.h" \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/string.cpp b/Plugins/listeningto/players/foo_mlt/pfc/string.cpp
new file mode 100644
index 0000000..947b9f8
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/string.cpp
@@ -0,0 +1,711 @@
+#include "pfc.h"
+
+namespace pfc {
+
+void string_receiver::add_char(t_uint32 p_char)
+{
+ char temp[8];
+ t_size len = utf8_encode_char(p_char,temp);
+ if (len>0) add_string(temp,len);
+}
+
+void string_base::skip_trailing_char(unsigned skip)
+{
+ const char * str = get_ptr();
+ t_size ptr,trunc;
+ bool need_trunc = false;
+ for(ptr=0;str[ptr];)
+ {
+ unsigned c;
+ t_size delta = utf8_decode_char(str+ptr,&c);
+ if (delta==0) break;
+ if (c==skip)
+ {
+ need_trunc = true;
+ trunc = ptr;
+ }
+ else
+ {
+ need_trunc = false;
+ }
+ ptr += delta;
+ }
+ if (need_trunc) truncate(trunc);
+}
+
+format_time::format_time(t_uint64 p_seconds) {
+ t_uint64 length = p_seconds;
+ unsigned weeks,days,hours,minutes,seconds;
+
+ weeks = (unsigned)( ( length / (60*60*24*7) ) );
+ days = (unsigned)( ( length / (60*60*24) ) % 7 );
+ hours = (unsigned) ( ( length / (60 * 60) ) % 24);
+ minutes = (unsigned) ( ( length / (60 ) ) % 60 );
+ seconds = (unsigned) ( ( length ) % 60 );
+
+ if (weeks) {
+ m_buffer << weeks << "wk ";
+ }
+ if (days || weeks) {
+ m_buffer << days << "d ";
+ }
+ if (hours || days || weeks) {
+ m_buffer << hours << ":" << format_uint(minutes,2) << ":" << format_uint(seconds,2);
+ } else {
+ m_buffer << minutes << ":" << format_uint(seconds,2);
+ }
+}
+
+int strcmp_partial(const char * p_string,const char * p_substring) {return strcmp_partial_ex(p_string,infinite,p_substring,infinite);}
+
+static int __strcmp_partial_ex(const char * p_string,t_size p_string_length,const char * p_substring,t_size p_substring_length) throw() {
+ for(t_size walk=0;walk<p_substring_length;walk++) {
+ char stringchar = (walk>=p_string_length ? 0 : p_string[walk]);
+ char substringchar = p_substring[walk];
+ int result = compare_t(stringchar,substringchar);
+ if (result != 0) return result;
+ }
+ return 0;
+}
+
+int strcmp_partial_ex(const char * p_string,t_size p_string_length,const char * p_substring,t_size p_substring_length) /*throw()*/ {
+ p_string_length = strlen_max(p_string,p_string_length); p_substring_length = strlen_max(p_substring,p_substring_length);
+ return __strcmp_partial_ex(p_string,p_string_length,p_substring,p_substring_length);
+}
+
+bool is_path_separator(unsigned c)
+{
+ return c=='\\' || c=='/' || c=='|' || c==':';
+}
+
+bool is_path_bad_char(unsigned c)
+{
+#ifdef _WINDOWS
+ return c=='\\' || c=='/' || c=='|' || c==':' || c=='*' || c=='?' || c=='\"' || c=='>' || c=='<';
+#else
+#error portme
+#endif
+}
+
+
+
+char * strdup_n(const char * src,t_size len)
+{
+ len = strlen_max(src,len);
+ char * ret = (char*)malloc(len+1);
+ if (ret)
+ {
+ memcpy(ret,src,len);
+ ret[len]=0;
+ }
+ return ret;
+}
+
+string_filename::string_filename(const char * fn)
+{
+ fn += pfc::scan_filename(fn);
+ const char * ptr=fn,*dot=0;
+ while(*ptr && *ptr!='?')
+ {
+ if (*ptr=='.') dot=ptr;
+ ptr++;
+ }
+
+ if (dot && dot>fn) set_string(fn,dot-fn);
+ else set_string(fn);
+}
+
+string_filename_ext::string_filename_ext(const char * fn)
+{
+ fn += pfc::scan_filename(fn);
+ const char * ptr = fn;
+ while(*ptr && *ptr!='?') ptr++;
+ set_string(fn,ptr-fn);
+}
+
+string_extension::string_extension(const char * src)
+{
+ buffer[0]=0;
+ const char * start = src + pfc::scan_filename(src);
+ const char * end = start + strlen(start);
+ const char * ptr = end-1;
+ while(ptr>start && *ptr!='.')
+ {
+ if (*ptr=='?') end=ptr;
+ ptr--;
+ }
+
+ if (ptr>=start && *ptr=='.')
+ {
+ ptr++;
+ t_size len = end-ptr;
+ if (len<tabsize(buffer))
+ {
+ memcpy(buffer,ptr,len*sizeof(char));
+ buffer[len]=0;
+ }
+ }
+}
+
+
+bool has_path_bad_chars(const char * param)
+{
+ while(*param)
+ {
+ if (is_path_bad_char(*param)) return true;
+ param++;
+ }
+ return false;
+}
+
+void float_to_string(char * out,t_size out_max,double val,unsigned precision,bool b_sign) {
+ pfc::string_fixed_t<63> temp;
+ t_size outptr;
+
+ if (out_max == 0) return;
+ out_max--;//for null terminator
+
+ outptr = 0;
+
+ if (outptr == out_max) {out[outptr]=0;return;}
+
+ if (val<0) {out[outptr++] = '-'; val = -val;}
+ else if (b_sign) {out[outptr++] = '+';}
+
+ if (outptr == out_max) {out[outptr]=0;return;}
+
+
+ {
+ double powval = pow((double)10.0,(double)precision);
+ temp << (t_int64)floor(val * powval + 0.5);
+ //_i64toa(blargh,temp,10);
+ }
+
+ const t_size temp_len = temp.length();
+ if (temp_len <= precision)
+ {
+ out[outptr++] = '0';
+ if (outptr == out_max) {out[outptr]=0;return;}
+ out[outptr++] = '.';
+ if (outptr == out_max) {out[outptr]=0;return;}
+ t_size d;
+ for(d=precision-temp_len;d;d--)
+ {
+ out[outptr++] = '0';
+ if (outptr == out_max) {out[outptr]=0;return;}
+ }
+ for(d=0;d<temp_len;d++)
+ {
+ out[outptr++] = temp[d];
+ if (outptr == out_max) {out[outptr]=0;return;}
+ }
+ }
+ else
+ {
+ t_size d = temp_len;
+ const char * src = temp;
+ while(*src)
+ {
+ if (d-- == precision)
+ {
+ out[outptr++] = '.';
+ if (outptr == out_max) {out[outptr]=0;return;}
+ }
+ out[outptr++] = *(src++);
+ if (outptr == out_max) {out[outptr]=0;return;}
+ }
+ }
+ out[outptr] = 0;
+}
+
+static double pfc_string_to_float_internal(const char * src)
+{
+ bool neg = false;
+ t_int64 val = 0;
+ int div = 0;
+ bool got_dot = false;
+
+ while(*src==' ') src++;
+
+ if (*src=='-') {neg = true;src++;}
+ else if (*src=='+') src++;
+
+ while(*src)
+ {
+ if (*src>='0' && *src<='9')
+ {
+ int d = *src - '0';
+ val = val * 10 + d;
+ if (got_dot) div--;
+ src++;
+ }
+ else if (*src=='.' || *src==',')
+ {
+ if (got_dot) break;
+ got_dot = true;
+ src++;
+ }
+ else if (*src=='E' || *src=='e')
+ {
+ src++;
+ div += atoi(src);
+ break;
+ }
+ else break;
+ }
+ if (neg) val = -val;
+ return (double) val * pow(10.0,(double)div);
+}
+
+double string_to_float(const char * src,t_size max) {
+ //old function wants an oldstyle nullterminated string, and i don't currently care enough to rewrite it as it works appropriately otherwise
+ char blargh[128];
+ if (max > 127) max = 127;
+ t_size walk;
+ for(walk = 0; walk < max && src[walk]; walk++) blargh[walk] = src[walk];
+ blargh[walk] = 0;
+ return pfc_string_to_float_internal(blargh);
+}
+
+
+
+void string_base::convert_to_lower_ascii(const char * src,char replace)
+{
+ reset();
+ PFC_ASSERT(replace>0);
+ while(*src)
+ {
+ unsigned c;
+ t_size delta = utf8_decode_char(src,&c);
+ if (delta==0) {c = replace; delta = 1;}
+ else if (c>=0x80) c = replace;
+ add_byte((char)c);
+ src += delta;
+ }
+}
+
+void convert_to_lower_ascii(const char * src,t_size max,char * out,char replace)
+{
+ t_size ptr = 0;
+ PFC_ASSERT(replace>0);
+ while(ptr<max && src[ptr])
+ {
+ unsigned c;
+ t_size delta = utf8_decode_char(src+ptr,&c,max-ptr);
+ if (delta==0) {c = replace; delta = 1;}
+ else if (c>=0x80) c = replace;
+ *(out++) = (char)c;
+ ptr += delta;
+ }
+ *out = 0;
+}
+
+t_size strstr_ex(const char * p_string,t_size p_string_len,const char * p_substring,t_size p_substring_len)
+{
+ p_string_len = strlen_max(p_string,p_string_len);
+ p_substring_len = strlen_max(p_substring,p_substring_len);
+ t_size index = 0;
+ while(index + p_substring_len <= p_string_len)
+ {
+ if (memcmp(p_string+index,p_substring,p_substring_len) == 0) return index;
+ t_size delta = utf8_char_len(p_string+index,p_string_len - index);
+ if (delta == 0) break;
+ index += delta;
+ }
+ return ~0;
+}
+
+unsigned atoui_ex(const char * p_string,t_size p_string_len)
+{
+ unsigned ret = 0; t_size ptr = 0;
+ while(ptr<p_string_len)
+ {
+ char c = p_string[ptr];
+ if (! ( c >= '0' && c <= '9' ) ) break;
+ ret = ret * 10 + (unsigned)( c - '0' );
+ ptr++;
+ }
+ return ret;
+}
+
+int strcmp_ex(const char* p1,t_size n1,const char* p2,t_size n2)
+{
+ t_size idx = 0;
+ n1 = strlen_max(p1,n1); n2 = strlen_max(p2,n2);
+ for(;;)
+ {
+ if (idx == n1 && idx == n2) return 0;
+ else if (idx == n1) return -1;//end of param1
+ else if (idx == n2) return 1;//end of param2
+
+ char c1 = p1[idx], c2 = p2[idx];
+ if (c1<c2) return -1;
+ else if (c1>c2) return 1;
+
+ idx++;
+ }
+}
+
+t_uint64 atoui64_ex(const char * src,t_size len) {
+ len = strlen_max(src,len);
+ t_uint64 ret = 0, mul = 1;
+ t_size ptr = len;
+ t_size start = 0;
+// start += skip_spacing(src+start,len-start);
+
+ while(ptr>start)
+ {
+ char c = src[--ptr];
+ if (c>='0' && c<='9')
+ {
+ ret += (c-'0') * mul;
+ mul *= 10;
+ }
+ else
+ {
+ ret = 0;
+ mul = 1;
+ }
+ }
+ return ret;
+}
+
+
+t_int64 atoi64_ex(const char * src,t_size len)
+{
+ len = strlen_max(src,len);
+ t_int64 ret = 0, mul = 1;
+ t_size ptr = len;
+ t_size start = 0;
+ bool neg = false;
+// start += skip_spacing(src+start,len-start);
+ if (start < len && src[start] == '-') {neg = true; start++;}
+// start += skip_spacing(src+start,len-start);
+
+ while(ptr>start)
+ {
+ char c = src[--ptr];
+ if (c>='0' && c<='9')
+ {
+ ret += (c-'0') * mul;
+ mul *= 10;
+ }
+ else
+ {
+ ret = 0;
+ mul = 1;
+ }
+ }
+ return neg ? -ret : ret;
+}
+
+int stricmp_ascii_ex(const char * const s1,t_size const len1,const char * const s2,t_size const len2) {
+ t_size walk1 = 0, walk2 = 0;
+ for(;;) {
+ char c1 = (walk1 < len1) ? s1[walk1] : 0;
+ char c2 = (walk2 < len2) ? s2[walk2] : 0;
+ c1 = ascii_tolower(c1); c2 = ascii_tolower(c2);
+ if (c1<c2) return -1;
+ else if (c1>c2) return 1;
+ else if (c1 == 0) return 0;
+ walk1++;
+ walk2++;
+ }
+
+}
+int stricmp_ascii(const char * s1,const char * s2) {
+ for(;;) {
+ char c1 = ascii_tolower(*s1), c2 = ascii_tolower(*s2);
+ if (c1<c2) return -1;
+ else if (c1>c2) return 1;
+ else if (c1 == 0) return 0;
+ s1++;
+ s2++;
+ }
+}
+
+format_float::format_float(double p_val,unsigned p_width,unsigned p_prec)
+{
+ char temp[64];
+ float_to_string(temp,64,p_val,p_prec,false);
+ temp[63] = 0;
+ t_size len = strlen(temp);
+ if (len < p_width)
+ m_buffer.add_chars(' ',p_width-len);
+ m_buffer += temp;
+}
+
+static char format_hex_char(unsigned p_val)
+{
+ PFC_ASSERT(p_val < 16);
+ return (p_val < 10) ? p_val + '0' : p_val - 10 + 'A';
+}
+
+format_hex::format_hex(t_uint64 p_val,unsigned p_width)
+{
+ if (p_width > 16) p_width = 16;
+ else if (p_width == 0) p_width = 1;
+ char temp[16];
+ unsigned n;
+ for(n=0;n<16;n++)
+ {
+ temp[15-n] = format_hex_char((unsigned)(p_val & 0xF));
+ p_val >>= 4;
+ }
+
+ for(n=0;n<16 && temp[n] == '0';n++) {}
+
+ if (n > 16 - p_width) n = 16 - p_width;
+
+ char * out = m_buffer;
+ for(;n<16;n++)
+ *(out++) = temp[n];
+ *out = 0;
+}
+
+static char format_hex_char_lowercase(unsigned p_val)
+{
+ PFC_ASSERT(p_val < 16);
+ return (p_val < 10) ? p_val + '0' : p_val - 10 + 'a';
+}
+
+format_hex_lowercase::format_hex_lowercase(t_uint64 p_val,unsigned p_width)
+{
+ if (p_width > 16) p_width = 16;
+ else if (p_width == 0) p_width = 1;
+ char temp[16];
+ unsigned n;
+ for(n=0;n<16;n++)
+ {
+ temp[15-n] = format_hex_char_lowercase((unsigned)(p_val & 0xF));
+ p_val >>= 4;
+ }
+
+ for(n=0;n<16 && temp[n] == '0';n++) {}
+
+ if (n > 16 - p_width) n = 16 - p_width;
+
+ char * out = m_buffer;
+ for(;n<16;n++)
+ *(out++) = temp[n];
+ *out = 0;
+}
+
+format_uint::format_uint(t_uint64 val,unsigned p_width,unsigned p_base)
+{
+
+ enum {max_width = tabsize(m_buffer) - 1};
+
+ if (p_width > max_width) p_width = max_width;
+ else if (p_width == 0) p_width = 1;
+
+ char temp[max_width];
+
+ unsigned n;
+ for(n=0;n<max_width;n++)
+ {
+ temp[max_width-1-n] = format_hex_char((unsigned)(val % p_base));
+ val /= p_base;
+ }
+
+ for(n=0;n<max_width && temp[n] == '0';n++) {}
+
+ if (n > max_width - p_width) n = max_width - p_width;
+
+ char * out = m_buffer;
+
+ for(;n<max_width;n++)
+ *(out++) = temp[n];
+ *out = 0;
+}
+
+format_fixedpoint::format_fixedpoint(t_int64 p_val,unsigned p_point)
+{
+ unsigned div = 1;
+ for(unsigned n=0;n<p_point;n++) div *= 10;
+
+ if (p_val < 0) {m_buffer << "-";p_val = -p_val;}
+
+
+ m_buffer << format_int(p_val / div) << "." << format_int(p_val % div, p_point);
+}
+
+format_int::format_int(t_int64 p_val,unsigned p_width,unsigned p_base)
+{
+ bool neg = false;
+ t_uint64 val;
+ if (p_val < 0) {neg = true; val = (t_uint64)(-p_val);}
+ else val = (t_uint64)p_val;
+
+ enum {max_width = tabsize(m_buffer) - 1};
+
+ if (p_width > max_width) p_width = max_width;
+ else if (p_width == 0) p_width = 1;
+
+ if (neg && p_width > 1) p_width --;
+
+ char temp[max_width];
+
+ unsigned n;
+ for(n=0;n<max_width;n++)
+ {
+ temp[max_width-1-n] = format_hex_char((unsigned)(val % p_base));
+ val /= p_base;
+ }
+
+ for(n=0;n<max_width && temp[n] == '0';n++) {}
+
+ if (n > max_width - p_width) n = max_width - p_width;
+
+ char * out = m_buffer;
+
+ if (neg) *(out++) = '-';
+
+ for(;n<max_width;n++)
+ *(out++) = temp[n];
+ *out = 0;
+}
+
+format_hexdump_lowercase::format_hexdump_lowercase(const void * p_buffer,t_size p_bytes,const char * p_spacing)
+{
+ t_size n;
+ const t_uint8 * buffer = (const t_uint8*)p_buffer;
+ for(n=0;n<p_bytes;n++)
+ {
+ if (n > 0 && p_spacing != 0) m_formatter << p_spacing;
+ m_formatter << format_hex_lowercase(buffer[n],2);
+ }
+}
+
+format_hexdump::format_hexdump(const void * p_buffer,t_size p_bytes,const char * p_spacing)
+{
+ t_size n;
+ const t_uint8 * buffer = (const t_uint8*)p_buffer;
+ for(n=0;n<p_bytes;n++)
+ {
+ if (n > 0 && p_spacing != 0) m_formatter << p_spacing;
+ m_formatter << format_hex(buffer[n],2);
+ }
+}
+
+
+
+string_replace_extension::string_replace_extension(const char * p_path,const char * p_ext)
+{
+ m_data = p_path;
+ t_size dot = m_data.find_last('.');
+ if (dot < m_data.scan_filename())
+ {//argh
+ m_data += ".";
+ m_data += p_ext;
+ }
+ else
+ {
+ m_data.truncate(dot+1);
+ m_data += p_ext;
+ }
+}
+
+string_directory::string_directory(const char * p_path)
+{
+ t_size ptr = scan_filename(p_path);
+ if (ptr > 0) m_data.set_string(p_path,ptr-1);
+}
+
+t_size scan_filename(const char * ptr)
+{
+ t_size n;
+ t_size _used = strlen(ptr);
+ for(n=_used-1;n!=~0;n--)
+ {
+ if (is_path_separator(ptr[n])) return n+1;
+ }
+ return 0;
+}
+
+
+
+t_size string_find_first(const char * p_string,char p_tofind,t_size p_start) {
+ return string_find_first_ex(p_string,infinite,&p_tofind,1,p_start);
+}
+t_size string_find_last(const char * p_string,char p_tofind,t_size p_start) {
+ return string_find_last_ex(p_string,infinite,&p_tofind,1,p_start);
+}
+t_size string_find_first(const char * p_string,const char * p_tofind,t_size p_start) {
+ return string_find_first_ex(p_string,infinite,p_tofind,infinite,p_start);
+}
+t_size string_find_last(const char * p_string,const char * p_tofind,t_size p_start) {
+ return string_find_last_ex(p_string,infinite,p_tofind,infinite,p_start);
+}
+
+t_size string_find_first_ex(const char * p_string,t_size p_string_length,char p_tofind,t_size p_start) {
+ return string_find_first_ex(p_string,p_string_length,&p_tofind,1,p_start);
+}
+t_size string_find_last_ex(const char * p_string,t_size p_string_length,char p_tofind,t_size p_start) {
+ return string_find_last_ex(p_string,p_string_length,&p_tofind,1,p_start);
+}
+t_size string_find_first_ex(const char * p_string,t_size p_string_length,const char * p_tofind,t_size p_tofind_length,t_size p_start) {
+ p_string_length = strlen_max(p_string,p_string_length); p_tofind_length = strlen_max(p_tofind,p_tofind_length);
+ if (p_string_length >= p_tofind_length) {
+ t_size max = p_string_length - p_tofind_length;
+ for(t_size walk = p_start; walk <= max; walk++) {
+ if (__strcmp_partial_ex(p_string+walk,p_string_length-walk,p_tofind,p_tofind_length) == 0) return walk;
+ }
+ }
+ return infinite;
+}
+t_size string_find_last_ex(const char * p_string,t_size p_string_length,const char * p_tofind,t_size p_tofind_length,t_size p_start) {
+ p_string_length = strlen_max(p_string,p_string_length); p_tofind_length = strlen_max(p_tofind,p_tofind_length);
+ if (p_string_length >= p_tofind_length) {
+ t_size max = min_t<t_size>(p_string_length - p_tofind_length,p_start);
+ for(t_size walk = max; walk != (t_size)(-1); walk--) {
+ if (__strcmp_partial_ex(p_string+walk,p_string_length-walk,p_tofind,p_tofind_length) == 0) return walk;
+ }
+ }
+ return infinite;
+}
+
+
+bool string_is_numeric(const char * p_string,t_size p_length) {
+ bool retval = false;
+ for(t_size walk = 0; walk < p_length && p_string[walk] != 0; walk++) {
+ if (!char_is_numeric(p_string[walk])) {retval = false; break;}
+ retval = true;
+ }
+ return retval;
+}
+
+
+void string_base::fix_dir_separator(char p_char) {
+ t_size length = get_length();
+ if (length == 0 || get_ptr()[length-1] != p_char) add_byte(p_char);
+}
+
+bool is_multiline(const char * p_string,t_size p_len) {
+ for(t_size n = 0; n < p_len && p_string[n]; n++) {
+ switch(p_string[n]) {
+ case '\r':
+ case '\n':
+ return true;
+ }
+ }
+ return false;
+}
+
+static t_uint64 pow10_helper(unsigned p_extra) {
+ t_uint64 ret = 1;
+ for(unsigned n = 0; n < p_extra; n++ ) ret *= 10;
+ return ret;
+}
+
+format_time_ex::format_time_ex(double p_seconds,unsigned p_extra) {
+ t_uint64 pow10 = pow10_helper(p_extra);
+ t_uint64 ticks = pfc::rint64(pow10 * p_seconds);
+
+ m_buffer << pfc::format_time(ticks / pow10);
+ if (p_extra>0) {
+ m_buffer << "." << pfc::format_uint(ticks % pow10, p_extra);
+ }
+}
+
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/string.h b/Plugins/listeningto/players/foo_mlt/pfc/string.h
new file mode 100644
index 0000000..cf7ed22
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/string.h
@@ -0,0 +1,610 @@
+#ifndef _PFC_STRING_H_
+#define _PFC_STRING_H_
+
+namespace pfc {
+
+ class NOVTABLE string_receiver {
+ public:
+ virtual void add_string(const char * p_string,t_size p_string_size = infinite) = 0;
+
+ void add_char(t_uint32 c);//adds unicode char to the string
+ void add_byte(char c) {add_string(&c,1);}
+ void add_chars(t_uint32 p_char,t_size p_count) {for(;p_count;p_count--) add_char(p_char);}
+ protected:
+ string_receiver() {}
+ ~string_receiver() {}
+ };
+
+ t_size scan_filename(const char * ptr);
+
+ bool is_path_separator(unsigned c);
+ bool is_path_bad_char(unsigned c);
+ bool is_valid_utf8(const char * param,t_size max = infinite);
+ bool is_lower_ascii(const char * param);
+ bool is_multiline(const char * p_string,t_size p_len = infinite);
+ bool has_path_bad_chars(const char * param);
+ void recover_invalid_utf8(const char * src,char * out,unsigned replace);//out must be enough to hold strlen(char) + 1, or appropiately bigger if replace needs multiple chars
+ void convert_to_lower_ascii(const char * src,t_size max,char * out,char replace = '?');//out should be at least strlen(src)+1 long
+
+ inline char ascii_tolower(char c) {if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; return c;}
+ inline char ascii_toupper(char c) {if (c >= 'a' && c <= 'z') c += 'A' - 'a'; return c;}
+
+ t_size string_find_first(const char * p_string,char p_tofind,t_size p_start = 0); //returns infinite if not found
+ t_size string_find_last(const char * p_string,char p_tofind,t_size p_start = ~0); //returns infinite if not found
+ t_size string_find_first(const char * p_string,const char * p_tofind,t_size p_start = 0); //returns infinite if not found
+ t_size string_find_last(const char * p_string,const char * p_tofind,t_size p_start = ~0); //returns infinite if not found
+
+ t_size string_find_first_ex(const char * p_string,t_size p_string_length,char p_tofind,t_size p_start = 0); //returns infinite if not found
+ t_size string_find_last_ex(const char * p_string,t_size p_string_length,char p_tofind,t_size p_start = ~0); //returns infinite if not found
+ t_size string_find_first_ex(const char * p_string,t_size p_string_length,const char * p_tofind,t_size p_tofind_length,t_size p_start = 0); //returns infinite if not found
+ t_size string_find_last_ex(const char * p_string,t_size p_string_length,const char * p_tofind,t_size p_tofind_length,t_size p_start = ~0); //returns infinite if not found
+
+
+ template<typename t_char>
+ t_size strlen_max_t(const t_char * ptr,t_size max) {
+ if (ptr == NULL) return 0;
+ t_size n = 0;
+ while(n<max && ptr[n] != 0) n++;
+ return n;
+ }
+
+ inline t_size strlen_max(const char * ptr,t_size max) {return strlen_max_t(ptr,max);}
+ inline t_size wcslen_max(const wchar_t * ptr,t_size max) {return strlen_max_t(ptr,max);}
+
+#ifdef _WINDOWS
+ inline t_size tcslen_max(const TCHAR * ptr,t_size max) {return strlen_max_t(ptr,max);}
+#endif
+
+ bool string_is_numeric(const char * p_string,t_size p_length = infinite);
+ inline bool char_is_numeric(char p_char) {return p_char >= '0' && p_char <= '9';}
+ inline bool char_is_ascii_alpha_upper(char p_char) {return p_char >= 'A' && p_char <= 'Z';}
+ inline bool char_is_ascii_alpha_lower(char p_char) {return p_char >= 'a' && p_char <= 'z';}
+ inline bool char_is_ascii_alpha(char p_char) {return char_is_ascii_alpha_lower(p_char) || char_is_ascii_alpha_upper(p_char);}
+ inline bool char_is_ascii_alphanumeric(char p_char) {return char_is_ascii_alpha(p_char) || char_is_numeric(p_char);}
+
+ unsigned atoui_ex(const char * ptr,t_size max);
+ t_int64 atoi64_ex(const char * ptr,t_size max);
+ t_uint64 atoui64_ex(const char * ptr,t_size max);
+
+ t_size strlen_utf8(const char * s,t_size num = ~0);//returns number of characters in utf8 string; num - no. of bytes (optional)
+ t_size utf8_char_len(const char * s,t_size max = ~0);//returns size of utf8 character pointed by s, in bytes, 0 on error
+ t_size utf8_char_len_from_header(char c);
+ t_size utf8_chars_to_bytes(const char * string,t_size count);
+
+ t_size strcpy_utf8_truncate(const char * src,char * out,t_size maxbytes);
+
+ t_size utf8_decode_char(const char * src,unsigned * out,t_size src_bytes = ~0);//returns length in bytes
+ t_size utf8_encode_char(unsigned c,char * out);//returns used length in bytes, max 6
+ t_size utf16_decode_char(const wchar_t * p_source,unsigned * p_out,t_size p_source_length = ~0);
+ t_size utf16_encode_char(unsigned c,wchar_t * out);
+
+
+ t_size strstr_ex(const char * p_string,t_size p_string_len,const char * p_substring,t_size p_substring_len);
+
+ int strcmp_partial(const char * p_string,const char * p_substring);
+ int strcmp_partial_ex(const char * p_string,t_size p_string_length,const char * p_substring,t_size p_substring_length);
+
+ t_size skip_utf8_chars(const char * ptr,t_size count);
+ char * strdup_n(const char * src,t_size len);
+ int stricmp_ascii(const char * s1,const char * s2);
+ int stricmp_ascii_ex(const char * s1,t_size len1,const char * s2,t_size len2);
+
+ int strcmp_ex(const char* p1,t_size n1,const char* p2,t_size n2);
+
+ unsigned utf8_get_char(const char * src);
+
+ inline bool utf8_advance(const char * & var) {
+ t_size delta = utf8_char_len(var);
+ var += delta;
+ return delta>0;
+ }
+
+ inline bool utf8_advance(char * & var) {
+ t_size delta = utf8_char_len(var);
+ var += delta;
+ return delta>0;
+ }
+
+ inline const char * utf8_char_next(const char * src) {return src + utf8_char_len(src);}
+ inline char * utf8_char_next(char * src) {return src + utf8_char_len(src);}
+
+ class NOVTABLE string_base : public pfc::string_receiver {
+ public:
+ virtual const char * get_ptr() const = 0;
+ virtual void add_string(const char * p_string,t_size p_length = ~0) = 0;//same as string_receiver method
+ virtual void set_string(const char * p_string,t_size p_length = ~0) {reset();add_string(p_string,p_length);}
+ virtual void truncate(t_size len)=0;
+ virtual t_size get_length() const {return strlen(get_ptr());}
+ virtual char * lock_buffer(t_size p_requested_length) = 0;
+ virtual void unlock_buffer() = 0;
+
+ //! For compatibility with old conventions.
+ inline t_size length() const {return get_length();}
+
+ inline void reset() {truncate(0);}
+
+ inline bool is_empty() const {return *get_ptr()==0;}
+
+ void skip_trailing_char(unsigned c = ' ');
+
+ bool is_valid_utf8() {return pfc::is_valid_utf8(get_ptr());}
+
+ void convert_to_lower_ascii(const char * src,char replace = '?');
+
+ inline const string_base & operator= (const char * src) {set_string(src);return *this;}
+ inline const string_base & operator+= (const char * src) {add_string(src);return *this;}
+ inline const string_base & operator= (const string_base & src) {set_string(src);return *this;}
+ inline const string_base & operator+= (const string_base & src) {add_string(src);return *this;}
+
+ inline operator const char * () const {return get_ptr();}
+
+ t_size scan_filename() const {return pfc::scan_filename(get_ptr());}
+
+ t_size find_first(char p_char,t_size p_start = 0) {return pfc::string_find_first(get_ptr(),p_char,p_start);}
+ t_size find_last(char p_char,t_size p_start = ~0) {return pfc::string_find_last(get_ptr(),p_char,p_start);}
+ t_size find_first(const char * p_string,t_size p_start = 0) {return pfc::string_find_first(get_ptr(),p_string,p_start);}
+ t_size find_last(const char * p_string,t_size p_start = ~0) {return pfc::string_find_last(get_ptr(),p_string,p_start);}
+
+ void fix_dir_separator(char p_char);
+ protected:
+ string_base() {}
+ ~string_base() {}
+ };
+
+ template<t_size max_length>
+ class string_fixed_t : public pfc::string_base {
+ public:
+ inline string_fixed_t() {init();}
+ inline string_fixed_t(const string_fixed_t<max_length> & p_source) {init(); *this = p_source;}
+ inline string_fixed_t(const char * p_source) {init(); set_string(p_source);}
+
+ inline const string_fixed_t<max_length> & operator=(const string_fixed_t<max_length> & p_source) {set_string(p_source);return *this;}
+ inline const string_fixed_t<max_length> & operator=(const char * p_source) {set_string(p_source);return *this;}
+
+ char * lock_buffer(t_size p_requested_length) {
+ if (p_requested_length >= max_length) return NULL;
+ memset(m_data,0,sizeof(m_data));
+ return m_data;
+ }
+ void unlock_buffer() {
+ m_length = strlen(m_data);
+ }
+
+ inline operator const char * () const {return m_data;}
+
+ const char * get_ptr() const {return m_data;}
+
+ void add_string(const char * ptr,t_size len) {
+ len = strlen_max(ptr,len);
+ if (m_length + len < m_length || m_length + len > max_length) throw pfc::exception_overflow();
+ for(t_size n=0;n<len;n++) {
+ m_data[m_length++] = ptr[n];
+ }
+ m_data[m_length] = 0;
+ }
+ void truncate(t_size len) {
+ if (len > max_length) len = max_length;
+ if (m_length > len) {
+ m_length = len;
+ m_data[len] = 0;
+ }
+ }
+ t_size get_length() const {return m_length;}
+ private:
+ inline void init() {
+ pfc::static_assert<(max_length>1)>();
+ m_length = 0; m_data[0] = 0;
+ }
+ t_size m_length;
+ char m_data[max_length+1];
+ };
+
+ template<template<typename> class t_alloc>
+ class string8_t : public pfc::string_base {
+ private:
+ typedef string8_t<t_alloc> t_self;
+ protected:
+ pfc::array_t<char,t_alloc> m_data;
+ t_size used;
+
+ inline void makespace(t_size s)
+ {
+ t_size old_size = m_data.get_size();
+ if (old_size < s)
+ m_data.set_size(s+16);
+ else if (old_size > s + 32)
+ m_data.set_size(s);
+ }
+
+ inline const char * __get_ptr() const throw() {return used > 0 ? m_data.get_ptr() : "";}
+
+ public:
+ inline const t_self & operator= (const char * src) {set_string(src);return *this;}
+ inline const t_self & operator+= (const char * src) {add_string(src);return *this;}
+ inline const t_self & operator= (const string_base & src) {set_string(src);return *this;}
+ inline const t_self & operator+= (const string_base & src) {add_string(src);return *this;}
+ inline const t_self & operator= (const t_self & src) {set_string(src);return *this;}
+ inline const t_self & operator+= (const t_self & src) {add_string(src);return *this;}
+
+ inline operator const char * () const throw() {return __get_ptr();}
+
+ string8_t() : used(0) {}
+ string8_t(const char * p_string) : used(0) {set_string(p_string);}
+ string8_t(const char * p_string,t_size p_length) : used(0) {set_string(p_string,p_length);}
+ string8_t(const t_self & p_string) : used(0) {set_string(p_string);}
+ string8_t(const string_base & p_string) : used(0) {set_string(p_string);}
+
+ void prealloc(t_size p_size) {m_data.prealloc(p_size+1);}
+
+ const char * get_ptr() const throw() {return __get_ptr();}
+
+ void add_string(const char * p_string,t_size p_length = ~0);
+ void set_string(const char * p_string,t_size p_length = ~0);
+
+ void truncate(t_size len)
+ {
+ if (used>len) {used=len;m_data[len]=0;makespace(used+1);}
+ }
+
+ t_size get_length() const throw() {return used;}
+
+
+ void set_char(unsigned offset,char c);
+
+ t_size replace_nontext_chars(char p_replace = '_');
+ t_size replace_char(unsigned c1,unsigned c2,t_size start = 0);
+ t_size replace_byte(char c1,char c2,t_size start = 0);
+ void fix_filename_chars(char def = '_',char leave=0);//replace "bad" characters, leave can be used to keep eg. path separators
+ void remove_chars(t_size first,t_size count); //slow
+ void insert_chars(t_size first,const char * src, t_size count);//slow
+ void insert_chars(t_size first,const char * src);
+ bool truncate_eol(t_size start = 0);
+ bool fix_eol(const char * append = " (...)",t_size start = 0);
+ bool limit_length(t_size length_in_chars,const char * append = " (...)");
+
+ //for string_buffer class
+ char * lock_buffer(t_size n)
+ {
+ makespace(n+1);
+ pfc::memset_t(m_data,(char)0);
+ return m_data.get_ptr();;
+ }
+
+ void unlock_buffer() {
+ used=strlen(m_data.get_ptr());
+ makespace(used+1);
+ }
+
+ void force_reset() {used=0;m_data.force_reset();}
+
+ inline static void g_swap(t_self & p_item1,t_self & p_item2) {
+ pfc::swap_t(p_item1.m_data,p_item2.m_data);
+ pfc::swap_t(p_item1.used,p_item2.used);
+ }
+ };
+
+ typedef string8_t<pfc::alloc_standard> string8;
+ typedef string8_t<pfc::alloc_fast> string8_fast;
+ typedef string8_t<pfc::alloc_fast_aggressive> string8_fast_aggressive;
+ //for backwards compatibility
+ typedef string8_t<pfc::alloc_fast_aggressive> string8_fastalloc;
+
+
+ template<template<typename> class t_alloc> class traits_t<string8_t<t_alloc> > : public pfc::combine_traits<pfc::traits_vtable,pfc::traits_t<pfc::array_t<char,t_alloc> > > {
+ public:
+ enum {
+ needs_constructor = true,
+ };
+ };
+}
+
+
+
+#include "string8_impl.h"
+
+#define PFC_DEPRECATE_PRINTF PFC_DEPRECATE("Use string8/string_fixed_t with operator<< overloads instead.")
+
+namespace pfc {
+
+ class string_buffer {
+ private:
+ string_base & m_owner;
+ char * m_buffer;
+ public:
+ explicit string_buffer(string_base & p_string,t_size p_requeted_length) : m_owner(p_string) {m_buffer = m_owner.lock_buffer(p_requeted_length);}
+ ~string_buffer() {m_owner.unlock_buffer();}
+ operator char* () {return m_buffer;}
+ };
+
+ class PFC_DEPRECATE_PRINTF string_printf : public string8_fastalloc {
+ public:
+ static void g_run(string_base & out,const char * fmt,va_list list);
+ void run(const char * fmt,va_list list);
+
+ explicit string_printf(const char * fmt,...);
+ };
+
+ class PFC_DEPRECATE_PRINTF string_printf_va : public string8_fastalloc {
+ public:
+ string_printf_va(const char * fmt,va_list list);
+ };
+
+ class format_time {
+ public:
+ format_time(t_uint64 p_seconds);
+ const char * get_ptr() const {return m_buffer;}
+ operator const char * () const {return m_buffer;}
+ protected:
+ string_fixed_t<127> m_buffer;
+ };
+
+
+ class format_time_ex {
+ public:
+ format_time_ex(double p_seconds,unsigned p_extra = 3);
+ const char * get_ptr() const {return m_buffer;}
+ operator const char * () const {return m_buffer;}
+ private:
+ string_fixed_t<127> m_buffer;
+ };
+
+
+
+
+ class string_filename : public string8 {
+ public:
+ explicit string_filename(const char * fn);
+ };
+
+ class string_filename_ext : public string8 {
+ public:
+ explicit string_filename_ext(const char * fn);
+ };
+
+ class string_extension
+ {
+ char buffer[32];
+ public:
+ inline const char * get_ptr() const {return buffer;}
+ inline t_size length() const {return strlen(buffer);}
+ inline operator const char * () const {return buffer;}
+ explicit string_extension(const char * src);
+ };
+
+
+ class string_replace_extension
+ {
+ public:
+ string_replace_extension(const char * p_path,const char * p_ext);
+ inline operator const char*() const {return m_data;}
+ private:
+ string8 m_data;
+ };
+
+ class string_directory
+ {
+ public:
+ string_directory(const char * p_path);
+ inline operator const char*() const {return m_data;}
+ private:
+ string8 m_data;
+ };
+
+ void float_to_string(char * out,t_size out_max,double val,unsigned precision,bool force_sign = false);//doesnt add E+X etc, has internal range limits, useful for storing float numbers as strings without having to bother with international coma/dot settings BS
+ double string_to_float(const char * src,t_size len = infinite);
+
+ template<>
+ inline void swap_t(string8 & p_item1,string8 & p_item2)
+ {
+ string8::g_swap(p_item1,p_item2);
+ }
+
+ class format_float
+ {
+ public:
+ format_float(double p_val,unsigned p_width,unsigned p_prec);
+ format_float(const format_float & p_source) {*this = p_source;}
+
+ inline const char * get_ptr() const {return m_buffer.get_ptr();}
+ inline operator const char*() const {return m_buffer.get_ptr();}
+ private:
+ string8 m_buffer;
+ };
+
+ class format_int
+ {
+ public:
+ format_int(t_int64 p_val,unsigned p_width = 0,unsigned p_base = 10);
+ format_int(const format_int & p_source) {*this = p_source;}
+ inline const char * get_ptr() const {return m_buffer;}
+ inline operator const char*() const {return m_buffer;}
+ private:
+ char m_buffer[64];
+ };
+
+
+ class format_uint
+ {
+ public:
+ format_uint(t_uint64 p_val,unsigned p_width = 0,unsigned p_base = 10);
+ format_uint(const format_uint & p_source) {*this = p_source;}
+ inline const char * get_ptr() const {return m_buffer;}
+ inline operator const char*() const {return m_buffer;}
+ private:
+ char m_buffer[64];
+ };
+
+ class format_hex
+ {
+ public:
+ format_hex(t_uint64 p_val,unsigned p_width = 0);
+ format_hex(const format_hex & p_source) {*this = p_source;}
+ inline const char * get_ptr() const {return m_buffer;}
+ inline operator const char*() const {return m_buffer;}
+ private:
+ char m_buffer[17];
+ };
+
+ class format_hex_lowercase
+ {
+ public:
+ format_hex_lowercase(t_uint64 p_val,unsigned p_width = 0);
+ format_hex_lowercase(const format_hex_lowercase & p_source) {*this = p_source;}
+ inline const char * get_ptr() const {return m_buffer;}
+ inline operator const char*() const {return m_buffer;}
+ private:
+ char m_buffer[17];
+ };
+
+
+ typedef string8_fastalloc string_formatter;
+
+ class format_hexdump
+ {
+ public:
+ format_hexdump(const void * p_buffer,t_size p_bytes,const char * p_spacing = " ");
+
+ inline const char * get_ptr() const {return m_formatter;}
+ inline operator const char * () const {return m_formatter;}
+
+ private:
+ string_formatter m_formatter;
+ };
+
+ class format_hexdump_lowercase
+ {
+ public:
+ format_hexdump_lowercase(const void * p_buffer,t_size p_bytes,const char * p_spacing = " ");
+
+ inline const char * get_ptr() const {return m_formatter;}
+ inline operator const char * () const {return m_formatter;}
+
+ private:
+ string_formatter m_formatter;
+ };
+
+ class format_fixedpoint
+ {
+ public:
+ format_fixedpoint(t_int64 p_val,unsigned p_point);
+ inline const char * get_ptr() const {return m_buffer;}
+ inline operator const char*() const {return m_buffer;}
+ private:
+ string_formatter m_buffer;
+ };
+
+ class format_char {
+ public:
+ format_char(char p_char) {m_buffer[0] = p_char; m_buffer[1] = 0;}
+ inline const char * get_ptr() const {return m_buffer;}
+ inline operator const char*() const {return m_buffer;}
+ private:
+ char m_buffer[2];
+ };
+
+ template<typename t_stringbuffer = pfc::string8_fastalloc>
+ class format_pad_left {
+ public:
+ format_pad_left(t_size p_chars,t_uint32 p_padding /* = ' ' */,const char * p_string,t_size p_string_length = infinite) {
+ t_size source_len = 0, source_walk = 0;
+
+ while(source_walk < p_string_length && source_len < p_chars) {
+ unsigned dummy;
+ t_size delta = pfc::utf8_decode_char(p_string + source_walk, &dummy, p_string_length - source_walk);
+ if (delta == 0) break;
+ source_len++;
+ source_walk += delta;
+ }
+
+ m_buffer.add_string(p_string,source_walk);
+ m_buffer.add_chars(p_padding,p_chars - source_len);
+ }
+ inline const char * get_ptr() const {return m_buffer;}
+ inline operator const char*() const {return m_buffer;}
+ private:
+ t_stringbuffer m_buffer;
+ };
+
+ template<typename t_stringbuffer = pfc::string8_fastalloc>
+ class format_pad_right {
+ public:
+ format_pad_right(t_size p_chars,t_uint32 p_padding /* = ' ' */,const char * p_string,t_size p_string_length = infinite) {
+ t_size source_len = 0, source_walk = 0;
+
+ while(source_walk < p_string_length && source_len < p_chars) {
+ unsigned dummy;
+ t_size delta = pfc::utf8_decode_char(p_string + source_walk, &dummy, p_string_length - source_walk);
+ if (delta == 0) break;
+ source_len++;
+ source_walk += delta;
+ }
+
+ m_buffer.add_chars(p_padding,p_chars - source_len);
+ m_buffer.add_string(p_string,source_walk);
+ }
+ inline const char * get_ptr() const {return m_buffer;}
+ inline operator const char*() const {return m_buffer;}
+ private:
+ t_stringbuffer m_buffer;
+ };
+}
+
+inline pfc::string_base & operator<<(pfc::string_base & p_fmt,const char * p_source) {p_fmt.add_string(p_source); return p_fmt;}
+inline pfc::string_base & operator<<(pfc::string_base & p_fmt,t_int32 p_val) {return p_fmt << pfc::format_int(p_val);}
+inline pfc::string_base & operator<<(pfc::string_base & p_fmt,t_uint32 p_val) {return p_fmt << pfc::format_uint(p_val);}
+inline pfc::string_base & operator<<(pfc::string_base & p_fmt,t_int64 p_val) {return p_fmt << pfc::format_int(p_val);}
+inline pfc::string_base & operator<<(pfc::string_base & p_fmt,t_uint64 p_val) {return p_fmt << pfc::format_uint(p_val);}
+inline pfc::string_base & operator<<(pfc::string_base & p_fmt,double p_val) {return p_fmt << pfc::format_float(p_val,0,7);}
+
+inline pfc::string_base & operator<<(pfc::string_base & p_fmt,std::exception const & p_exception) {return p_fmt << p_exception.what();}
+
+
+
+
+
+
+namespace pfc {
+ template<typename t_char>
+ class string_simple_t {
+ private:
+ typedef string_simple_t<t_char> t_self;
+ public:
+ t_size length(t_size p_limit = infinite) const {return pfc::strlen_t(get_ptr(),infinite);}
+ bool is_empty() const {return length(1) == 0;}
+ void set_string(const t_char * p_source,t_size p_length = infinite) {
+ t_size length = pfc::strlen_t(p_source,p_length);
+ m_buffer.set_size(length + 1);
+ pfc::memcpy_t(m_buffer.get_ptr(),p_source,length);
+ m_buffer[length] = 0;
+ }
+ string_simple_t() {}
+ string_simple_t(const t_char * p_source,t_size p_length = infinite) {set_string(p_source,p_length);}
+ const t_self & operator=(const t_char * p_source) {set_string(p_source);return *this;}
+ operator const t_char* () const {return get_ptr();}
+ const t_char * get_ptr() const {return m_buffer.get_size() > 0 ? m_buffer.get_ptr() : pfc::empty_string_t<t_char>();}
+ private:
+ pfc::array_t<t_char> m_buffer;
+ };
+
+ typedef string_simple_t<char> string_simple;
+
+ template<typename t_char> class traits_t<string_simple_t<t_char> > : public traits_t<array_t<t_char> > {};
+}
+
+
+namespace pfc {
+ //for tree/map classes
+
+ class comparator_strcmp {
+ public:
+ inline static int compare(const char * p_item1,const char * p_item2) {return strcmp(p_item1,p_item2);}
+ };
+
+ class comparator_stricmp_ascii {
+ public:
+ inline static int compare(const char * p_item1,const char * p_item2) {return pfc::stricmp_ascii(p_item1,p_item2);}
+ };
+
+}
+
+#endif //_PFC_STRING_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/string8_impl.h b/Plugins/listeningto/players/foo_mlt/pfc/string8_impl.h
new file mode 100644
index 0000000..c020ff9
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/string8_impl.h
@@ -0,0 +1,164 @@
+namespace pfc {
+
+template<template<typename> class t_alloc>
+void string8_t<t_alloc>::add_string(const char * ptr,t_size len)
+{
+ if (len > 0 && ptr >= m_data.get_ptr() && ptr <= m_data.get_ptr() + m_data.get_size()) {
+ add_string(string8(ptr,len));
+ } else {
+ len = strlen_max(ptr,len);
+ makespace(used+len+1);
+ pfc::memcpy_t(m_data.get_ptr() + used,ptr,len);
+ used+=len;
+ m_data[used]=0;
+ true;
+ }
+}
+
+template<template<typename> class t_alloc>
+void string8_t<t_alloc>::set_string(const char * ptr,t_size len) {
+ if (len > 0 && ptr >= m_data.get_ptr() && ptr < m_data.get_ptr() + m_data.get_size()) {
+ set_string(string8(ptr,len));
+ } else {
+ len = strlen_max(ptr,len);
+ makespace(len+1);
+ pfc::memcpy_t(m_data.get_ptr(),ptr,len);
+ used=len;
+ m_data[used]=0;
+ }
+}
+
+template<template<typename> class t_alloc>
+void string8_t<t_alloc>::set_char(unsigned offset,char c)
+{
+ if (!c) truncate(offset);
+ else if (offset<used) m_data[offset]=c;
+}
+
+template<template<typename> class t_alloc>
+void string8_t<t_alloc>::fix_filename_chars(char def,char leave)//replace "bad" characters, leave can be used to keep eg. path separators
+{
+ t_size n;
+ for(n=0;n<used;n++)
+ if (m_data[n]!=leave && pfc::is_path_bad_char(m_data[n])) m_data[n]=def;
+}
+
+template<template<typename> class t_alloc>
+void string8_t<t_alloc>::remove_chars(t_size first,t_size count)
+{
+ if (first>used) first = used;
+ if (first+count>used) count = used-first;
+ if (count>0)
+ {
+ t_size n;
+ for(n=first+count;n<=used;n++)
+ m_data[n-count]=m_data[n];
+ used -= count;
+ makespace(used+1);
+ }
+}
+
+template<template<typename> class t_alloc>
+void string8_t<t_alloc>::insert_chars(t_size first,const char * src, t_size count)
+{
+ if (first > used) first = used;
+
+ makespace(used+count+1);
+ t_size n;
+ for(n=used;(int)n>=(int)first;n--)
+ m_data[n+count] = m_data[n];
+ for(n=0;n<count;n++)
+ m_data[first+n] = src[n];
+
+ used+=count;
+}
+
+template<template<typename> class t_alloc>
+void string8_t<t_alloc>::insert_chars(t_size first,const char * src) {insert_chars(first,src,strlen(src));}
+
+template<template<typename> class t_alloc>
+bool string8_t<t_alloc>::truncate_eol(t_size start)
+{
+ t_size n;
+ const char * ptr = m_data.get_ptr() + start;
+ for(n=start;n<used;n++)
+ {
+ if (*ptr==10 || *ptr==13)
+ {
+ truncate(n);
+ return true;
+ }
+ ptr++;
+ }
+ return false;
+}
+
+template<template<typename> class t_alloc>
+bool string8_t<t_alloc>::fix_eol(const char * append,t_size start)
+{
+ bool rv = truncate_eol(start);
+ if (rv) add_string(append);
+ return rv;
+}
+
+
+template<template<typename> class t_alloc>
+bool string8_t<t_alloc>::limit_length(t_size length_in_chars,const char * append)
+{
+ bool rv = false;
+ const char * base = get_ptr(), * ptr = base;
+ while(length_in_chars && utf8_advance(ptr)) length_in_chars--;
+ if (length_in_chars==0)
+ {
+ truncate(ptr-base);
+ add_string(append);
+ rv = true;
+ }
+ return rv;
+}
+
+template<template<typename> class t_alloc>
+t_size string8_t<t_alloc>::replace_nontext_chars(char p_replace)
+{
+ t_size ret = 0;
+ for(t_size n=0;n<used;n++)
+ {
+ if ((unsigned char)m_data[n] < 32) {m_data[n] = p_replace; ret++; }
+ }
+ return ret;
+}
+
+template<template<typename> class t_alloc>
+t_size string8_t<t_alloc>::replace_byte(char c1,char c2,t_size start)
+{
+ PFC_ASSERT(c1 != 0); PFC_ASSERT(c2 != 0);
+ t_size n, ret = 0;
+ for(n=start;n<used;n++)
+ {
+ if (m_data[n] == c1) {m_data[n] = c2; ret++;}
+ }
+ return ret;
+}
+
+template<template<typename> class t_alloc>
+t_size string8_t<t_alloc>::replace_char(unsigned c1,unsigned c2,t_size start)
+{
+ if (c1 < 128 && c2 < 128) return replace_byte((char)c1,(char)c2,start);
+
+ string8 temp(get_ptr()+start);
+ truncate(start);
+ const char * ptr = temp;
+ t_size rv = 0;
+ while(*ptr)
+ {
+ unsigned test;
+ t_size delta = utf8_decode_char(ptr,&test);
+ if (delta==0 || test==0) break;
+ if (test == c1) {test = c2;rv++;}
+ add_char(test);
+ ptr += delta;
+ }
+ return rv;
+}
+
+}
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/string_conv.cpp b/Plugins/listeningto/players/foo_mlt/pfc/string_conv.cpp
new file mode 100644
index 0000000..b25bfe1
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/string_conv.cpp
@@ -0,0 +1,163 @@
+#include "pfc.h"
+
+
+#ifdef _WINDOWS
+
+namespace {
+ template<typename t_char>
+ class string_writer_t {
+ public:
+ string_writer_t(t_char * p_buffer,t_size p_size) : m_buffer(p_buffer), m_size(p_size), m_writeptr(0) {}
+
+ void write(t_char p_char) {
+ if (m_writeptr < m_size) {
+ m_buffer[m_writeptr++] = p_char;
+ }
+ }
+ void write_multi(const t_char * p_buffer,t_size p_count) {
+ const t_size delta = pfc::min_t<t_size>(p_count,m_size-m_writeptr);
+ for(t_size n=0;n<delta;n++) {
+ m_buffer[m_writeptr++] = p_buffer[n];
+ }
+ }
+
+ void write_as_utf8(unsigned p_char) {
+ char temp[6];
+ t_size n = pfc::utf8_encode_char(p_char,temp);
+ write_multi(temp,n);
+ }
+
+ void write_as_wide(unsigned p_char) {
+ wchar_t temp[2];
+ t_size n = pfc::utf16_encode_char(p_char,temp);
+ write_multi(temp,n);
+ }
+
+ t_size finalize() {
+ if (m_size == 0) return 0;
+ t_size terminator = pfc::min_t<t_size>(m_writeptr,m_size-1);
+ m_buffer[terminator] = 0;
+ return terminator;
+ }
+ bool is_overrun() const {
+ return m_writeptr >= m_size;
+ }
+ private:
+ t_char * m_buffer;
+ t_size m_size;
+ t_size m_writeptr;
+ };
+
+
+
+};
+
+namespace pfc {
+ namespace stringcvt {
+
+
+ t_size convert_utf8_to_wide(wchar_t * p_out,t_size p_out_size,const char * p_in,t_size p_in_size) {
+ const t_size insize = p_in_size;
+ t_size inptr = 0;
+ string_writer_t<wchar_t> writer(p_out,p_out_size);
+
+ while(inptr < insize && !writer.is_overrun()) {
+ unsigned newchar = 0;
+ t_size delta = utf8_decode_char(p_in + inptr,&newchar,insize - inptr);
+ if (delta == 0 || newchar == 0) break;
+ PFC_ASSERT(inptr + delta <= insize);
+ inptr += delta;
+ writer.write_as_wide(newchar);
+ }
+
+ return writer.finalize();
+ }
+
+ t_size convert_wide_to_utf8(char * p_out,t_size p_out_size,const wchar_t * p_in,t_size p_in_size) {
+ const t_size insize = p_in_size;
+ t_size inptr = 0;
+ string_writer_t<char> writer(p_out,p_out_size);
+
+ while(inptr < insize && !writer.is_overrun()) {
+ unsigned newchar = 0;
+ t_size delta = utf16_decode_char(p_in + inptr,&newchar,insize - inptr);
+ if (delta == 0 || newchar == 0) break;
+ PFC_ASSERT(inptr + delta <= insize);
+ inptr += delta;
+ writer.write_as_utf8(newchar);
+ }
+
+ return writer.finalize();
+ }
+
+ t_size estimate_utf8_to_wide(const char * p_in,t_size p_in_size) {
+ const t_size insize = p_in_size;
+ t_size inptr = 0;
+ t_size retval = 1;//1 for null terminator
+ while(inptr < insize) {
+ unsigned newchar = 0;
+ t_size delta = utf8_decode_char(p_in + inptr,&newchar,insize - inptr);
+ if (delta == 0 || newchar == 0) break;
+ PFC_ASSERT(inptr + delta <= insize);
+ inptr += delta;
+
+ {
+ wchar_t temp[2];
+ delta = utf16_encode_char(newchar,temp);
+ if (delta == 0) break;
+ retval += delta;
+ }
+ }
+ return retval;
+ }
+
+ t_size estimate_wide_to_utf8(const wchar_t * p_in,t_size p_in_size) {
+ const t_size insize = p_in_size;
+ t_size inptr = 0;
+ t_size retval = 1;//1 for null terminator
+ while(inptr < insize) {
+ unsigned newchar = 0;
+ t_size delta = utf16_decode_char(p_in + inptr,&newchar,insize - inptr);
+ if (delta == 0 || newchar == 0) break;
+ PFC_ASSERT(inptr + delta <= insize);
+ inptr += delta;
+
+ {
+ char temp[6];
+ delta = utf8_encode_char(newchar,temp);
+ if (delta == 0) break;
+ retval += delta;
+ }
+ }
+ return retval;
+ }
+
+
+ t_size convert_codepage_to_wide(unsigned p_codepage,wchar_t * p_out,t_size p_out_size,const char * p_source,t_size p_source_size) {
+ if (p_out_size == 0) return 0;
+ memset(p_out,0,p_out_size * sizeof(*p_out));
+ MultiByteToWideChar(p_codepage,0,p_source,p_source_size,p_out,p_out_size);
+ p_out[p_out_size-1] = 0;
+ return wcslen(p_out);
+ }
+
+ t_size convert_wide_to_codepage(unsigned p_codepage,char * p_out,t_size p_out_size,const wchar_t * p_source,t_size p_source_size) {
+ if (p_out_size == 0) return 0;
+ memset(p_out,0,p_out_size * sizeof(*p_out));
+ WideCharToMultiByte(p_codepage,0,p_source,p_source_size,p_out,p_out_size,0,FALSE);
+ p_out[p_out_size-1] = 0;
+ return strlen(p_out);
+ }
+
+ t_size estimate_codepage_to_wide(unsigned p_codepage,const char * p_source,t_size p_source_size) {
+ return MultiByteToWideChar(p_codepage,0,p_source,strlen_max(p_source,p_source_size),0,0) + 1;
+ }
+ t_size estimate_wide_to_codepage(unsigned p_codepage,const wchar_t * p_source,t_size p_source_size) {
+ return WideCharToMultiByte(p_codepage,0,p_source,wcslen_max(p_source,p_source_size),0,0,0,FALSE) + 1;
+ }
+ }
+
+}
+
+#endif //_WINDOWS
+
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/string_conv.h b/Plugins/listeningto/players/foo_mlt/pfc/string_conv.h
new file mode 100644
index 0000000..b6b2ba0
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/string_conv.h
@@ -0,0 +1,355 @@
+namespace pfc {
+
+ namespace stringcvt {
+
+#ifdef _WINDOWS
+ enum {
+ codepage_system = CP_ACP,
+ codepage_ascii = 20127,
+ codepage_iso_8859_1 = 28591,
+ };
+
+ //! Converts UTF-8 characters to wide character.
+ //! @param p_out Output buffer, receives converted string, with null terminator.
+ //! @param p_out_size Size of output buffer, in characters. If converted string is too long, it will be truncated. Null terminator is always written, unless p_out_size is zero.
+ //! @param p_source String to convert.
+ //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
+ //! @returns Number of characters written, not counting null terminator.
+ t_size convert_utf8_to_wide(wchar_t * p_out,t_size p_out_size,const char * p_source,t_size p_source_size);
+
+ //! Estimates buffer size required to convert specified UTF-8 string to widechar.
+ //! @param p_source String to be converted.
+ //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
+ //! @returns Number of characters to allocate, including space for null terminator.
+ t_size estimate_utf8_to_wide(const char * p_source,t_size p_source_size);
+
+ //! Converts wide character string to UTF-8.
+ //! @param p_out Output buffer, receives converted string, with null terminator.
+ //! @param p_out_size Size of output buffer, in characters. If converted string is too long, it will be truncated. Null terminator is always written, unless p_out_size is zero.
+ //! @param p_source String to convert.
+ //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
+ //! @returns Number of characters written, not counting null terminator.
+ t_size convert_wide_to_utf8(char * p_out,t_size p_out_size,const wchar_t * p_source,t_size p_source_size);
+
+ //! Estimates buffer size required to convert specified wide character string to UTF-8.
+ //! @param p_source String to be converted.
+ //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
+ //! @returns Number of characters to allocate, including space for null terminator.
+ t_size estimate_wide_to_utf8(const wchar_t * p_source,t_size p_source_size);
+
+
+
+ //! Converts string from specified codepage to wide character.
+ //! @param p_out Output buffer, receives converted string, with null terminator.
+ //! @param p_codepage Codepage ID of source string.
+ //! @param p_source String to convert.
+ //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
+ //! @param p_out_size Size of output buffer, in characters. If converted string is too long, it will be truncated. Null terminator is always written, unless p_out_size is zero.
+ //! @returns Number of characters written, not counting null terminator.
+ t_size convert_codepage_to_wide(unsigned p_codepage,wchar_t * p_out,t_size p_out_size,const char * p_source,t_size p_source_size);
+
+ //! Estimates buffer size required to convert specified string from specified codepage to wide character.
+ //! @param p_codepage Codepage ID of source string.
+ //! @param p_source String to be converted.
+ //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
+ //! @returns Number of characters to allocate, including space for null terminator.
+ t_size estimate_codepage_to_wide(unsigned p_codepage,const char * p_source,t_size p_source_size);
+
+ //! Converts string from wide character to specified codepage.
+ //! @param p_codepage Codepage ID of source string.
+ //! @param p_out Output buffer, receives converted string, with null terminator.
+ //! @param p_out_size Size of output buffer, in characters. If converted string is too long, it will be truncated. Null terminator is always written, unless p_out_size is zero.
+ //! @param p_source String to convert.
+ //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
+ //! @returns Number of characters written, not counting null terminator.
+ t_size convert_wide_to_codepage(unsigned p_codepage,char * p_out,t_size p_out_size,const wchar_t * p_source,t_size p_source_size);
+
+ //! Estimates buffer size required to convert specified wide character string to specified codepage.
+ //! @param p_codepage Codepage ID of source string.
+ //! @param p_source String to be converted.
+ //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
+ //! @returns Number of characters to allocate, including space for null terminator.
+ t_size estimate_wide_to_codepage(unsigned p_codepage,const wchar_t * p_source,t_size p_source_size);
+
+
+ //! Converts string from system codepage to wide character.
+ //! @param p_out Output buffer, receives converted string, with null terminator.
+ //! @param p_source String to convert.
+ //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
+ //! @param p_out_size Size of output buffer, in characters. If converted string is too long, it will be truncated. Null terminator is always written, unless p_out_size is zero.
+ //! @returns Number of characters written, not counting null terminator.
+ inline t_size convert_ansi_to_wide(wchar_t * p_out,t_size p_out_size,const char * p_source,t_size p_source_size) {
+ return convert_codepage_to_wide(codepage_system,p_out,p_out_size,p_source,p_source_size);
+ }
+
+ //! Estimates buffer size required to convert specified system codepage string to wide character.
+ //! @param p_source String to be converted.
+ //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
+ //! @returns Number of characters to allocate, including space for null terminator.
+ inline t_size estimate_ansi_to_wide(const char * p_source,t_size p_source_size) {
+ return estimate_codepage_to_wide(codepage_system,p_source,p_source_size);
+ }
+
+ //! Converts string from wide character to system codepage.
+ //! @param p_out Output buffer, receives converted string, with null terminator.
+ //! @param p_out_size Size of output buffer, in characters. If converted string is too long, it will be truncated. Null terminator is always written, unless p_out_size is zero.
+ //! @param p_source String to convert.
+ //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
+ //! @returns Number of characters written, not counting null terminator.
+ inline t_size convert_wide_to_ansi(char * p_out,t_size p_out_size,const wchar_t * p_source,t_size p_source_size) {
+ return convert_wide_to_codepage(codepage_system,p_out,p_out_size,p_source,p_source_size);
+ }
+
+ //! Estimates buffer size required to convert specified wide character string to system codepage.
+ //! @param p_source String to be converted.
+ //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
+ //! @returns Number of characters to allocate, including space for null terminator.
+ inline t_size estimate_wide_to_ansi(const wchar_t * p_source,t_size p_source_size) {
+ return estimate_wide_to_codepage(codepage_system,p_source,p_source_size);
+ }
+
+ template<typename t_char> const t_char * null_string_t();
+ template<> inline const char * null_string_t<char>() {return "";}
+ template<> inline const wchar_t * null_string_t<wchar_t>() {return L"";}
+
+ template<typename t_char> t_size strlen_t(const t_char * p_string,t_size p_string_size = ~0) {
+ for(t_size n=0;n<p_string_size;n++) {
+ if (p_string[n] == 0) return n;
+ }
+ return p_string_size;
+ }
+
+ template<typename t_char> bool string_is_empty_t(const t_char * p_string,t_size p_string_size = ~0) {
+ if (p_string_size == 0) return true;
+ return p_string[0] == 0;
+ }
+
+ template<typename t_char,template<typename t_allocitem> class t_alloc = pfc::alloc_standard> class char_buffer_t {
+ public:
+ char_buffer_t() {}
+ char_buffer_t(const char_buffer_t & p_source) : m_buffer(p_source.m_buffer) {}
+ void set_size(t_size p_count) {m_buffer.set_size(p_count);}
+ t_char * get_ptr_var() {return m_buffer.get_ptr();}
+ const t_char * get_ptr() const {
+ return m_buffer.get_size() > 0 ? m_buffer.get_ptr() : null_string_t<t_char>();
+ }
+ private:
+ pfc::array_t<t_char,t_alloc> m_buffer;
+ };
+
+ template<template<typename t_allocitem> class t_alloc = pfc::alloc_standard>
+ class string_utf8_from_wide_t {
+ public:
+ string_utf8_from_wide_t() {}
+ string_utf8_from_wide_t(const wchar_t * p_source,t_size p_source_size = ~0) {convert(p_source,p_source_size);}
+
+ void convert(const wchar_t * p_source,t_size p_source_size = ~0) {
+ t_size size = estimate_wide_to_utf8(p_source,p_source_size);
+ m_buffer.set_size(size);
+ convert_wide_to_utf8( m_buffer.get_ptr_var(),size,p_source,p_source_size);
+ }
+
+ operator const char * () const {return get_ptr();}
+ const char * get_ptr() const {return m_buffer.get_ptr();}
+ bool is_empty() const {return string_is_empty_t(get_ptr());}
+ t_size length() const {return strlen_t(get_ptr());}
+
+ private:
+ char_buffer_t<char,t_alloc> m_buffer;
+ };
+ typedef string_utf8_from_wide_t<> string_utf8_from_wide;
+
+ template<template<typename t_allocitem> class t_alloc = pfc::alloc_standard>
+ class string_wide_from_utf8_t {
+ public:
+ string_wide_from_utf8_t() {}
+ string_wide_from_utf8_t(const string_wide_from_utf8_t<t_alloc> & p_source) : m_buffer(p_source.m_buffer) {}
+ string_wide_from_utf8_t(const char* p_source,t_size p_source_size = ~0) {convert(p_source,p_source_size);}
+
+ void convert(const char* p_source,t_size p_source_size = ~0) {
+ t_size size = estimate_utf8_to_wide(p_source,p_source_size);
+ m_buffer.set_size(size);
+ convert_utf8_to_wide( m_buffer.get_ptr_var(),size,p_source,p_source_size);
+ }
+
+ operator const wchar_t * () const {return get_ptr();}
+ const wchar_t * get_ptr() const {return m_buffer.get_ptr();}
+ bool is_empty() const {return string_is_empty_t(get_ptr());}
+ t_size length() const {return strlen_t(get_ptr());}
+
+ private:
+ char_buffer_t<wchar_t,t_alloc> m_buffer;
+ };
+ typedef string_wide_from_utf8_t<> string_wide_from_utf8;
+
+ template<template<typename t_allocitem> class t_alloc = pfc::alloc_standard>
+ class string_wide_from_codepage_t {
+ public:
+ string_wide_from_codepage_t() {}
+ string_wide_from_codepage_t(const string_wide_from_codepage_t<t_alloc> & p_source) : m_buffer(p_source.m_buffer) {}
+ string_wide_from_codepage_t(unsigned p_codepage,const char * p_source,t_size p_source_size = ~0) {convert(p_codepage,p_source,p_source_size);}
+
+ void convert(unsigned p_codepage,const char * p_source,t_size p_source_size = ~0) {
+ t_size size = estimate_codepage_to_wide(p_codepage,p_source,p_source_size);
+ m_buffer.set_size(size);
+ convert_codepage_to_wide(p_codepage, m_buffer.get_ptr_var(),size,p_source,p_source_size);
+ }
+
+ operator const wchar_t * () const {return get_ptr();}
+ const wchar_t * get_ptr() const {return m_buffer.get_ptr();}
+ bool is_empty() const {return string_is_empty_t(get_ptr());}
+ t_size length() const {return strlen_t(get_ptr());}
+
+ private:
+ char_buffer_t<wchar_t,t_alloc> m_buffer;
+ };
+ typedef string_wide_from_codepage_t<> string_wide_from_codepage;
+
+
+ template<template<typename t_allocitem> class t_alloc = pfc::alloc_standard>
+ class string_codepage_from_wide_t {
+ public:
+ string_codepage_from_wide_t() {}
+ string_codepage_from_wide_t(const string_codepage_from_wide_t<t_alloc> & p_source) : m_buffer(p_source.m_buffer) {}
+ string_codepage_from_wide_t(unsigned p_codepage,const wchar_t * p_source,t_size p_source_size = ~0) {convert(p_codepage,p_source,p_source_size);}
+
+ void convert(unsigned p_codepage,const wchar_t * p_source,t_size p_source_size = ~0) {
+ t_size size = estimate_wide_to_codepage(p_codepage,p_source,p_source_size);
+ m_buffer.set_size(size);
+ convert_wide_to_codepage(p_codepage, m_buffer.get_ptr_var(),size,p_source,p_source_size);
+ }
+
+ operator const char * () const {return get_ptr();}
+ const char * get_ptr() const {return m_buffer.get_ptr();}
+ bool is_empty() const {return string_is_empty_t(get_ptr());}
+ t_size length() const {return strlen_t(get_ptr());}
+
+ private:
+ char_buffer_t<char,t_alloc> m_buffer;
+ };
+ typedef string_codepage_from_wide_t<> string_codepage_from_wide;
+
+ class string_codepage_from_utf8 {
+ public:
+ string_codepage_from_utf8() {}
+ string_codepage_from_utf8(const string_codepage_from_utf8 & p_source) : m_buffer(p_source.m_buffer) {}
+ string_codepage_from_utf8(unsigned p_codepage,const char * p_source,t_size p_source_size = ~0) {convert(p_codepage,p_source,p_source_size);}
+
+ void convert(unsigned p_codepage,const char * p_source,t_size p_source_size = ~0) {
+ string_wide_from_utf8 temp;
+ temp.convert(p_source,p_source_size);
+ t_size size = estimate_wide_to_codepage(p_codepage,temp,~0);
+ m_buffer.set_size(size);
+ convert_wide_to_codepage(p_codepage,m_buffer.get_ptr_var(),size,temp,~0);
+ }
+
+ operator const char * () const {return get_ptr();}
+ const char * get_ptr() const {return m_buffer.get_ptr();}
+ bool is_empty() const {return string_is_empty_t(get_ptr());}
+ t_size length() const {return strlen_t(get_ptr());}
+
+ private:
+ char_buffer_t<char> m_buffer;
+ };
+
+ class string_utf8_from_codepage {
+ public:
+ string_utf8_from_codepage() {}
+ string_utf8_from_codepage(const string_utf8_from_codepage & p_source) : m_buffer(p_source.m_buffer) {}
+ string_utf8_from_codepage(unsigned p_codepage,const char * p_source,t_size p_source_size = ~0) {convert(p_codepage,p_source,p_source_size);}
+
+ void convert(unsigned p_codepage,const char * p_source,t_size p_source_size = ~0) {
+ string_wide_from_codepage temp;
+ temp.convert(p_codepage,p_source,p_source_size);
+ t_size size = estimate_wide_to_utf8(temp,~0);
+ m_buffer.set_size(size);
+ convert_wide_to_utf8( m_buffer.get_ptr_var(),size,temp,~0);
+ }
+
+ operator const char * () const {return get_ptr();}
+ const char * get_ptr() const {return m_buffer.get_ptr();}
+ bool is_empty() const {return string_is_empty_t(get_ptr());}
+ t_size length() const {return strlen_t(get_ptr());}
+
+ private:
+ char_buffer_t<char> m_buffer;
+ };
+
+
+ class string_utf8_from_ansi {
+ public:
+ string_utf8_from_ansi() {}
+ string_utf8_from_ansi(const string_utf8_from_ansi & p_source) : m_buffer(p_source.m_buffer) {}
+ string_utf8_from_ansi(const char * p_source,t_size p_source_size = ~0) : m_buffer(codepage_system,p_source,p_source_size) {}
+ operator const char * () const {return get_ptr();}
+ const char * get_ptr() const {return m_buffer.get_ptr();}
+ bool is_empty() const {return string_is_empty_t(get_ptr());}
+ t_size length() const {return strlen_t(get_ptr());}
+
+ void convert(const char * p_source,t_size p_source_size = ~0) {m_buffer.convert(codepage_system,p_source,p_source_size);}
+
+ private:
+ string_utf8_from_codepage m_buffer;
+ };
+
+ class string_ansi_from_utf8 {
+ public:
+ string_ansi_from_utf8() {}
+ string_ansi_from_utf8(const string_ansi_from_utf8 & p_source) : m_buffer(p_source.m_buffer) {}
+ string_ansi_from_utf8(const char * p_source,t_size p_source_size = ~0) : m_buffer(codepage_system,p_source,p_source_size) {}
+ operator const char * () const {return get_ptr();}
+ const char * get_ptr() const {return m_buffer.get_ptr();}
+ bool is_empty() const {return string_is_empty_t(get_ptr());}
+ t_size length() const {return strlen_t(get_ptr());}
+
+ void convert(const char * p_source,t_size p_source_size = ~0) {m_buffer.convert(codepage_system,p_source,p_source_size);}
+
+ private:
+ string_codepage_from_utf8 m_buffer;
+ };
+
+ class string_wide_from_ansi {
+ public:
+ string_wide_from_ansi() {}
+ string_wide_from_ansi(const string_wide_from_ansi & p_source) : m_buffer(p_source.m_buffer) {}
+ string_wide_from_ansi(const char * p_source,t_size p_source_size = ~0) : m_buffer(codepage_system,p_source,p_source_size) {}
+ operator const wchar_t * () const {return get_ptr();}
+ const wchar_t * get_ptr() const {return m_buffer.get_ptr();}
+ bool is_empty() const {return string_is_empty_t(get_ptr());}
+ t_size length() const {return strlen_t(get_ptr());}
+
+ void convert(const char * p_source,t_size p_source_size = ~0) {m_buffer.convert(codepage_system,p_source,p_source_size);}
+
+ private:
+ string_wide_from_codepage m_buffer;
+ };
+
+ class string_ansi_from_wide {
+ public:
+ string_ansi_from_wide() {}
+ string_ansi_from_wide(const string_ansi_from_wide & p_source) : m_buffer(p_source.m_buffer) {}
+ string_ansi_from_wide(const wchar_t * p_source,t_size p_source_size = ~0) : m_buffer(codepage_system,p_source,p_source_size) {}
+ operator const char * () const {return get_ptr();}
+ const char * get_ptr() const {return m_buffer.get_ptr();}
+ bool is_empty() const {return string_is_empty_t(get_ptr());}
+ t_size length() const {return strlen_t(get_ptr());}
+
+ void convert(const wchar_t * p_source,t_size p_source_size = ~0) {m_buffer.convert(codepage_system,p_source,p_source_size);}
+
+ private:
+ string_codepage_from_wide m_buffer;
+ };
+
+#ifdef UNICODE
+ typedef string_wide_from_utf8 string_os_from_utf8;
+ typedef string_utf8_from_wide string_utf8_from_os;
+#else
+ typedef string_ansi_from_utf8 string_os_from_utf8;
+ typedef string_utf8_from_ansi string_utf8_from_os;
+#endif
+ }
+
+#else
+//PORTME
+#endif
+}; \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/string_list.h b/Plugins/listeningto/players/foo_mlt/pfc/string_list.h
new file mode 100644
index 0000000..bf07cdd
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/string_list.h
@@ -0,0 +1,58 @@
+#ifndef _PFC_STRING_LIST_H_
+#define _PFC_STRING_LIST_H_
+
+namespace pfc {
+
+ typedef list_base_const_t<const char*> string_list_const;
+
+ class string_list_impl : public string_list_const
+ {
+ public:
+ t_size get_count() const {return m_data.get_size();}
+ void get_item_ex(const char* & p_out, t_size n) const {p_out = m_data[n];}
+
+ inline const char * operator[] (t_size n) const {return m_data[n];}
+
+ void add_item(const char * p_string) {
+ t_size idx = m_data.get_size();
+ m_data.set_size(idx + 1);
+ m_data[idx] = p_string;
+ }
+
+ void add_items(const string_list_const & p_source) {_append(p_source);}
+
+ void remove_all()
+ {
+ m_data.set_size(0);
+ }
+
+ //unnecessary since pfc::array_t<pfc::string8> is in use for implementation
+ //~string_list_impl() {remove_all();}
+
+ inline string_list_impl() {}
+ inline string_list_impl(const string_list_impl & p_source) {_copy(p_source);}
+ inline string_list_impl(const string_list_const & p_source) {_copy(p_source);}
+ inline const string_list_impl & operator=(const string_list_impl & p_source) {_copy(p_source);return *this;}
+ inline const string_list_impl & operator=(const string_list_const & p_source) {_copy(p_source);return *this;}
+ inline const string_list_impl & operator+=(const string_list_impl & p_source) {_append(p_source);return *this;}
+ inline const string_list_impl & operator+=(const string_list_const & p_source) {_append(p_source);return *this;}
+
+ private:
+
+ void _append(const string_list_const & p_source) {
+ const t_size toadd = p_source.get_count(), base = m_data.get_size();
+ m_data.set_size(base+toadd);
+ for(t_size n=0;n<toadd;n++) m_data[base+n] = p_source[n];
+ }
+
+ void _copy(const string_list_const & p_source) {
+ const t_size newcount = p_source.get_count();
+ m_data.set_size(newcount);
+ for(t_size n=0;n<newcount;n++) m_data[n] = p_source[n];
+ }
+
+ pfc::array_t<pfc::string8,pfc::alloc_fast> m_data;
+ };
+}
+
+#endif //_PFC_STRING_LIST_H_
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/traits.h b/Plugins/listeningto/players/foo_mlt/pfc/traits.h
new file mode 100644
index 0000000..0110eb5
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/traits.h
@@ -0,0 +1,81 @@
+namespace pfc {
+
+ class traits_default {
+ public:
+ enum {
+ realloc_safe = false,
+ needs_destructor = true,
+ needs_constructor = true,
+ constructor_may_fail = true
+ };
+ };
+
+ class traits_default_movable {
+ public:
+ enum {
+ realloc_safe = true,
+ needs_destructor = true,
+ needs_constructor = true,
+ constructor_may_fail = true
+ };
+ };
+
+ class traits_rawobject : public traits_default {
+ public:
+ enum {
+ realloc_safe = true,
+ needs_destructor = false,
+ needs_constructor = false,
+ constructor_may_fail = false
+ };
+ };
+
+ class traits_vtable {
+ public:
+ enum {
+ realloc_safe = true,
+ needs_destructor = true,
+ needs_constructor = true,
+ constructor_may_fail = false
+ };
+ };
+
+ template<typename T> class traits_t : public traits_default {};
+
+ template<typename traits1,typename traits2>
+ class combine_traits {
+ public:
+ enum {
+ realloc_safe = (traits1::realloc_safe && traits2::realloc_safe),
+ needs_destructor = (traits1::needs_destructor || traits2::needs_destructor),
+ needs_constructor = (traits1::needs_constructor || traits2::needs_constructor),
+ constructor_may_fail = (traits1::constructor_may_fail || traits2::constructor_may_fail),
+ };
+ };
+
+ template<typename type1, typename type2>
+ class traits_combined : public combine_traits<pfc::traits_t<type1>,pfc::traits_t<type2> > {};
+
+ template<typename T> class traits_t<T*> : public traits_rawobject {};
+
+ template<> class traits_t<char> : public traits_rawobject {};
+ template<> class traits_t<unsigned char> : public traits_rawobject {};
+ template<> class traits_t<wchar_t> : public traits_rawobject {};
+ template<> class traits_t<short> : public traits_rawobject {};
+ template<> class traits_t<unsigned short> : public traits_rawobject {};
+ template<> class traits_t<int> : public traits_rawobject {};
+ template<> class traits_t<unsigned int> : public traits_rawobject {};
+ template<> class traits_t<long> : public traits_rawobject {};
+ template<> class traits_t<unsigned long> : public traits_rawobject {};
+ template<> class traits_t<long long> : public traits_rawobject {};
+ template<> class traits_t<unsigned long long> : public traits_rawobject {};
+ template<> class traits_t<bool> : public traits_rawobject {};
+
+ template<> class traits_t<float> : public traits_rawobject {};
+ template<> class traits_t<double> : public traits_rawobject {};
+
+ template<> class traits_t<GUID> : public traits_rawobject {};
+
+ template<typename T,t_size p_count>
+ class traits_t<T[p_count]> : public traits_t<T> {};
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foo_mlt/pfc/utf8.cpp b/Plugins/listeningto/players/foo_mlt/pfc/utf8.cpp
new file mode 100644
index 0000000..2bd1f3f
--- /dev/null
+++ b/Plugins/listeningto/players/foo_mlt/pfc/utf8.cpp
@@ -0,0 +1,286 @@
+#include "pfc.h"
+
+namespace pfc {
+//utf8 stuff
+
+static const t_uint8 mask_tab[6]={0x80,0xE0,0xF0,0xF8,0xFC,0xFE};
+
+static const t_uint8 val_tab[6]={0,0xC0,0xE0,0xF0,0xF8,0xFC};
+
+t_size utf8_char_len_from_header(char p_c)
+{
+ t_uint8 c = (t_uint8)p_c;
+
+ t_size cnt = 0;
+ for(;;)
+ {
+ if ((p_c & mask_tab[cnt])==val_tab[cnt]) break;
+ if (++cnt>=6) return 0;
+ }
+
+ return cnt + 1;
+
+}
+
+t_size utf8_decode_char(const char *p_utf8,unsigned * wide,t_size max)
+{
+ const t_uint8 * utf8 = (const t_uint8*)p_utf8;
+
+ if (wide) *wide = 0;
+
+ if (max==0)
+ return 0;
+ else if (max>6) max = 6;
+
+ if (utf8[0]<0x80)
+ {
+ if (wide) *wide = utf8[0];
+ return utf8[0]>0 ? 1 : 0;
+ }
+
+ unsigned res=0;
+ unsigned n;
+ unsigned cnt=0;
+ for(;;)
+ {
+ if ((*utf8&mask_tab[cnt])==val_tab[cnt]) break;
+ if (++cnt>=max) return 0;
+ }
+ cnt++;
+
+ if (cnt==2 && !(*utf8&0x1E)) return 0;
+
+ if (cnt==1)
+ res=*utf8;
+ else
+ res=(0xFF>>(cnt+1))&*utf8;
+
+ for (n=1;n<cnt;n++)
+ {
+ if ((utf8[n]&0xC0) != 0x80)
+ return 0;
+ if (!res && n==2 && !((utf8[n]&0x7F) >> (7 - cnt)))
+ return 0;
+
+ res=(res<<6)|(utf8[n]&0x3F);
+ }
+
+ if (wide)
+ *wide=res;
+
+ return cnt;
+}
+
+
+t_size utf8_encode_char(unsigned wide,char * target)
+{
+ t_size count;
+
+ if (wide < 0x80)
+ count = 1;
+ else if (wide < 0x800)
+ count = 2;
+ else if (wide < 0x10000)
+ count = 3;
+ else if (wide < 0x200000)
+ count = 4;
+ else if (wide < 0x4000000)
+ count = 5;
+ else if (wide <= 0x7FFFFFFF)
+ count = 6;
+ else
+ return 0;
+ //if (count>max) return 0;
+
+ if (target == 0)
+ return count;
+
+ switch (count)
+ {
+ case 6:
+ target[5] = 0x80 | (wide & 0x3F);
+ wide = wide >> 6;
+ wide |= 0x4000000;
+ case 5:
+ target[4] = 0x80 | (wide & 0x3F);
+ wide = wide >> 6;
+ wide |= 0x200000;
+ case 4:
+ target[3] = 0x80 | (wide & 0x3F);
+ wide = wide >> 6;
+ wide |= 0x10000;
+ case 3:
+ target[2] = 0x80 | (wide & 0x3F);
+ wide = wide >> 6;
+ wide |= 0x800;
+ case 2:
+ target[1] = 0x80 | (wide & 0x3F);
+ wide = wide >> 6;
+ wide |= 0xC0;
+ case 1:
+ target[0] = wide;
+ }
+
+ return count;
+}
+
+t_size utf16_encode_char(unsigned cur_wchar,wchar_t * out)
+{
+ if (cur_wchar>0 && cur_wchar<(1<<20))
+ {
+ if (sizeof(wchar_t) == 2 && cur_wchar>=0x10000)
+ {
+ unsigned c = cur_wchar - 0x10000;
+ //MSDN:
+ //The first (high) surrogate is a 16-bit code value in the range U+D800 to U+DBFF. The second (low) surrogate is a 16-bit code value in the range U+DC00 to U+DFFF. Using surrogates, Unicode can support over one million characters. For more details about surrogates, refer to The Unicode Standard, version 2.0.
+ out[0] = (wchar_t)(0xD800 | (0x3FF & (c>>10)) );
+ out[1] = (wchar_t)(0xDC00 | (0x3FF & c) ) ;
+ return 2;
+ }
+ else
+ {
+ *out = (wchar_t)cur_wchar;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+t_size utf16_decode_char(const wchar_t * p_source,unsigned * p_out,t_size p_source_length) {
+ if (p_source_length == 0) return 0;
+ else if (p_source_length == 1) {
+ *p_out = p_source[0];
+ return 1;
+ } else {
+ t_size retval = 0;
+ unsigned decoded = p_source[0];
+ if (decoded != 0)
+ {
+ retval = 1;
+ if ((decoded & 0xFC00) == 0xD800)
+ {
+ unsigned low = p_source[1];
+ if ((low & 0xFC00) == 0xDC00)
+ {
+ decoded = 0x10000 + ( ((decoded & 0x3FF) << 10) | (low & 0x3FF) );
+ retval = 2;
+ }
+ }
+ }
+ *p_out = decoded;
+ return retval;
+ }
+}
+
+
+UINT utf8_get_char(const char * src)
+{
+ UINT rv = 0;
+ utf8_decode_char(src,&rv);
+ return rv;
+}
+
+
+t_size utf8_char_len(const char * s,t_size max)
+{
+ return utf8_decode_char(s,0,max);
+}
+
+t_size skip_utf8_chars(const char * ptr,t_size count)
+{
+ t_size num = 0;
+ for(;count && ptr[num];count--)
+ {
+ t_size d = utf8_char_len(ptr+num);
+ if (d<=0) break;
+ num+=d;
+ }
+ return num;
+}
+
+bool is_valid_utf8(const char * param,t_size max) {
+ t_size walk = 0;
+ while(walk < max && param[walk] != 0) {
+ t_size d;
+ d = utf8_decode_char(param + walk,NULL,max - walk);
+ if (d==0) return false;
+ walk += d;
+ if (walk > max) {
+ PFC_ASSERT(0);//should not be triggerable
+ return false;
+ }
+ }
+ return true;
+}
+
+bool is_lower_ascii(const char * param)
+{
+ while(*param)
+ {
+ if (*param<0) return false;
+ param++;
+ }
+ return true;
+}
+
+static bool check_end_of_string(const char * ptr)
+{
+ __try {
+ return !*ptr;
+ }
+ __except(1) {return true;}
+}
+
+unsigned strcpy_utf8_truncate(const char * src,char * out,unsigned maxbytes)
+{
+ unsigned rv = 0 , ptr = 0;
+ if (maxbytes>0)
+ {
+ maxbytes--;//for null
+ while(!check_end_of_string(src) && maxbytes>0)
+ {
+ __try {
+ t_size delta = utf8_char_len(src);
+ if (delta>maxbytes || delta==0) break;
+ do
+ {
+ out[ptr++] = *(src++);
+ } while(--delta);
+ } __except(1) { break; }
+ rv = ptr;
+ }
+ out[rv]=0;
+ }
+ return rv;
+}
+
+t_size strlen_utf8(const char * p,t_size num)
+{
+ unsigned w;
+ t_size d;
+ t_size ret = 0;
+ for(;num;)
+ {
+ d = utf8_decode_char(p,&w);
+ if (w==0 || d<=0) break;
+ ret++;
+ p+=d;
+ num-=d;
+ }
+ return ret;
+}
+
+t_size utf8_chars_to_bytes(const char * string,t_size count)
+{
+ t_size bytes = 0;
+ while(count)
+ {
+ t_size delta = utf8_decode_char(string+bytes,0);
+ if (delta==0) break;
+ bytes += delta;
+ count--;
+ }
+ return bytes;
+}
+
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/foobar.cpp b/Plugins/listeningto/players/foobar.cpp
new file mode 100644
index 0000000..4eca008
--- /dev/null
+++ b/Plugins/listeningto/players/foobar.cpp
@@ -0,0 +1,35 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "..\\commons.h"
+
+static TCHAR *wcs[] = {
+ _T("{DA7CD0DE-1602-45e6-89A1-C2CA151E008E}/1"), // Foobar 0.9.1
+ _T("{DA7CD0DE-1602-45e6-89A1-C2CA151E008E}"),
+ _T("{97E27FAA-C0B3-4b8e-A693-ED7881E99FC1}"), // Foobar 0.9.5.3
+ _T("{E7076D1C-A7BF-4f39-B771-BCBE88F2A2A8}"), // Foobar Columns UI
+};
+
+Foobar::Foobar()
+{
+ name = _T("foobar2000");
+ window_classes = wcs;
+ num_window_classes = MAX_REGS(wcs);
+}
diff --git a/Plugins/listeningto/players/foobar.h b/Plugins/listeningto/players/foobar.h
new file mode 100644
index 0000000..b03f6f7
--- /dev/null
+++ b/Plugins/listeningto/players/foobar.h
@@ -0,0 +1,25 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+class Foobar : public ExternalPlayer
+{
+public:
+ Foobar();
+};
diff --git a/Plugins/listeningto/players/generic.cpp b/Plugins/listeningto/players/generic.cpp
new file mode 100644
index 0000000..4963010
--- /dev/null
+++ b/Plugins/listeningto/players/generic.cpp
@@ -0,0 +1,337 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "..\\commons.h"
+
+
+static LRESULT CALLBACK ReceiverWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+
+static UINT hTimer = NULL;
+
+GenericPlayer *singleton = NULL;
+
+
+
+int m_log(const TCHAR *function, const TCHAR *fmt, ...)
+{
+#if 0
+ va_list va;
+ TCHAR text[1024];
+ size_t len;
+
+ mir_sntprintf(text, MAX_REGS(text) - 10, _T("[%08u - %08u] [%s] "),
+ GetCurrentThreadId(), GetTickCount(), function);
+ len = lstrlen(text);
+
+ va_start(va, fmt);
+ mir_vsntprintf(&text[len], MAX_REGS(text) - len, fmt, va);
+ va_end(va);
+
+ BOOL writeBOM = (GetFileAttributes(_T("c:\\miranda_listeningto.log.txt")) == INVALID_FILE_ATTRIBUTES);
+
+ FILE *fp = _tfopen(_T("c:\\miranda_listeningto.log.txt"), _T("ab"));
+
+ if (fp != NULL)
+ {
+#ifdef UNICODE
+ if (writeBOM)
+ fwprintf(fp, L"\xFEFF");
+#endif
+
+ _ftprintf(fp, _T("%s\r\n"), text);
+ fclose(fp);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+#else
+ return 0;
+#endif
+}
+
+
+GenericPlayer::GenericPlayer()
+{
+ name = _T("GenericPlayer");
+
+ enabled = TRUE;
+ received[0] = L'\0';
+ singleton = this;
+
+ WNDCLASS wc = {0};
+ wc.lpfnWndProc = ReceiverWndProc;
+ wc.hInstance = hInst;
+ wc.lpszClassName = MIRANDA_WINDOWCLASS;
+
+ RegisterClass(&wc);
+
+ hWnd = CreateWindow(MIRANDA_WINDOWCLASS, _T("Miranda ListeningTo receiver"),
+ 0, 0, 0, 0, 0, NULL, NULL, hInst, NULL);
+}
+
+
+
+GenericPlayer::~GenericPlayer()
+{
+ if (hTimer != NULL)
+ {
+ KillTimer(NULL, hTimer);
+ hTimer = NULL;
+ }
+
+ DestroyWindow(hWnd);
+ hWnd = NULL;
+
+ UnregisterClass(MIRANDA_WINDOWCLASS, hInst);
+ singleton = NULL;
+}
+
+
+
+void GenericPlayer::ProcessReceived()
+{
+ EnterCriticalSection(&cs);
+
+ // Do the processing
+ // L"<Status 0-stoped 1-playing>\\0<Player>\\0<Type>\\0<Title>\\0<Artist>\\0<Album>\\0<Track>\\0<Year>\\0<Genre>\\0<Length (secs)>\\0\\0"
+
+ WCHAR *p1 = wcsstr(received, L"\\0");
+
+ if (IsEmpty(received) || p1 == NULL)
+ {
+// if (received[0] == L'\0')
+// m_log(_T("ProcessReceived"), _T("ERROR: Empty text"));
+// else
+// m_log(_T("ProcessReceived"), _T("ERROR: No \\0 found"));
+
+ // Ignore
+ LeaveCriticalSection(&cs);
+ return;
+ }
+
+ // Process string
+ WCHAR *parts[11] = {0};
+ int pCount = 0;
+ WCHAR *p = received;
+ do {
+ *p1 = L'\0';
+ parts[pCount] = p;
+ pCount ++;
+ p = p1 + 2;
+ p1 = wcsstr(p, L"\\0");
+ } while( p1 != NULL && pCount < 10 );
+ if (p1 != NULL)
+ *p1 = L'\0';
+ parts[pCount] = p;
+
+ if (pCount < 5)
+ {
+// m_log(_T("ProcessReceived"), _T("ERROR: Too little pieces"));
+
+ // Ignore
+ LeaveCriticalSection(&cs);
+ return;
+ }
+
+ // See if player is enabled
+ Player *player = this;
+ for (int i = FIRST_PLAYER; i < NUM_PLAYERS; i++)
+ {
+#ifdef UNICODE
+ WCHAR *player_name = players[i]->name;
+#else
+ WCHAR player_name[128];
+ MultiByteToWideChar(CP_ACP, 0, players[i]->m_name, -1, player_name, MAX_REGS(player_name));
+#endif
+ if (_wcsicmp(parts[1], player_name) == 0)
+ {
+ player = players[i];
+ break;
+ }
+ }
+
+
+ player->FreeData();
+
+
+ if (wcscmp(L"1", parts[0]) != 0 || IsEmpty(parts[1]) || (IsEmpty(parts[3]) && IsEmpty(parts[4])))
+ {
+ // Stoped playing or not enought info
+
+// if (wcscmp(L"1", parts[0]) != 0)
+// m_log(_T("ProcessReceived"), _T("END: Stoped playing"));
+// else
+// m_log(_T("ProcessReceived"), _T("ERROR: not enought info"));
+ }
+ else
+ {
+ LISTENINGTOINFO *li = player->LockListeningInfo();
+
+ li->cbSize = sizeof(listening_info);
+ li->dwFlags = LTI_TCHAR;
+ li->ptszType = U2TD(parts[2], L"Music");
+ li->ptszTitle = U2T(parts[3]);
+ li->ptszArtist = U2T(parts[4]);
+ li->ptszAlbum = U2T(parts[5]);
+ li->ptszTrack = U2T(parts[6]);
+ li->ptszYear = U2T(parts[7]);
+ li->ptszGenre = U2T(parts[8]);
+
+ if (player == this)
+ li->ptszPlayer = mir_u2t(parts[1]);
+ else
+ li->ptszPlayer = mir_tstrdup(player->name);
+
+ if (parts[9] != NULL)
+ {
+ long length = _wtoi(parts[9]);
+ if (length > 0)
+ {
+ li->ptszLength = (TCHAR*) mir_alloc(10 * sizeof(TCHAR));
+
+ int s = length % 60;
+ int m = (length / 60) % 60;
+ int h = (length / 60) / 60;
+
+ if (h > 0)
+ mir_sntprintf(li->ptszLength, 9, _T("%d:%02d:%02d"), h, m, s);
+ else
+ mir_sntprintf(li->ptszLength, 9, _T("%d:%02d"), m, s);
+ }
+ }
+
+ player->ReleaseListeningInfo();
+ }
+
+ // Put back the '\\'s
+ for(i = 1; i <= pCount; i++)
+ *(parts[i] - 2) = L'\\';
+ if (p1 != NULL)
+ *p1 = L'\\';
+
+ wcscpy(last_received, received);
+
+ LeaveCriticalSection(&cs);
+
+ NotifyInfoChanged();
+
+// m_log(_T("ProcessReceived"), _T("END: Success"));
+}
+
+
+static VOID CALLBACK SendTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ KillTimer(NULL, hTimer);
+ hTimer = NULL;
+
+ if (!loaded)
+ return;
+
+// m_log(_T("SendTimerProc"), _T("It's time to process"));
+
+ if (singleton != NULL)
+ singleton->ProcessReceived();
+}
+
+
+void GenericPlayer::NewData(const WCHAR *data, size_t len)
+{
+// m_log(_T("NewData"), _T("Processing"));
+
+ if (data[0] == L'\0')
+ {
+// m_log(_T("NewData"), _T("ERROR: Text is empty"));
+ return;
+ }
+
+ EnterCriticalSection(&cs);
+
+ len = min(len, 1023);
+ if (wcsncmp(received, data, len) != 0)
+ {
+// m_log(_T("NewData"), _T("Got new text, scheduling update"));
+
+ wcsncpy(received, data, len);
+ received[len] = L'\0';
+
+//#ifdef UNICODE
+// m_log(_T("NewData"), _T("Text: %s"), received);
+//#else
+// m_log(_T("NewData"), _T("Text: %S"), received);
+//#endif
+
+ if (hTimer)
+ KillTimer(NULL, hTimer);
+ hTimer = SetTimer(NULL, NULL, 300, SendTimerProc); // Do the processing after we return true
+ }
+// else
+// {
+// m_log(_T("NewData"), _T("END: Text is the same as last time"));
+// }
+
+ LeaveCriticalSection(&cs);
+}
+
+
+static LRESULT CALLBACK ReceiverWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_COPYDATA:
+ {
+ if (!loaded)
+ return FALSE;
+
+// m_log(_T("ReceiverWndProc"), _T("START: Received message"));
+
+ COPYDATASTRUCT* pData = (PCOPYDATASTRUCT) lParam;
+ if (pData == NULL || pData->dwData != MIRANDA_DW_PROTECTION
+ || pData->cbData == 0 || pData->lpData == NULL)
+ {
+/* if (pData == NULL)
+ m_log(_T("ReceiverWndProc"), _T("ERROR: COPYDATASTRUCT* is NULL"));
+ else if (pData->dwData != MIRANDA_DW_PROTECTION)
+ m_log(_T("ReceiverWndProc"), _T("ERROR: pData->dwData is incorrect"));
+ else if (pData->cbData == 0)
+ m_log(_T("ReceiverWndProc"), _T("ERROR: pData->cbData is 0"));
+ else if (pData->lpData == NULL)
+ m_log(_T("ReceiverWndProc"), _T("ERROR: pData->lpData is NULL"));
+*/
+ return FALSE;
+ }
+
+// m_log(_T("ReceiverWndProc"), _T("Going to process"));
+ if (singleton != NULL)
+ singleton->NewData((WCHAR *) pData->lpData, pData->cbData / 2);
+
+ return TRUE;
+ }
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+
+ default :
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+ return 0;
+}
diff --git a/Plugins/listeningto/players/generic.h b/Plugins/listeningto/players/generic.h
new file mode 100644
index 0000000..b9e56dd
--- /dev/null
+++ b/Plugins/listeningto/players/generic.h
@@ -0,0 +1,34 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+class GenericPlayer : public Player
+{
+protected:
+ HWND hWnd;
+
+public:
+ GenericPlayer();
+ virtual ~GenericPlayer();
+
+ WCHAR received[1024];
+ WCHAR last_received[1024];
+ void ProcessReceived();
+ void NewData(const WCHAR *data, size_t len);
+};
diff --git a/Plugins/listeningto/players/iTunesCOMInterface.h b/Plugins/listeningto/players/iTunesCOMInterface.h
new file mode 100644
index 0000000..31e701d
--- /dev/null
+++ b/Plugins/listeningto/players/iTunesCOMInterface.h
@@ -0,0 +1,13053 @@
+/* this ALWAYS GENERATED file contains the definitions for the interfaces */
+
+
+/* File created by MIDL compiler version 5.01.0164 */
+/* at Thu Oct 20 13:02:07 2005
+ */
+/* Compiler settings for iTunesCOMInterface.idl:
+ Oicf (OptLev=i2), W1, Zp8, env=Win32, ms_ext, c_ext
+ error checks: allocation ref bounds_check enum stub_data
+*/
+//@@MIDL_FILE_HEADING( )
+
+
+/* verify that the <rpcndr.h> version is high enough to compile this file*/
+#ifndef __REQUIRED_RPCNDR_H_VERSION__
+#define __REQUIRED_RPCNDR_H_VERSION__ 440
+#endif
+
+#include "rpc.h"
+#include "rpcndr.h"
+
+#ifndef __iTunesCOMInterface_h__
+#define __iTunesCOMInterface_h__
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+/* Forward Declarations */
+
+#ifndef __IITObject_FWD_DEFINED__
+#define __IITObject_FWD_DEFINED__
+typedef interface IITObject IITObject;
+#endif /* __IITObject_FWD_DEFINED__ */
+
+
+#ifndef __IITSource_FWD_DEFINED__
+#define __IITSource_FWD_DEFINED__
+typedef interface IITSource IITSource;
+#endif /* __IITSource_FWD_DEFINED__ */
+
+
+#ifndef __IITSourceCollection_FWD_DEFINED__
+#define __IITSourceCollection_FWD_DEFINED__
+typedef interface IITSourceCollection IITSourceCollection;
+#endif /* __IITSourceCollection_FWD_DEFINED__ */
+
+
+#ifndef __IITEncoder_FWD_DEFINED__
+#define __IITEncoder_FWD_DEFINED__
+typedef interface IITEncoder IITEncoder;
+#endif /* __IITEncoder_FWD_DEFINED__ */
+
+
+#ifndef __IITEncoderCollection_FWD_DEFINED__
+#define __IITEncoderCollection_FWD_DEFINED__
+typedef interface IITEncoderCollection IITEncoderCollection;
+#endif /* __IITEncoderCollection_FWD_DEFINED__ */
+
+
+#ifndef __IITEQPreset_FWD_DEFINED__
+#define __IITEQPreset_FWD_DEFINED__
+typedef interface IITEQPreset IITEQPreset;
+#endif /* __IITEQPreset_FWD_DEFINED__ */
+
+
+#ifndef __IITEQPresetCollection_FWD_DEFINED__
+#define __IITEQPresetCollection_FWD_DEFINED__
+typedef interface IITEQPresetCollection IITEQPresetCollection;
+#endif /* __IITEQPresetCollection_FWD_DEFINED__ */
+
+
+#ifndef __IITPlaylist_FWD_DEFINED__
+#define __IITPlaylist_FWD_DEFINED__
+typedef interface IITPlaylist IITPlaylist;
+#endif /* __IITPlaylist_FWD_DEFINED__ */
+
+
+#ifndef __IITOperationStatus_FWD_DEFINED__
+#define __IITOperationStatus_FWD_DEFINED__
+typedef interface IITOperationStatus IITOperationStatus;
+#endif /* __IITOperationStatus_FWD_DEFINED__ */
+
+
+#ifndef __IITConvertOperationStatus_FWD_DEFINED__
+#define __IITConvertOperationStatus_FWD_DEFINED__
+typedef interface IITConvertOperationStatus IITConvertOperationStatus;
+#endif /* __IITConvertOperationStatus_FWD_DEFINED__ */
+
+
+#ifndef __IITLibraryPlaylist_FWD_DEFINED__
+#define __IITLibraryPlaylist_FWD_DEFINED__
+typedef interface IITLibraryPlaylist IITLibraryPlaylist;
+#endif /* __IITLibraryPlaylist_FWD_DEFINED__ */
+
+
+#ifndef __IITUserPlaylist_FWD_DEFINED__
+#define __IITUserPlaylist_FWD_DEFINED__
+typedef interface IITUserPlaylist IITUserPlaylist;
+#endif /* __IITUserPlaylist_FWD_DEFINED__ */
+
+
+#ifndef __IITTrack_FWD_DEFINED__
+#define __IITTrack_FWD_DEFINED__
+typedef interface IITTrack IITTrack;
+#endif /* __IITTrack_FWD_DEFINED__ */
+
+
+#ifndef __IITTrackCollection_FWD_DEFINED__
+#define __IITTrackCollection_FWD_DEFINED__
+typedef interface IITTrackCollection IITTrackCollection;
+#endif /* __IITTrackCollection_FWD_DEFINED__ */
+
+
+#ifndef __IITVisual_FWD_DEFINED__
+#define __IITVisual_FWD_DEFINED__
+typedef interface IITVisual IITVisual;
+#endif /* __IITVisual_FWD_DEFINED__ */
+
+
+#ifndef __IITVisualCollection_FWD_DEFINED__
+#define __IITVisualCollection_FWD_DEFINED__
+typedef interface IITVisualCollection IITVisualCollection;
+#endif /* __IITVisualCollection_FWD_DEFINED__ */
+
+
+#ifndef __IITWindow_FWD_DEFINED__
+#define __IITWindow_FWD_DEFINED__
+typedef interface IITWindow IITWindow;
+#endif /* __IITWindow_FWD_DEFINED__ */
+
+
+#ifndef __IITBrowserWindow_FWD_DEFINED__
+#define __IITBrowserWindow_FWD_DEFINED__
+typedef interface IITBrowserWindow IITBrowserWindow;
+#endif /* __IITBrowserWindow_FWD_DEFINED__ */
+
+
+#ifndef __IITWindowCollection_FWD_DEFINED__
+#define __IITWindowCollection_FWD_DEFINED__
+typedef interface IITWindowCollection IITWindowCollection;
+#endif /* __IITWindowCollection_FWD_DEFINED__ */
+
+
+#ifndef __IiTunes_FWD_DEFINED__
+#define __IiTunes_FWD_DEFINED__
+typedef interface IiTunes IiTunes;
+#endif /* __IiTunes_FWD_DEFINED__ */
+
+
+#ifndef ___IiTunesEvents_FWD_DEFINED__
+#define ___IiTunesEvents_FWD_DEFINED__
+typedef interface _IiTunesEvents _IiTunesEvents;
+#endif /* ___IiTunesEvents_FWD_DEFINED__ */
+
+
+#ifndef ___IITConvertOperationStatusEvents_FWD_DEFINED__
+#define ___IITConvertOperationStatusEvents_FWD_DEFINED__
+typedef interface _IITConvertOperationStatusEvents _IITConvertOperationStatusEvents;
+#endif /* ___IITConvertOperationStatusEvents_FWD_DEFINED__ */
+
+
+#ifndef __iTunesApp_FWD_DEFINED__
+#define __iTunesApp_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class iTunesApp iTunesApp;
+#else
+typedef struct iTunesApp iTunesApp;
+#endif /* __cplusplus */
+
+#endif /* __iTunesApp_FWD_DEFINED__ */
+
+
+#ifndef __iTunesConvertOperationStatus_FWD_DEFINED__
+#define __iTunesConvertOperationStatus_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class iTunesConvertOperationStatus iTunesConvertOperationStatus;
+#else
+typedef struct iTunesConvertOperationStatus iTunesConvertOperationStatus;
+#endif /* __cplusplus */
+
+#endif /* __iTunesConvertOperationStatus_FWD_DEFINED__ */
+
+
+#ifndef __IITArtwork_FWD_DEFINED__
+#define __IITArtwork_FWD_DEFINED__
+typedef interface IITArtwork IITArtwork;
+#endif /* __IITArtwork_FWD_DEFINED__ */
+
+
+#ifndef __IITArtworkCollection_FWD_DEFINED__
+#define __IITArtworkCollection_FWD_DEFINED__
+typedef interface IITArtworkCollection IITArtworkCollection;
+#endif /* __IITArtworkCollection_FWD_DEFINED__ */
+
+
+#ifndef __IITURLTrack_FWD_DEFINED__
+#define __IITURLTrack_FWD_DEFINED__
+typedef interface IITURLTrack IITURLTrack;
+#endif /* __IITURLTrack_FWD_DEFINED__ */
+
+
+#ifndef __IITAudioCDPlaylist_FWD_DEFINED__
+#define __IITAudioCDPlaylist_FWD_DEFINED__
+typedef interface IITAudioCDPlaylist IITAudioCDPlaylist;
+#endif /* __IITAudioCDPlaylist_FWD_DEFINED__ */
+
+
+#ifndef __IITPlaylistCollection_FWD_DEFINED__
+#define __IITPlaylistCollection_FWD_DEFINED__
+typedef interface IITPlaylistCollection IITPlaylistCollection;
+#endif /* __IITPlaylistCollection_FWD_DEFINED__ */
+
+
+#ifndef __IITIPodSource_FWD_DEFINED__
+#define __IITIPodSource_FWD_DEFINED__
+typedef interface IITIPodSource IITIPodSource;
+#endif /* __IITIPodSource_FWD_DEFINED__ */
+
+
+#ifndef __IITFileOrCDTrack_FWD_DEFINED__
+#define __IITFileOrCDTrack_FWD_DEFINED__
+typedef interface IITFileOrCDTrack IITFileOrCDTrack;
+#endif /* __IITFileOrCDTrack_FWD_DEFINED__ */
+
+
+#ifndef __IITPlaylistWindow_FWD_DEFINED__
+#define __IITPlaylistWindow_FWD_DEFINED__
+typedef interface IITPlaylistWindow IITPlaylistWindow;
+#endif /* __IITPlaylistWindow_FWD_DEFINED__ */
+
+
+/* header files for imported files */
+#include "oaidl.h"
+#include "ocidl.h"
+#include "DispEx.h"
+
+void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t);
+void __RPC_USER MIDL_user_free( void __RPC_FAR * );
+
+/* interface __MIDL_itf_iTunesCOMInterface_0000 */
+/* [local] */
+
+typedef /* [public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0000_0001
+ { kITTypeLibrary_MajorVersion = 1,
+ kITTypeLibrary_MinorVersion = 7
+ } ITVersion;
+
+typedef /* [public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0000_0002
+ { ITUNES_E_USERCANCEL = 0xa0040201,
+ ITUNES_E_OBJECTDELETED = 0xa0040202,
+ ITUNES_E_OBJECTLOCKED = 0xa0040203,
+ ITUNES_E_CONVERSIONINPROGRESS = 0xa0040204,
+ ITUNES_E_MUSICSTOREDISABLED = 0xa0040205,
+ ITUNES_E_OBJECTEXISTS = 0xa0040206,
+ ITUNES_E_PODCASTSDISABLED = 0xa0040207
+ } ITErrors;
+
+
+
+extern RPC_IF_HANDLE __MIDL_itf_iTunesCOMInterface_0000_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_iTunesCOMInterface_0000_v0_0_s_ifspec;
+
+
+#ifndef __iTunesLib_LIBRARY_DEFINED__
+#define __iTunesLib_LIBRARY_DEFINED__
+
+/* library iTunesLib */
+/* [helpstring][uuid][version] */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef /* [public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0267_0001
+ { ITPlayerStateStopped = 0,
+ ITPlayerStatePlaying = ITPlayerStateStopped + 1,
+ ITPlayerStateFastForward = ITPlayerStatePlaying + 1,
+ ITPlayerStateRewind = ITPlayerStateFastForward + 1
+ } ITPlayerState;
+
+typedef /* [public][public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0267_0002
+ { ITVisualSizeSmall = 0,
+ ITVisualSizeMedium = ITVisualSizeSmall + 1,
+ ITVisualSizeLarge = ITVisualSizeMedium + 1
+ } ITVisualSize;
+
+typedef /* [public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0267_0003
+ { ITCOMDisabledReasonOther = 0,
+ ITCOMDisabledReasonDialog = ITCOMDisabledReasonOther + 1,
+ ITCOMDisabledReasonQuitting = ITCOMDisabledReasonDialog + 1
+ } ITCOMDisabledReason;
+
+typedef /* [public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0267_0004
+ { ITPlayButtonStatePlayDisabled = 0,
+ ITPlayButtonStatePlayEnabled = ITPlayButtonStatePlayDisabled + 1,
+ ITPlayButtonStatePauseEnabled = ITPlayButtonStatePlayEnabled + 1,
+ ITPlayButtonStatePauseDisabled = ITPlayButtonStatePauseEnabled + 1,
+ ITPlayButtonStateStopEnabled = ITPlayButtonStatePauseDisabled + 1,
+ ITPlayButtonStateStopDisabled = ITPlayButtonStateStopEnabled + 1
+ } ITPlayButtonState;
+
+typedef /* [public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0267_0005
+ { ITPlayerButtonPrevious = 0,
+ ITPlayerButtonPlay = ITPlayerButtonPrevious + 1,
+ ITPlayerButtonNext = ITPlayerButtonPlay + 1
+ } ITPlayerButton;
+
+typedef /* [public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0267_0006
+ { ITPlayerButtonModifierKeyNone = 0,
+ ITPlayerButtonModifierKeyShift = 1,
+ ITPlayerButtonModifierKeyControl = 2,
+ ITPlayerButtonModifierKeyAlt = 4,
+ ITPlayerButtonModifierKeyCapsLock = 8
+ } ITPlayerButtonModifierKey;
+
+typedef /* [public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0270_0001
+ { ITEventDatabaseChanged = 1,
+ ITEventPlayerPlay = 2,
+ ITEventPlayerStop = 3,
+ ITEventPlayerPlayingTrackChanged = 4,
+ ITEventUserInterfaceEnabled = 5,
+ ITEventCOMCallsDisabled = 6,
+ ITEventCOMCallsEnabled = 7,
+ ITEventQuitting = 8,
+ ITEventAboutToPromptUserToQuit = 9,
+ ITEventSoundVolumeChanged = 10
+ } ITEvent;
+
+typedef /* [public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0271_0001
+ { ITConvertOperationStatusChanged = 1,
+ ITConvertOperationComplete = 2
+ } ITConvertOperationStatusEvent;
+
+typedef /* [public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0272_0001
+ { ITArtworkFormatUnknown = 0,
+ ITArtworkFormatJPEG = ITArtworkFormatUnknown + 1,
+ ITArtworkFormatPNG = ITArtworkFormatJPEG + 1,
+ ITArtworkFormatBMP = ITArtworkFormatPNG + 1
+ } ITArtworkFormat;
+
+
+
+
+typedef /* [public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0278_0001
+ { ITPlaylistKindUnknown = 0,
+ ITPlaylistKindLibrary = ITPlaylistKindUnknown + 1,
+ ITPlaylistKindUser = ITPlaylistKindLibrary + 1,
+ ITPlaylistKindCD = ITPlaylistKindUser + 1,
+ ITPlaylistKindDevice = ITPlaylistKindCD + 1,
+ ITPlaylistKindRadioTuner = ITPlaylistKindDevice + 1
+ } ITPlaylistKind;
+
+typedef /* [public][public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0278_0002
+ { ITPlaylistRepeatModeOff = 0,
+ ITPlaylistRepeatModeOne = ITPlaylistRepeatModeOff + 1,
+ ITPlaylistRepeatModeAll = ITPlaylistRepeatModeOne + 1
+ } ITPlaylistRepeatMode;
+
+typedef /* [public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0278_0003
+ { ITPlaylistPrintKindPlaylist = 0,
+ ITPlaylistPrintKindAlbumlist = ITPlaylistPrintKindPlaylist + 1,
+ ITPlaylistPrintKindInsert = ITPlaylistPrintKindAlbumlist + 1
+ } ITPlaylistPrintKind;
+
+typedef /* [public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0278_0004
+ { ITPlaylistSearchFieldAll = 0,
+ ITPlaylistSearchFieldVisible = ITPlaylistSearchFieldAll + 1,
+ ITPlaylistSearchFieldArtists = ITPlaylistSearchFieldVisible + 1,
+ ITPlaylistSearchFieldAlbums = ITPlaylistSearchFieldArtists + 1,
+ ITPlaylistSearchFieldComposers = ITPlaylistSearchFieldAlbums + 1,
+ ITPlaylistSearchFieldSongNames = ITPlaylistSearchFieldComposers + 1
+ } ITPlaylistSearchField;
+
+typedef /* [public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0280_0001
+ { ITUserPlaylistSpecialKindNone = 0,
+ ITUserPlaylistSpecialKindPurchasedMusic = ITUserPlaylistSpecialKindNone + 1,
+ ITUserPlaylistSpecialKindPartyShuffle = ITUserPlaylistSpecialKindPurchasedMusic + 1,
+ ITUserPlaylistSpecialKindPodcasts = ITUserPlaylistSpecialKindPartyShuffle + 1,
+ ITUserPlaylistSpecialKindFolder = ITUserPlaylistSpecialKindPodcasts + 1,
+ ITUserPlaylistSpecialKindVideos = ITUserPlaylistSpecialKindFolder + 1
+ } ITUserPlaylistSpecialKind;
+
+
+typedef /* [public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0283_0001
+ { ITSourceKindUnknown = 0,
+ ITSourceKindLibrary = ITSourceKindUnknown + 1,
+ ITSourceKindIPod = ITSourceKindLibrary + 1,
+ ITSourceKindAudioCD = ITSourceKindIPod + 1,
+ ITSourceKindMP3CD = ITSourceKindAudioCD + 1,
+ ITSourceKindDevice = ITSourceKindMP3CD + 1,
+ ITSourceKindRadioTuner = ITSourceKindDevice + 1,
+ ITSourceKindSharedLibrary = ITSourceKindRadioTuner + 1
+ } ITSourceKind;
+
+
+typedef /* [public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0286_0001
+ { ITTrackKindUnknown = 0,
+ ITTrackKindFile = ITTrackKindUnknown + 1,
+ ITTrackKindCD = ITTrackKindFile + 1,
+ ITTrackKindURL = ITTrackKindCD + 1,
+ ITTrackKindDevice = ITTrackKindURL + 1,
+ ITTrackKindSharedLibrary = ITTrackKindDevice + 1
+ } ITTrackKind;
+
+typedef /* [public][public][v1_enum][uuid] */
+enum __MIDL___MIDL_itf_iTunesCOMInterface_0292_0001
+ { ITWindowKindUnknown = 0,
+ ITWindowKindBrowser = ITWindowKindUnknown + 1,
+ ITWindowKindPlaylist = ITWindowKindBrowser + 1,
+ ITWindowKindEQ = ITWindowKindPlaylist + 1,
+ ITWindowKindArtwork = ITWindowKindEQ + 1,
+ ITWindowKindNowPlaying = ITWindowKindArtwork + 1
+ } ITWindowKind;
+
+
+EXTERN_C const IID LIBID_iTunesLib;
+
+#ifndef __IITObject_INTERFACE_DEFINED__
+#define __IITObject_INTERFACE_DEFINED__
+
+/* interface IITObject */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITObject;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("9FAB0E27-70D7-4e3a-9965-B0C8B8869BB6")
+ IITObject : public IDispatch
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetITObjectIDs(
+ /* [out] */ long __RPC_FAR *sourceID,
+ /* [out] */ long __RPC_FAR *playlistID,
+ /* [out] */ long __RPC_FAR *trackID,
+ /* [out] */ long __RPC_FAR *databaseID) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Name(
+ /* [retval][out] */ BSTR __RPC_FAR *name) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Name(
+ /* [in] */ BSTR name) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Index(
+ /* [retval][out] */ long __RPC_FAR *index) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_SourceID(
+ /* [retval][out] */ long __RPC_FAR *sourceID) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_PlaylistID(
+ /* [retval][out] */ long __RPC_FAR *playlistID) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_TrackID(
+ /* [retval][out] */ long __RPC_FAR *trackID) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_TrackDatabaseID(
+ /* [retval][out] */ long __RPC_FAR *databaseID) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITObjectVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITObject __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITObject __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITObject __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITObject __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITObject __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITObject __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITObject __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetITObjectIDs )(
+ IITObject __RPC_FAR * This,
+ /* [out] */ long __RPC_FAR *sourceID,
+ /* [out] */ long __RPC_FAR *playlistID,
+ /* [out] */ long __RPC_FAR *trackID,
+ /* [out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITObject __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Name )(
+ IITObject __RPC_FAR * This,
+ /* [in] */ BSTR name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Index )(
+ IITObject __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SourceID )(
+ IITObject __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sourceID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlaylistID )(
+ IITObject __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playlistID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackID )(
+ IITObject __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackDatabaseID )(
+ IITObject __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *databaseID);
+
+ END_INTERFACE
+ } IITObjectVtbl;
+
+ interface IITObject
+ {
+ CONST_VTBL struct IITObjectVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITObject_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITObject_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITObject_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITObject_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITObject_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITObject_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITObject_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITObject_GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID) \
+ (This)->lpVtbl -> GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID)
+
+#define IITObject_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITObject_put_Name(This,name) \
+ (This)->lpVtbl -> put_Name(This,name)
+
+#define IITObject_get_Index(This,index) \
+ (This)->lpVtbl -> get_Index(This,index)
+
+#define IITObject_get_SourceID(This,sourceID) \
+ (This)->lpVtbl -> get_SourceID(This,sourceID)
+
+#define IITObject_get_PlaylistID(This,playlistID) \
+ (This)->lpVtbl -> get_PlaylistID(This,playlistID)
+
+#define IITObject_get_TrackID(This,trackID) \
+ (This)->lpVtbl -> get_TrackID(This,trackID)
+
+#define IITObject_get_TrackDatabaseID(This,databaseID) \
+ (This)->lpVtbl -> get_TrackDatabaseID(This,databaseID)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITObject_GetITObjectIDs_Proxy(
+ IITObject __RPC_FAR * This,
+ /* [out] */ long __RPC_FAR *sourceID,
+ /* [out] */ long __RPC_FAR *playlistID,
+ /* [out] */ long __RPC_FAR *trackID,
+ /* [out] */ long __RPC_FAR *databaseID);
+
+
+void __RPC_STUB IITObject_GetITObjectIDs_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITObject_get_Name_Proxy(
+ IITObject __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+
+void __RPC_STUB IITObject_get_Name_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITObject_put_Name_Proxy(
+ IITObject __RPC_FAR * This,
+ /* [in] */ BSTR name);
+
+
+void __RPC_STUB IITObject_put_Name_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITObject_get_Index_Proxy(
+ IITObject __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+
+void __RPC_STUB IITObject_get_Index_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITObject_get_SourceID_Proxy(
+ IITObject __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sourceID);
+
+
+void __RPC_STUB IITObject_get_SourceID_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITObject_get_PlaylistID_Proxy(
+ IITObject __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playlistID);
+
+
+void __RPC_STUB IITObject_get_PlaylistID_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITObject_get_TrackID_Proxy(
+ IITObject __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackID);
+
+
+void __RPC_STUB IITObject_get_TrackID_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITObject_get_TrackDatabaseID_Proxy(
+ IITObject __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *databaseID);
+
+
+void __RPC_STUB IITObject_get_TrackDatabaseID_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITObject_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITSource_INTERFACE_DEFINED__
+#define __IITSource_INTERFACE_DEFINED__
+
+/* interface IITSource */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITSource;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("AEC1C4D3-AEF1-4255-B892-3E3D13ADFDF9")
+ IITSource : public IITObject
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Kind(
+ /* [retval][out] */ ITSourceKind __RPC_FAR *kind) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Capacity(
+ /* [retval][out] */ double __RPC_FAR *capacity) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_FreeSpace(
+ /* [retval][out] */ double __RPC_FAR *freespace) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Playlists(
+ /* [retval][out] */ IITPlaylistCollection __RPC_FAR *__RPC_FAR *iPlaylistCollection) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITSourceVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITSource __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITSource __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITSource __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITSource __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITSource __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITSource __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITSource __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetITObjectIDs )(
+ IITSource __RPC_FAR * This,
+ /* [out] */ long __RPC_FAR *sourceID,
+ /* [out] */ long __RPC_FAR *playlistID,
+ /* [out] */ long __RPC_FAR *trackID,
+ /* [out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Name )(
+ IITSource __RPC_FAR * This,
+ /* [in] */ BSTR name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Index )(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SourceID )(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sourceID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlaylistID )(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playlistID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackID )(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackDatabaseID )(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Kind )(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ ITSourceKind __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Capacity )(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *capacity);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_FreeSpace )(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *freespace);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Playlists )(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ IITPlaylistCollection __RPC_FAR *__RPC_FAR *iPlaylistCollection);
+
+ END_INTERFACE
+ } IITSourceVtbl;
+
+ interface IITSource
+ {
+ CONST_VTBL struct IITSourceVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITSource_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITSource_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITSource_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITSource_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITSource_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITSource_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITSource_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITSource_GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID) \
+ (This)->lpVtbl -> GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID)
+
+#define IITSource_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITSource_put_Name(This,name) \
+ (This)->lpVtbl -> put_Name(This,name)
+
+#define IITSource_get_Index(This,index) \
+ (This)->lpVtbl -> get_Index(This,index)
+
+#define IITSource_get_SourceID(This,sourceID) \
+ (This)->lpVtbl -> get_SourceID(This,sourceID)
+
+#define IITSource_get_PlaylistID(This,playlistID) \
+ (This)->lpVtbl -> get_PlaylistID(This,playlistID)
+
+#define IITSource_get_TrackID(This,trackID) \
+ (This)->lpVtbl -> get_TrackID(This,trackID)
+
+#define IITSource_get_TrackDatabaseID(This,databaseID) \
+ (This)->lpVtbl -> get_TrackDatabaseID(This,databaseID)
+
+
+#define IITSource_get_Kind(This,kind) \
+ (This)->lpVtbl -> get_Kind(This,kind)
+
+#define IITSource_get_Capacity(This,capacity) \
+ (This)->lpVtbl -> get_Capacity(This,capacity)
+
+#define IITSource_get_FreeSpace(This,freespace) \
+ (This)->lpVtbl -> get_FreeSpace(This,freespace)
+
+#define IITSource_get_Playlists(This,iPlaylistCollection) \
+ (This)->lpVtbl -> get_Playlists(This,iPlaylistCollection)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITSource_get_Kind_Proxy(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ ITSourceKind __RPC_FAR *kind);
+
+
+void __RPC_STUB IITSource_get_Kind_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITSource_get_Capacity_Proxy(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *capacity);
+
+
+void __RPC_STUB IITSource_get_Capacity_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITSource_get_FreeSpace_Proxy(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *freespace);
+
+
+void __RPC_STUB IITSource_get_FreeSpace_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITSource_get_Playlists_Proxy(
+ IITSource __RPC_FAR * This,
+ /* [retval][out] */ IITPlaylistCollection __RPC_FAR *__RPC_FAR *iPlaylistCollection);
+
+
+void __RPC_STUB IITSource_get_Playlists_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITSource_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITSourceCollection_INTERFACE_DEFINED__
+#define __IITSourceCollection_INTERFACE_DEFINED__
+
+/* interface IITSourceCollection */
+/* [unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITSourceCollection;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("2FF6CE20-FF87-4183-B0B3-F323D047AF41")
+ IITSourceCollection : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
+ /* [retval][out] */ long __RPC_FAR *count) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Item(
+ /* [in] */ long index,
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iSource) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ItemByName(
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iSource) = 0;
+
+ virtual /* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITSourceCollectionVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITSourceCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITSourceCollection __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITSourceCollection __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITSourceCollection __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITSourceCollection __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITSourceCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITSourceCollection __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Count )(
+ IITSourceCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Item )(
+ IITSourceCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iSource);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ItemByName )(
+ IITSourceCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iSource);
+
+ /* [helpstring][restricted][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get__NewEnum )(
+ IITSourceCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+ END_INTERFACE
+ } IITSourceCollectionVtbl;
+
+ interface IITSourceCollection
+ {
+ CONST_VTBL struct IITSourceCollectionVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITSourceCollection_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITSourceCollection_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITSourceCollection_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITSourceCollection_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITSourceCollection_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITSourceCollection_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITSourceCollection_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITSourceCollection_get_Count(This,count) \
+ (This)->lpVtbl -> get_Count(This,count)
+
+#define IITSourceCollection_get_Item(This,index,iSource) \
+ (This)->lpVtbl -> get_Item(This,index,iSource)
+
+#define IITSourceCollection_get_ItemByName(This,name,iSource) \
+ (This)->lpVtbl -> get_ItemByName(This,name,iSource)
+
+#define IITSourceCollection_get__NewEnum(This,iEnumerator) \
+ (This)->lpVtbl -> get__NewEnum(This,iEnumerator)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITSourceCollection_get_Count_Proxy(
+ IITSourceCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+
+void __RPC_STUB IITSourceCollection_get_Count_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IITSourceCollection_get_Item_Proxy(
+ IITSourceCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iSource);
+
+
+void __RPC_STUB IITSourceCollection_get_Item_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITSourceCollection_get_ItemByName_Proxy(
+ IITSourceCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iSource);
+
+
+void __RPC_STUB IITSourceCollection_get_ItemByName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE IITSourceCollection_get__NewEnum_Proxy(
+ IITSourceCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+
+void __RPC_STUB IITSourceCollection_get__NewEnum_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITSourceCollection_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITEncoder_INTERFACE_DEFINED__
+#define __IITEncoder_INTERFACE_DEFINED__
+
+/* interface IITEncoder */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITEncoder;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("1CF95A1C-55FE-4f45-A2D3-85AC6C504A73")
+ IITEncoder : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Name(
+ /* [retval][out] */ BSTR __RPC_FAR *name) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Format(
+ /* [retval][out] */ BSTR __RPC_FAR *format) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITEncoderVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITEncoder __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITEncoder __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITEncoder __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITEncoder __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITEncoder __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITEncoder __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITEncoder __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITEncoder __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Format )(
+ IITEncoder __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *format);
+
+ END_INTERFACE
+ } IITEncoderVtbl;
+
+ interface IITEncoder
+ {
+ CONST_VTBL struct IITEncoderVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITEncoder_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITEncoder_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITEncoder_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITEncoder_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITEncoder_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITEncoder_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITEncoder_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITEncoder_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITEncoder_get_Format(This,format) \
+ (This)->lpVtbl -> get_Format(This,format)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEncoder_get_Name_Proxy(
+ IITEncoder __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+
+void __RPC_STUB IITEncoder_get_Name_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEncoder_get_Format_Proxy(
+ IITEncoder __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *format);
+
+
+void __RPC_STUB IITEncoder_get_Format_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITEncoder_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITEncoderCollection_INTERFACE_DEFINED__
+#define __IITEncoderCollection_INTERFACE_DEFINED__
+
+/* interface IITEncoderCollection */
+/* [unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITEncoderCollection;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("8862BCA9-168D-4549-A9D5-ADB35E553BA6")
+ IITEncoderCollection : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
+ /* [retval][out] */ long __RPC_FAR *count) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Item(
+ /* [in] */ long index,
+ /* [retval][out] */ IITEncoder __RPC_FAR *__RPC_FAR *iEncoder) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ItemByName(
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITEncoder __RPC_FAR *__RPC_FAR *iEncoder) = 0;
+
+ virtual /* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITEncoderCollectionVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITEncoderCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITEncoderCollection __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITEncoderCollection __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITEncoderCollection __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITEncoderCollection __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITEncoderCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITEncoderCollection __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Count )(
+ IITEncoderCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Item )(
+ IITEncoderCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITEncoder __RPC_FAR *__RPC_FAR *iEncoder);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ItemByName )(
+ IITEncoderCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITEncoder __RPC_FAR *__RPC_FAR *iEncoder);
+
+ /* [helpstring][restricted][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get__NewEnum )(
+ IITEncoderCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+ END_INTERFACE
+ } IITEncoderCollectionVtbl;
+
+ interface IITEncoderCollection
+ {
+ CONST_VTBL struct IITEncoderCollectionVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITEncoderCollection_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITEncoderCollection_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITEncoderCollection_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITEncoderCollection_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITEncoderCollection_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITEncoderCollection_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITEncoderCollection_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITEncoderCollection_get_Count(This,count) \
+ (This)->lpVtbl -> get_Count(This,count)
+
+#define IITEncoderCollection_get_Item(This,index,iEncoder) \
+ (This)->lpVtbl -> get_Item(This,index,iEncoder)
+
+#define IITEncoderCollection_get_ItemByName(This,name,iEncoder) \
+ (This)->lpVtbl -> get_ItemByName(This,name,iEncoder)
+
+#define IITEncoderCollection_get__NewEnum(This,iEnumerator) \
+ (This)->lpVtbl -> get__NewEnum(This,iEnumerator)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEncoderCollection_get_Count_Proxy(
+ IITEncoderCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+
+void __RPC_STUB IITEncoderCollection_get_Count_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IITEncoderCollection_get_Item_Proxy(
+ IITEncoderCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITEncoder __RPC_FAR *__RPC_FAR *iEncoder);
+
+
+void __RPC_STUB IITEncoderCollection_get_Item_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEncoderCollection_get_ItemByName_Proxy(
+ IITEncoderCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITEncoder __RPC_FAR *__RPC_FAR *iEncoder);
+
+
+void __RPC_STUB IITEncoderCollection_get_ItemByName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE IITEncoderCollection_get__NewEnum_Proxy(
+ IITEncoderCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+
+void __RPC_STUB IITEncoderCollection_get__NewEnum_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITEncoderCollection_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITEQPreset_INTERFACE_DEFINED__
+#define __IITEQPreset_INTERFACE_DEFINED__
+
+/* interface IITEQPreset */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITEQPreset;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("5BE75F4F-68FA-4212-ACB7-BE44EA569759")
+ IITEQPreset : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Name(
+ /* [retval][out] */ BSTR __RPC_FAR *name) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Modifiable(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isModifiable) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Preamp(
+ /* [retval][out] */ double __RPC_FAR *level) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Preamp(
+ /* [in] */ double level) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Band1(
+ /* [retval][out] */ double __RPC_FAR *level) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Band1(
+ /* [in] */ double level) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Band2(
+ /* [retval][out] */ double __RPC_FAR *level) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Band2(
+ /* [in] */ double level) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Band3(
+ /* [retval][out] */ double __RPC_FAR *level) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Band3(
+ /* [in] */ double level) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Band4(
+ /* [retval][out] */ double __RPC_FAR *level) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Band4(
+ /* [in] */ double level) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Band5(
+ /* [retval][out] */ double __RPC_FAR *level) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Band5(
+ /* [in] */ double level) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Band6(
+ /* [retval][out] */ double __RPC_FAR *level) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Band6(
+ /* [in] */ double level) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Band7(
+ /* [retval][out] */ double __RPC_FAR *level) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Band7(
+ /* [in] */ double level) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Band8(
+ /* [retval][out] */ double __RPC_FAR *level) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Band8(
+ /* [in] */ double level) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Band9(
+ /* [retval][out] */ double __RPC_FAR *level) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Band9(
+ /* [in] */ double level) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Band10(
+ /* [retval][out] */ double __RPC_FAR *level) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Band10(
+ /* [in] */ double level) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Delete(
+ /* [in] */ VARIANT_BOOL updateAllTracks) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Rename(
+ /* [in] */ BSTR newName,
+ /* [in] */ VARIANT_BOOL updateAllTracks) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITEQPresetVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITEQPreset __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITEQPreset __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITEQPreset __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Modifiable )(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isModifiable);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Preamp )(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Preamp )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Band1 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Band1 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Band2 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Band2 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Band3 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Band3 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Band4 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Band4 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Band5 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Band5 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Band6 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Band6 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Band7 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Band7 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Band8 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Band8 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Band9 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Band9 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Band10 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Band10 )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Delete )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL updateAllTracks);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Rename )(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ BSTR newName,
+ /* [in] */ VARIANT_BOOL updateAllTracks);
+
+ END_INTERFACE
+ } IITEQPresetVtbl;
+
+ interface IITEQPreset
+ {
+ CONST_VTBL struct IITEQPresetVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITEQPreset_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITEQPreset_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITEQPreset_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITEQPreset_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITEQPreset_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITEQPreset_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITEQPreset_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITEQPreset_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITEQPreset_get_Modifiable(This,isModifiable) \
+ (This)->lpVtbl -> get_Modifiable(This,isModifiable)
+
+#define IITEQPreset_get_Preamp(This,level) \
+ (This)->lpVtbl -> get_Preamp(This,level)
+
+#define IITEQPreset_put_Preamp(This,level) \
+ (This)->lpVtbl -> put_Preamp(This,level)
+
+#define IITEQPreset_get_Band1(This,level) \
+ (This)->lpVtbl -> get_Band1(This,level)
+
+#define IITEQPreset_put_Band1(This,level) \
+ (This)->lpVtbl -> put_Band1(This,level)
+
+#define IITEQPreset_get_Band2(This,level) \
+ (This)->lpVtbl -> get_Band2(This,level)
+
+#define IITEQPreset_put_Band2(This,level) \
+ (This)->lpVtbl -> put_Band2(This,level)
+
+#define IITEQPreset_get_Band3(This,level) \
+ (This)->lpVtbl -> get_Band3(This,level)
+
+#define IITEQPreset_put_Band3(This,level) \
+ (This)->lpVtbl -> put_Band3(This,level)
+
+#define IITEQPreset_get_Band4(This,level) \
+ (This)->lpVtbl -> get_Band4(This,level)
+
+#define IITEQPreset_put_Band4(This,level) \
+ (This)->lpVtbl -> put_Band4(This,level)
+
+#define IITEQPreset_get_Band5(This,level) \
+ (This)->lpVtbl -> get_Band5(This,level)
+
+#define IITEQPreset_put_Band5(This,level) \
+ (This)->lpVtbl -> put_Band5(This,level)
+
+#define IITEQPreset_get_Band6(This,level) \
+ (This)->lpVtbl -> get_Band6(This,level)
+
+#define IITEQPreset_put_Band6(This,level) \
+ (This)->lpVtbl -> put_Band6(This,level)
+
+#define IITEQPreset_get_Band7(This,level) \
+ (This)->lpVtbl -> get_Band7(This,level)
+
+#define IITEQPreset_put_Band7(This,level) \
+ (This)->lpVtbl -> put_Band7(This,level)
+
+#define IITEQPreset_get_Band8(This,level) \
+ (This)->lpVtbl -> get_Band8(This,level)
+
+#define IITEQPreset_put_Band8(This,level) \
+ (This)->lpVtbl -> put_Band8(This,level)
+
+#define IITEQPreset_get_Band9(This,level) \
+ (This)->lpVtbl -> get_Band9(This,level)
+
+#define IITEQPreset_put_Band9(This,level) \
+ (This)->lpVtbl -> put_Band9(This,level)
+
+#define IITEQPreset_get_Band10(This,level) \
+ (This)->lpVtbl -> get_Band10(This,level)
+
+#define IITEQPreset_put_Band10(This,level) \
+ (This)->lpVtbl -> put_Band10(This,level)
+
+#define IITEQPreset_Delete(This,updateAllTracks) \
+ (This)->lpVtbl -> Delete(This,updateAllTracks)
+
+#define IITEQPreset_Rename(This,newName,updateAllTracks) \
+ (This)->lpVtbl -> Rename(This,newName,updateAllTracks)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPreset_get_Name_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+
+void __RPC_STUB IITEQPreset_get_Name_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPreset_get_Modifiable_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isModifiable);
+
+
+void __RPC_STUB IITEQPreset_get_Modifiable_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPreset_get_Preamp_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+
+void __RPC_STUB IITEQPreset_get_Preamp_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITEQPreset_put_Preamp_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+
+void __RPC_STUB IITEQPreset_put_Preamp_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPreset_get_Band1_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+
+void __RPC_STUB IITEQPreset_get_Band1_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITEQPreset_put_Band1_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+
+void __RPC_STUB IITEQPreset_put_Band1_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPreset_get_Band2_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+
+void __RPC_STUB IITEQPreset_get_Band2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITEQPreset_put_Band2_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+
+void __RPC_STUB IITEQPreset_put_Band2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPreset_get_Band3_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+
+void __RPC_STUB IITEQPreset_get_Band3_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITEQPreset_put_Band3_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+
+void __RPC_STUB IITEQPreset_put_Band3_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPreset_get_Band4_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+
+void __RPC_STUB IITEQPreset_get_Band4_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITEQPreset_put_Band4_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+
+void __RPC_STUB IITEQPreset_put_Band4_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPreset_get_Band5_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+
+void __RPC_STUB IITEQPreset_get_Band5_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITEQPreset_put_Band5_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+
+void __RPC_STUB IITEQPreset_put_Band5_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPreset_get_Band6_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+
+void __RPC_STUB IITEQPreset_get_Band6_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITEQPreset_put_Band6_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+
+void __RPC_STUB IITEQPreset_put_Band6_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPreset_get_Band7_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+
+void __RPC_STUB IITEQPreset_get_Band7_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITEQPreset_put_Band7_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+
+void __RPC_STUB IITEQPreset_put_Band7_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPreset_get_Band8_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+
+void __RPC_STUB IITEQPreset_get_Band8_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITEQPreset_put_Band8_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+
+void __RPC_STUB IITEQPreset_put_Band8_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPreset_get_Band9_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+
+void __RPC_STUB IITEQPreset_get_Band9_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITEQPreset_put_Band9_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+
+void __RPC_STUB IITEQPreset_put_Band9_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPreset_get_Band10_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *level);
+
+
+void __RPC_STUB IITEQPreset_get_Band10_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITEQPreset_put_Band10_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ double level);
+
+
+void __RPC_STUB IITEQPreset_put_Band10_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITEQPreset_Delete_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL updateAllTracks);
+
+
+void __RPC_STUB IITEQPreset_Delete_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITEQPreset_Rename_Proxy(
+ IITEQPreset __RPC_FAR * This,
+ /* [in] */ BSTR newName,
+ /* [in] */ VARIANT_BOOL updateAllTracks);
+
+
+void __RPC_STUB IITEQPreset_Rename_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITEQPreset_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITEQPresetCollection_INTERFACE_DEFINED__
+#define __IITEQPresetCollection_INTERFACE_DEFINED__
+
+/* interface IITEQPresetCollection */
+/* [unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITEQPresetCollection;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("AEF4D111-3331-48da-B0C2-B468D5D61D08")
+ IITEQPresetCollection : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
+ /* [retval][out] */ long __RPC_FAR *count) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Item(
+ /* [in] */ long index,
+ /* [retval][out] */ IITEQPreset __RPC_FAR *__RPC_FAR *iEQPreset) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ItemByName(
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITEQPreset __RPC_FAR *__RPC_FAR *iEQPreset) = 0;
+
+ virtual /* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITEQPresetCollectionVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITEQPresetCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITEQPresetCollection __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITEQPresetCollection __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITEQPresetCollection __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITEQPresetCollection __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITEQPresetCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITEQPresetCollection __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Count )(
+ IITEQPresetCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Item )(
+ IITEQPresetCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITEQPreset __RPC_FAR *__RPC_FAR *iEQPreset);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ItemByName )(
+ IITEQPresetCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITEQPreset __RPC_FAR *__RPC_FAR *iEQPreset);
+
+ /* [helpstring][restricted][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get__NewEnum )(
+ IITEQPresetCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+ END_INTERFACE
+ } IITEQPresetCollectionVtbl;
+
+ interface IITEQPresetCollection
+ {
+ CONST_VTBL struct IITEQPresetCollectionVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITEQPresetCollection_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITEQPresetCollection_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITEQPresetCollection_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITEQPresetCollection_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITEQPresetCollection_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITEQPresetCollection_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITEQPresetCollection_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITEQPresetCollection_get_Count(This,count) \
+ (This)->lpVtbl -> get_Count(This,count)
+
+#define IITEQPresetCollection_get_Item(This,index,iEQPreset) \
+ (This)->lpVtbl -> get_Item(This,index,iEQPreset)
+
+#define IITEQPresetCollection_get_ItemByName(This,name,iEQPreset) \
+ (This)->lpVtbl -> get_ItemByName(This,name,iEQPreset)
+
+#define IITEQPresetCollection_get__NewEnum(This,iEnumerator) \
+ (This)->lpVtbl -> get__NewEnum(This,iEnumerator)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPresetCollection_get_Count_Proxy(
+ IITEQPresetCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+
+void __RPC_STUB IITEQPresetCollection_get_Count_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IITEQPresetCollection_get_Item_Proxy(
+ IITEQPresetCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITEQPreset __RPC_FAR *__RPC_FAR *iEQPreset);
+
+
+void __RPC_STUB IITEQPresetCollection_get_Item_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITEQPresetCollection_get_ItemByName_Proxy(
+ IITEQPresetCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITEQPreset __RPC_FAR *__RPC_FAR *iEQPreset);
+
+
+void __RPC_STUB IITEQPresetCollection_get_ItemByName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE IITEQPresetCollection_get__NewEnum_Proxy(
+ IITEQPresetCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+
+void __RPC_STUB IITEQPresetCollection_get__NewEnum_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITEQPresetCollection_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITPlaylist_INTERFACE_DEFINED__
+#define __IITPlaylist_INTERFACE_DEFINED__
+
+/* interface IITPlaylist */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITPlaylist;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("3D5E072F-2A77-4b17-9E73-E03B77CCCCA9")
+ IITPlaylist : public IITObject
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Delete( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE PlayFirstTrack( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Print(
+ /* [in] */ VARIANT_BOOL showPrintDialog,
+ /* [in] */ ITPlaylistPrintKind printKind,
+ /* [in] */ BSTR theme) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Search(
+ /* [in] */ BSTR searchText,
+ /* [in] */ ITPlaylistSearchField searchFields,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Kind(
+ /* [retval][out] */ ITPlaylistKind __RPC_FAR *kind) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Source(
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iSource) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Duration(
+ /* [retval][out] */ long __RPC_FAR *duration) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Shuffle(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isShuffle) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Shuffle(
+ /* [in] */ VARIANT_BOOL shouldShuffle) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Size(
+ /* [retval][out] */ double __RPC_FAR *size) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_SongRepeat(
+ /* [retval][out] */ ITPlaylistRepeatMode __RPC_FAR *repeatMode) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_SongRepeat(
+ /* [in] */ ITPlaylistRepeatMode repeatMode) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Time(
+ /* [retval][out] */ BSTR __RPC_FAR *time) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Visible(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isVisible) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Tracks(
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITPlaylistVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITPlaylist __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITPlaylist __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITPlaylist __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITPlaylist __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITPlaylist __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITPlaylist __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITPlaylist __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetITObjectIDs )(
+ IITPlaylist __RPC_FAR * This,
+ /* [out] */ long __RPC_FAR *sourceID,
+ /* [out] */ long __RPC_FAR *playlistID,
+ /* [out] */ long __RPC_FAR *trackID,
+ /* [out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Name )(
+ IITPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Index )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SourceID )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sourceID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlaylistID )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playlistID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackID )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackDatabaseID )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Delete )(
+ IITPlaylist __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *PlayFirstTrack )(
+ IITPlaylist __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Print )(
+ IITPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL showPrintDialog,
+ /* [in] */ ITPlaylistPrintKind printKind,
+ /* [in] */ BSTR theme);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Search )(
+ IITPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR searchText,
+ /* [in] */ ITPlaylistSearchField searchFields,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Kind )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ ITPlaylistKind __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Source )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iSource);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Duration )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *duration);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Shuffle )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isShuffle);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Shuffle )(
+ IITPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldShuffle);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Size )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *size);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SongRepeat )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ ITPlaylistRepeatMode __RPC_FAR *repeatMode);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_SongRepeat )(
+ IITPlaylist __RPC_FAR * This,
+ /* [in] */ ITPlaylistRepeatMode repeatMode);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Time )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *time);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Visible )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isVisible);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Tracks )(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+ END_INTERFACE
+ } IITPlaylistVtbl;
+
+ interface IITPlaylist
+ {
+ CONST_VTBL struct IITPlaylistVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITPlaylist_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITPlaylist_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITPlaylist_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITPlaylist_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITPlaylist_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITPlaylist_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITPlaylist_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITPlaylist_GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID) \
+ (This)->lpVtbl -> GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID)
+
+#define IITPlaylist_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITPlaylist_put_Name(This,name) \
+ (This)->lpVtbl -> put_Name(This,name)
+
+#define IITPlaylist_get_Index(This,index) \
+ (This)->lpVtbl -> get_Index(This,index)
+
+#define IITPlaylist_get_SourceID(This,sourceID) \
+ (This)->lpVtbl -> get_SourceID(This,sourceID)
+
+#define IITPlaylist_get_PlaylistID(This,playlistID) \
+ (This)->lpVtbl -> get_PlaylistID(This,playlistID)
+
+#define IITPlaylist_get_TrackID(This,trackID) \
+ (This)->lpVtbl -> get_TrackID(This,trackID)
+
+#define IITPlaylist_get_TrackDatabaseID(This,databaseID) \
+ (This)->lpVtbl -> get_TrackDatabaseID(This,databaseID)
+
+
+#define IITPlaylist_Delete(This) \
+ (This)->lpVtbl -> Delete(This)
+
+#define IITPlaylist_PlayFirstTrack(This) \
+ (This)->lpVtbl -> PlayFirstTrack(This)
+
+#define IITPlaylist_Print(This,showPrintDialog,printKind,theme) \
+ (This)->lpVtbl -> Print(This,showPrintDialog,printKind,theme)
+
+#define IITPlaylist_Search(This,searchText,searchFields,iTrackCollection) \
+ (This)->lpVtbl -> Search(This,searchText,searchFields,iTrackCollection)
+
+#define IITPlaylist_get_Kind(This,kind) \
+ (This)->lpVtbl -> get_Kind(This,kind)
+
+#define IITPlaylist_get_Source(This,iSource) \
+ (This)->lpVtbl -> get_Source(This,iSource)
+
+#define IITPlaylist_get_Duration(This,duration) \
+ (This)->lpVtbl -> get_Duration(This,duration)
+
+#define IITPlaylist_get_Shuffle(This,isShuffle) \
+ (This)->lpVtbl -> get_Shuffle(This,isShuffle)
+
+#define IITPlaylist_put_Shuffle(This,shouldShuffle) \
+ (This)->lpVtbl -> put_Shuffle(This,shouldShuffle)
+
+#define IITPlaylist_get_Size(This,size) \
+ (This)->lpVtbl -> get_Size(This,size)
+
+#define IITPlaylist_get_SongRepeat(This,repeatMode) \
+ (This)->lpVtbl -> get_SongRepeat(This,repeatMode)
+
+#define IITPlaylist_put_SongRepeat(This,repeatMode) \
+ (This)->lpVtbl -> put_SongRepeat(This,repeatMode)
+
+#define IITPlaylist_get_Time(This,time) \
+ (This)->lpVtbl -> get_Time(This,time)
+
+#define IITPlaylist_get_Visible(This,isVisible) \
+ (This)->lpVtbl -> get_Visible(This,isVisible)
+
+#define IITPlaylist_get_Tracks(This,iTrackCollection) \
+ (This)->lpVtbl -> get_Tracks(This,iTrackCollection)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITPlaylist_Delete_Proxy(
+ IITPlaylist __RPC_FAR * This);
+
+
+void __RPC_STUB IITPlaylist_Delete_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITPlaylist_PlayFirstTrack_Proxy(
+ IITPlaylist __RPC_FAR * This);
+
+
+void __RPC_STUB IITPlaylist_PlayFirstTrack_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITPlaylist_Print_Proxy(
+ IITPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL showPrintDialog,
+ /* [in] */ ITPlaylistPrintKind printKind,
+ /* [in] */ BSTR theme);
+
+
+void __RPC_STUB IITPlaylist_Print_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITPlaylist_Search_Proxy(
+ IITPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR searchText,
+ /* [in] */ ITPlaylistSearchField searchFields,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+
+void __RPC_STUB IITPlaylist_Search_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylist_get_Kind_Proxy(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ ITPlaylistKind __RPC_FAR *kind);
+
+
+void __RPC_STUB IITPlaylist_get_Kind_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylist_get_Source_Proxy(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iSource);
+
+
+void __RPC_STUB IITPlaylist_get_Source_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylist_get_Duration_Proxy(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *duration);
+
+
+void __RPC_STUB IITPlaylist_get_Duration_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylist_get_Shuffle_Proxy(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isShuffle);
+
+
+void __RPC_STUB IITPlaylist_get_Shuffle_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITPlaylist_put_Shuffle_Proxy(
+ IITPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldShuffle);
+
+
+void __RPC_STUB IITPlaylist_put_Shuffle_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylist_get_Size_Proxy(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *size);
+
+
+void __RPC_STUB IITPlaylist_get_Size_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylist_get_SongRepeat_Proxy(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ ITPlaylistRepeatMode __RPC_FAR *repeatMode);
+
+
+void __RPC_STUB IITPlaylist_get_SongRepeat_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITPlaylist_put_SongRepeat_Proxy(
+ IITPlaylist __RPC_FAR * This,
+ /* [in] */ ITPlaylistRepeatMode repeatMode);
+
+
+void __RPC_STUB IITPlaylist_put_SongRepeat_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylist_get_Time_Proxy(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *time);
+
+
+void __RPC_STUB IITPlaylist_get_Time_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylist_get_Visible_Proxy(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isVisible);
+
+
+void __RPC_STUB IITPlaylist_get_Visible_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylist_get_Tracks_Proxy(
+ IITPlaylist __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+
+void __RPC_STUB IITPlaylist_get_Tracks_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITPlaylist_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITOperationStatus_INTERFACE_DEFINED__
+#define __IITOperationStatus_INTERFACE_DEFINED__
+
+/* interface IITOperationStatus */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITOperationStatus;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("206479C9-FE32-4f9b-A18A-475AC939B479")
+ IITOperationStatus : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_InProgress(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isInProgress) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Tracks(
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITOperationStatusVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITOperationStatus __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITOperationStatus __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITOperationStatus __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITOperationStatus __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITOperationStatus __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITOperationStatus __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITOperationStatus __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_InProgress )(
+ IITOperationStatus __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isInProgress);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Tracks )(
+ IITOperationStatus __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+ END_INTERFACE
+ } IITOperationStatusVtbl;
+
+ interface IITOperationStatus
+ {
+ CONST_VTBL struct IITOperationStatusVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITOperationStatus_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITOperationStatus_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITOperationStatus_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITOperationStatus_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITOperationStatus_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITOperationStatus_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITOperationStatus_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITOperationStatus_get_InProgress(This,isInProgress) \
+ (This)->lpVtbl -> get_InProgress(This,isInProgress)
+
+#define IITOperationStatus_get_Tracks(This,iTrackCollection) \
+ (This)->lpVtbl -> get_Tracks(This,iTrackCollection)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITOperationStatus_get_InProgress_Proxy(
+ IITOperationStatus __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isInProgress);
+
+
+void __RPC_STUB IITOperationStatus_get_InProgress_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITOperationStatus_get_Tracks_Proxy(
+ IITOperationStatus __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+
+void __RPC_STUB IITOperationStatus_get_Tracks_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITOperationStatus_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITConvertOperationStatus_INTERFACE_DEFINED__
+#define __IITConvertOperationStatus_INTERFACE_DEFINED__
+
+/* interface IITConvertOperationStatus */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITConvertOperationStatus;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("7063AAF6-ABA0-493b-B4FC-920A9F105875")
+ IITConvertOperationStatus : public IITOperationStatus
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetConversionStatus(
+ /* [out] */ BSTR __RPC_FAR *trackName,
+ /* [out] */ long __RPC_FAR *progressValue,
+ /* [out] */ long __RPC_FAR *maxProgressValue) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE StopConversion( void) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_TrackName(
+ /* [retval][out] */ BSTR __RPC_FAR *trackName) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ProgressValue(
+ /* [retval][out] */ long __RPC_FAR *progressValue) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_MaxProgressValue(
+ /* [retval][out] */ long __RPC_FAR *maxProgressValue) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITConvertOperationStatusVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITConvertOperationStatus __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITConvertOperationStatus __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_InProgress )(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isInProgress);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Tracks )(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetConversionStatus )(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [out] */ BSTR __RPC_FAR *trackName,
+ /* [out] */ long __RPC_FAR *progressValue,
+ /* [out] */ long __RPC_FAR *maxProgressValue);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *StopConversion )(
+ IITConvertOperationStatus __RPC_FAR * This);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackName )(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *trackName);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ProgressValue )(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *progressValue);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_MaxProgressValue )(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *maxProgressValue);
+
+ END_INTERFACE
+ } IITConvertOperationStatusVtbl;
+
+ interface IITConvertOperationStatus
+ {
+ CONST_VTBL struct IITConvertOperationStatusVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITConvertOperationStatus_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITConvertOperationStatus_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITConvertOperationStatus_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITConvertOperationStatus_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITConvertOperationStatus_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITConvertOperationStatus_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITConvertOperationStatus_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITConvertOperationStatus_get_InProgress(This,isInProgress) \
+ (This)->lpVtbl -> get_InProgress(This,isInProgress)
+
+#define IITConvertOperationStatus_get_Tracks(This,iTrackCollection) \
+ (This)->lpVtbl -> get_Tracks(This,iTrackCollection)
+
+
+#define IITConvertOperationStatus_GetConversionStatus(This,trackName,progressValue,maxProgressValue) \
+ (This)->lpVtbl -> GetConversionStatus(This,trackName,progressValue,maxProgressValue)
+
+#define IITConvertOperationStatus_StopConversion(This) \
+ (This)->lpVtbl -> StopConversion(This)
+
+#define IITConvertOperationStatus_get_TrackName(This,trackName) \
+ (This)->lpVtbl -> get_TrackName(This,trackName)
+
+#define IITConvertOperationStatus_get_ProgressValue(This,progressValue) \
+ (This)->lpVtbl -> get_ProgressValue(This,progressValue)
+
+#define IITConvertOperationStatus_get_MaxProgressValue(This,maxProgressValue) \
+ (This)->lpVtbl -> get_MaxProgressValue(This,maxProgressValue)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITConvertOperationStatus_GetConversionStatus_Proxy(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [out] */ BSTR __RPC_FAR *trackName,
+ /* [out] */ long __RPC_FAR *progressValue,
+ /* [out] */ long __RPC_FAR *maxProgressValue);
+
+
+void __RPC_STUB IITConvertOperationStatus_GetConversionStatus_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITConvertOperationStatus_StopConversion_Proxy(
+ IITConvertOperationStatus __RPC_FAR * This);
+
+
+void __RPC_STUB IITConvertOperationStatus_StopConversion_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITConvertOperationStatus_get_TrackName_Proxy(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *trackName);
+
+
+void __RPC_STUB IITConvertOperationStatus_get_TrackName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITConvertOperationStatus_get_ProgressValue_Proxy(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *progressValue);
+
+
+void __RPC_STUB IITConvertOperationStatus_get_ProgressValue_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITConvertOperationStatus_get_MaxProgressValue_Proxy(
+ IITConvertOperationStatus __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *maxProgressValue);
+
+
+void __RPC_STUB IITConvertOperationStatus_get_MaxProgressValue_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITConvertOperationStatus_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITLibraryPlaylist_INTERFACE_DEFINED__
+#define __IITLibraryPlaylist_INTERFACE_DEFINED__
+
+/* interface IITLibraryPlaylist */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITLibraryPlaylist;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("53AE1704-491C-4289-94A0-958815675A3D")
+ IITLibraryPlaylist : public IITPlaylist
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE AddFile(
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE AddFiles(
+ /* [in] */ VARIANT __RPC_FAR *filePaths,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE AddURL(
+ /* [in] */ BSTR url,
+ /* [retval][out] */ IITURLTrack __RPC_FAR *__RPC_FAR *iURLTrack) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE AddTrack(
+ /* [in] */ VARIANT __RPC_FAR *iTrackToAdd,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iAddedTrack) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITLibraryPlaylistVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITLibraryPlaylist __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITLibraryPlaylist __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetITObjectIDs )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [out] */ long __RPC_FAR *sourceID,
+ /* [out] */ long __RPC_FAR *playlistID,
+ /* [out] */ long __RPC_FAR *trackID,
+ /* [out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Name )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Index )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SourceID )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sourceID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlaylistID )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playlistID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackID )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackDatabaseID )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Delete )(
+ IITLibraryPlaylist __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *PlayFirstTrack )(
+ IITLibraryPlaylist __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Print )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL showPrintDialog,
+ /* [in] */ ITPlaylistPrintKind printKind,
+ /* [in] */ BSTR theme);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Search )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR searchText,
+ /* [in] */ ITPlaylistSearchField searchFields,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Kind )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ ITPlaylistKind __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Source )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iSource);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Duration )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *duration);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Shuffle )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isShuffle);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Shuffle )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldShuffle);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Size )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *size);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SongRepeat )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ ITPlaylistRepeatMode __RPC_FAR *repeatMode);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_SongRepeat )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ ITPlaylistRepeatMode repeatMode);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Time )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *time);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Visible )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isVisible);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Tracks )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddFile )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddFiles )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *filePaths,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddURL )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR url,
+ /* [retval][out] */ IITURLTrack __RPC_FAR *__RPC_FAR *iURLTrack);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddTrack )(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iTrackToAdd,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iAddedTrack);
+
+ END_INTERFACE
+ } IITLibraryPlaylistVtbl;
+
+ interface IITLibraryPlaylist
+ {
+ CONST_VTBL struct IITLibraryPlaylistVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITLibraryPlaylist_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITLibraryPlaylist_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITLibraryPlaylist_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITLibraryPlaylist_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITLibraryPlaylist_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITLibraryPlaylist_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITLibraryPlaylist_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITLibraryPlaylist_GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID) \
+ (This)->lpVtbl -> GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID)
+
+#define IITLibraryPlaylist_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITLibraryPlaylist_put_Name(This,name) \
+ (This)->lpVtbl -> put_Name(This,name)
+
+#define IITLibraryPlaylist_get_Index(This,index) \
+ (This)->lpVtbl -> get_Index(This,index)
+
+#define IITLibraryPlaylist_get_SourceID(This,sourceID) \
+ (This)->lpVtbl -> get_SourceID(This,sourceID)
+
+#define IITLibraryPlaylist_get_PlaylistID(This,playlistID) \
+ (This)->lpVtbl -> get_PlaylistID(This,playlistID)
+
+#define IITLibraryPlaylist_get_TrackID(This,trackID) \
+ (This)->lpVtbl -> get_TrackID(This,trackID)
+
+#define IITLibraryPlaylist_get_TrackDatabaseID(This,databaseID) \
+ (This)->lpVtbl -> get_TrackDatabaseID(This,databaseID)
+
+
+#define IITLibraryPlaylist_Delete(This) \
+ (This)->lpVtbl -> Delete(This)
+
+#define IITLibraryPlaylist_PlayFirstTrack(This) \
+ (This)->lpVtbl -> PlayFirstTrack(This)
+
+#define IITLibraryPlaylist_Print(This,showPrintDialog,printKind,theme) \
+ (This)->lpVtbl -> Print(This,showPrintDialog,printKind,theme)
+
+#define IITLibraryPlaylist_Search(This,searchText,searchFields,iTrackCollection) \
+ (This)->lpVtbl -> Search(This,searchText,searchFields,iTrackCollection)
+
+#define IITLibraryPlaylist_get_Kind(This,kind) \
+ (This)->lpVtbl -> get_Kind(This,kind)
+
+#define IITLibraryPlaylist_get_Source(This,iSource) \
+ (This)->lpVtbl -> get_Source(This,iSource)
+
+#define IITLibraryPlaylist_get_Duration(This,duration) \
+ (This)->lpVtbl -> get_Duration(This,duration)
+
+#define IITLibraryPlaylist_get_Shuffle(This,isShuffle) \
+ (This)->lpVtbl -> get_Shuffle(This,isShuffle)
+
+#define IITLibraryPlaylist_put_Shuffle(This,shouldShuffle) \
+ (This)->lpVtbl -> put_Shuffle(This,shouldShuffle)
+
+#define IITLibraryPlaylist_get_Size(This,size) \
+ (This)->lpVtbl -> get_Size(This,size)
+
+#define IITLibraryPlaylist_get_SongRepeat(This,repeatMode) \
+ (This)->lpVtbl -> get_SongRepeat(This,repeatMode)
+
+#define IITLibraryPlaylist_put_SongRepeat(This,repeatMode) \
+ (This)->lpVtbl -> put_SongRepeat(This,repeatMode)
+
+#define IITLibraryPlaylist_get_Time(This,time) \
+ (This)->lpVtbl -> get_Time(This,time)
+
+#define IITLibraryPlaylist_get_Visible(This,isVisible) \
+ (This)->lpVtbl -> get_Visible(This,isVisible)
+
+#define IITLibraryPlaylist_get_Tracks(This,iTrackCollection) \
+ (This)->lpVtbl -> get_Tracks(This,iTrackCollection)
+
+
+#define IITLibraryPlaylist_AddFile(This,filePath,iStatus) \
+ (This)->lpVtbl -> AddFile(This,filePath,iStatus)
+
+#define IITLibraryPlaylist_AddFiles(This,filePaths,iStatus) \
+ (This)->lpVtbl -> AddFiles(This,filePaths,iStatus)
+
+#define IITLibraryPlaylist_AddURL(This,url,iURLTrack) \
+ (This)->lpVtbl -> AddURL(This,url,iURLTrack)
+
+#define IITLibraryPlaylist_AddTrack(This,iTrackToAdd,iAddedTrack) \
+ (This)->lpVtbl -> AddTrack(This,iTrackToAdd,iAddedTrack)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITLibraryPlaylist_AddFile_Proxy(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+
+void __RPC_STUB IITLibraryPlaylist_AddFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITLibraryPlaylist_AddFiles_Proxy(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *filePaths,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+
+void __RPC_STUB IITLibraryPlaylist_AddFiles_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITLibraryPlaylist_AddURL_Proxy(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR url,
+ /* [retval][out] */ IITURLTrack __RPC_FAR *__RPC_FAR *iURLTrack);
+
+
+void __RPC_STUB IITLibraryPlaylist_AddURL_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITLibraryPlaylist_AddTrack_Proxy(
+ IITLibraryPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iTrackToAdd,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iAddedTrack);
+
+
+void __RPC_STUB IITLibraryPlaylist_AddTrack_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITLibraryPlaylist_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITUserPlaylist_INTERFACE_DEFINED__
+#define __IITUserPlaylist_INTERFACE_DEFINED__
+
+/* interface IITUserPlaylist */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITUserPlaylist;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("0A504DED-A0B5-465a-8A94-50E20D7DF692")
+ IITUserPlaylist : public IITPlaylist
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE AddFile(
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE AddFiles(
+ /* [in] */ VARIANT __RPC_FAR *filePaths,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE AddURL(
+ /* [in] */ BSTR url,
+ /* [retval][out] */ IITURLTrack __RPC_FAR *__RPC_FAR *iURLTrack) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE AddTrack(
+ /* [in] */ VARIANT __RPC_FAR *iTrackToAdd,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iAddedTrack) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Shared(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isShared) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Shared(
+ /* [in] */ VARIANT_BOOL shouldBeShared) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Smart(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isSmart) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_SpecialKind(
+ /* [retval][out] */ ITUserPlaylistSpecialKind __RPC_FAR *specialKind) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Parent(
+ /* [retval][out] */ IITUserPlaylist __RPC_FAR *__RPC_FAR *iParentPlayList) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CreatePlaylist(
+ /* [in] */ BSTR playlistName,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CreateFolder(
+ /* [in] */ BSTR folderName,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iFolder) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Parent(
+ /* [in] */ VARIANT __RPC_FAR *iParent) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITUserPlaylistVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITUserPlaylist __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITUserPlaylist __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetITObjectIDs )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [out] */ long __RPC_FAR *sourceID,
+ /* [out] */ long __RPC_FAR *playlistID,
+ /* [out] */ long __RPC_FAR *trackID,
+ /* [out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Name )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Index )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SourceID )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sourceID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlaylistID )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playlistID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackID )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackDatabaseID )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Delete )(
+ IITUserPlaylist __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *PlayFirstTrack )(
+ IITUserPlaylist __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Print )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL showPrintDialog,
+ /* [in] */ ITPlaylistPrintKind printKind,
+ /* [in] */ BSTR theme);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Search )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR searchText,
+ /* [in] */ ITPlaylistSearchField searchFields,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Kind )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ ITPlaylistKind __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Source )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iSource);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Duration )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *duration);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Shuffle )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isShuffle);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Shuffle )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldShuffle);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Size )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *size);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SongRepeat )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ ITPlaylistRepeatMode __RPC_FAR *repeatMode);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_SongRepeat )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ ITPlaylistRepeatMode repeatMode);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Time )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *time);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Visible )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isVisible);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Tracks )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddFile )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddFiles )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *filePaths,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddURL )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR url,
+ /* [retval][out] */ IITURLTrack __RPC_FAR *__RPC_FAR *iURLTrack);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddTrack )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iTrackToAdd,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iAddedTrack);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Shared )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isShared);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Shared )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeShared);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Smart )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isSmart);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SpecialKind )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ ITUserPlaylistSpecialKind __RPC_FAR *specialKind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Parent )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ IITUserPlaylist __RPC_FAR *__RPC_FAR *iParentPlayList);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CreatePlaylist )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR playlistName,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CreateFolder )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR folderName,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iFolder);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Parent )(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iParent);
+
+ END_INTERFACE
+ } IITUserPlaylistVtbl;
+
+ interface IITUserPlaylist
+ {
+ CONST_VTBL struct IITUserPlaylistVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITUserPlaylist_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITUserPlaylist_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITUserPlaylist_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITUserPlaylist_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITUserPlaylist_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITUserPlaylist_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITUserPlaylist_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITUserPlaylist_GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID) \
+ (This)->lpVtbl -> GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID)
+
+#define IITUserPlaylist_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITUserPlaylist_put_Name(This,name) \
+ (This)->lpVtbl -> put_Name(This,name)
+
+#define IITUserPlaylist_get_Index(This,index) \
+ (This)->lpVtbl -> get_Index(This,index)
+
+#define IITUserPlaylist_get_SourceID(This,sourceID) \
+ (This)->lpVtbl -> get_SourceID(This,sourceID)
+
+#define IITUserPlaylist_get_PlaylistID(This,playlistID) \
+ (This)->lpVtbl -> get_PlaylistID(This,playlistID)
+
+#define IITUserPlaylist_get_TrackID(This,trackID) \
+ (This)->lpVtbl -> get_TrackID(This,trackID)
+
+#define IITUserPlaylist_get_TrackDatabaseID(This,databaseID) \
+ (This)->lpVtbl -> get_TrackDatabaseID(This,databaseID)
+
+
+#define IITUserPlaylist_Delete(This) \
+ (This)->lpVtbl -> Delete(This)
+
+#define IITUserPlaylist_PlayFirstTrack(This) \
+ (This)->lpVtbl -> PlayFirstTrack(This)
+
+#define IITUserPlaylist_Print(This,showPrintDialog,printKind,theme) \
+ (This)->lpVtbl -> Print(This,showPrintDialog,printKind,theme)
+
+#define IITUserPlaylist_Search(This,searchText,searchFields,iTrackCollection) \
+ (This)->lpVtbl -> Search(This,searchText,searchFields,iTrackCollection)
+
+#define IITUserPlaylist_get_Kind(This,kind) \
+ (This)->lpVtbl -> get_Kind(This,kind)
+
+#define IITUserPlaylist_get_Source(This,iSource) \
+ (This)->lpVtbl -> get_Source(This,iSource)
+
+#define IITUserPlaylist_get_Duration(This,duration) \
+ (This)->lpVtbl -> get_Duration(This,duration)
+
+#define IITUserPlaylist_get_Shuffle(This,isShuffle) \
+ (This)->lpVtbl -> get_Shuffle(This,isShuffle)
+
+#define IITUserPlaylist_put_Shuffle(This,shouldShuffle) \
+ (This)->lpVtbl -> put_Shuffle(This,shouldShuffle)
+
+#define IITUserPlaylist_get_Size(This,size) \
+ (This)->lpVtbl -> get_Size(This,size)
+
+#define IITUserPlaylist_get_SongRepeat(This,repeatMode) \
+ (This)->lpVtbl -> get_SongRepeat(This,repeatMode)
+
+#define IITUserPlaylist_put_SongRepeat(This,repeatMode) \
+ (This)->lpVtbl -> put_SongRepeat(This,repeatMode)
+
+#define IITUserPlaylist_get_Time(This,time) \
+ (This)->lpVtbl -> get_Time(This,time)
+
+#define IITUserPlaylist_get_Visible(This,isVisible) \
+ (This)->lpVtbl -> get_Visible(This,isVisible)
+
+#define IITUserPlaylist_get_Tracks(This,iTrackCollection) \
+ (This)->lpVtbl -> get_Tracks(This,iTrackCollection)
+
+
+#define IITUserPlaylist_AddFile(This,filePath,iStatus) \
+ (This)->lpVtbl -> AddFile(This,filePath,iStatus)
+
+#define IITUserPlaylist_AddFiles(This,filePaths,iStatus) \
+ (This)->lpVtbl -> AddFiles(This,filePaths,iStatus)
+
+#define IITUserPlaylist_AddURL(This,url,iURLTrack) \
+ (This)->lpVtbl -> AddURL(This,url,iURLTrack)
+
+#define IITUserPlaylist_AddTrack(This,iTrackToAdd,iAddedTrack) \
+ (This)->lpVtbl -> AddTrack(This,iTrackToAdd,iAddedTrack)
+
+#define IITUserPlaylist_get_Shared(This,isShared) \
+ (This)->lpVtbl -> get_Shared(This,isShared)
+
+#define IITUserPlaylist_put_Shared(This,shouldBeShared) \
+ (This)->lpVtbl -> put_Shared(This,shouldBeShared)
+
+#define IITUserPlaylist_get_Smart(This,isSmart) \
+ (This)->lpVtbl -> get_Smart(This,isSmart)
+
+#define IITUserPlaylist_get_SpecialKind(This,specialKind) \
+ (This)->lpVtbl -> get_SpecialKind(This,specialKind)
+
+#define IITUserPlaylist_get_Parent(This,iParentPlayList) \
+ (This)->lpVtbl -> get_Parent(This,iParentPlayList)
+
+#define IITUserPlaylist_CreatePlaylist(This,playlistName,iPlaylist) \
+ (This)->lpVtbl -> CreatePlaylist(This,playlistName,iPlaylist)
+
+#define IITUserPlaylist_CreateFolder(This,folderName,iFolder) \
+ (This)->lpVtbl -> CreateFolder(This,folderName,iFolder)
+
+#define IITUserPlaylist_put_Parent(This,iParent) \
+ (This)->lpVtbl -> put_Parent(This,iParent)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITUserPlaylist_AddFile_Proxy(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+
+void __RPC_STUB IITUserPlaylist_AddFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITUserPlaylist_AddFiles_Proxy(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *filePaths,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+
+void __RPC_STUB IITUserPlaylist_AddFiles_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITUserPlaylist_AddURL_Proxy(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR url,
+ /* [retval][out] */ IITURLTrack __RPC_FAR *__RPC_FAR *iURLTrack);
+
+
+void __RPC_STUB IITUserPlaylist_AddURL_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITUserPlaylist_AddTrack_Proxy(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iTrackToAdd,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iAddedTrack);
+
+
+void __RPC_STUB IITUserPlaylist_AddTrack_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITUserPlaylist_get_Shared_Proxy(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isShared);
+
+
+void __RPC_STUB IITUserPlaylist_get_Shared_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITUserPlaylist_put_Shared_Proxy(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeShared);
+
+
+void __RPC_STUB IITUserPlaylist_put_Shared_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITUserPlaylist_get_Smart_Proxy(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isSmart);
+
+
+void __RPC_STUB IITUserPlaylist_get_Smart_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITUserPlaylist_get_SpecialKind_Proxy(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ ITUserPlaylistSpecialKind __RPC_FAR *specialKind);
+
+
+void __RPC_STUB IITUserPlaylist_get_SpecialKind_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITUserPlaylist_get_Parent_Proxy(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [retval][out] */ IITUserPlaylist __RPC_FAR *__RPC_FAR *iParentPlayList);
+
+
+void __RPC_STUB IITUserPlaylist_get_Parent_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITUserPlaylist_CreatePlaylist_Proxy(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR playlistName,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+
+void __RPC_STUB IITUserPlaylist_CreatePlaylist_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITUserPlaylist_CreateFolder_Proxy(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR folderName,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iFolder);
+
+
+void __RPC_STUB IITUserPlaylist_CreateFolder_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITUserPlaylist_put_Parent_Proxy(
+ IITUserPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iParent);
+
+
+void __RPC_STUB IITUserPlaylist_put_Parent_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITUserPlaylist_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITTrack_INTERFACE_DEFINED__
+#define __IITTrack_INTERFACE_DEFINED__
+
+/* interface IITTrack */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITTrack;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("4CB0915D-1E54-4727-BAF3-CE6CC9A225A1")
+ IITTrack : public IITObject
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Delete( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Play( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE AddArtworkFromFile(
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITArtwork __RPC_FAR *__RPC_FAR *iArtwork) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Kind(
+ /* [retval][out] */ ITTrackKind __RPC_FAR *kind) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Playlist(
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Album(
+ /* [retval][out] */ BSTR __RPC_FAR *album) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Album(
+ /* [in] */ BSTR album) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Artist(
+ /* [retval][out] */ BSTR __RPC_FAR *artist) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Artist(
+ /* [in] */ BSTR artist) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_BitRate(
+ /* [retval][out] */ long __RPC_FAR *bitrate) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_BPM(
+ /* [retval][out] */ long __RPC_FAR *beatsPerMinute) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_BPM(
+ /* [in] */ long beatsPerMinute) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Comment(
+ /* [retval][out] */ BSTR __RPC_FAR *comment) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Comment(
+ /* [in] */ BSTR comment) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Compilation(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isCompilation) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Compilation(
+ /* [in] */ VARIANT_BOOL shouldBeCompilation) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Composer(
+ /* [retval][out] */ BSTR __RPC_FAR *composer) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Composer(
+ /* [in] */ BSTR composer) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_DateAdded(
+ /* [retval][out] */ DATE __RPC_FAR *dateAdded) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_DiscCount(
+ /* [retval][out] */ long __RPC_FAR *discCount) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_DiscCount(
+ /* [in] */ long discCount) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_DiscNumber(
+ /* [retval][out] */ long __RPC_FAR *discNumber) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_DiscNumber(
+ /* [in] */ long discNumber) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Duration(
+ /* [retval][out] */ long __RPC_FAR *duration) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Enabled(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Enabled(
+ /* [in] */ VARIANT_BOOL shouldBeEnabled) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_EQ(
+ /* [retval][out] */ BSTR __RPC_FAR *eq) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_EQ(
+ /* [in] */ BSTR eq) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Finish(
+ /* [in] */ long finish) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Finish(
+ /* [retval][out] */ long __RPC_FAR *finish) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Genre(
+ /* [retval][out] */ BSTR __RPC_FAR *genre) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Genre(
+ /* [in] */ BSTR genre) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Grouping(
+ /* [retval][out] */ BSTR __RPC_FAR *grouping) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Grouping(
+ /* [in] */ BSTR grouping) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_KindAsString(
+ /* [retval][out] */ BSTR __RPC_FAR *kind) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ModificationDate(
+ /* [retval][out] */ DATE __RPC_FAR *dateModified) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_PlayedCount(
+ /* [retval][out] */ long __RPC_FAR *playedCount) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_PlayedCount(
+ /* [in] */ long playedCount) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_PlayedDate(
+ /* [retval][out] */ DATE __RPC_FAR *playedDate) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_PlayedDate(
+ /* [in] */ DATE playedDate) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_PlayOrderIndex(
+ /* [retval][out] */ long __RPC_FAR *index) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Rating(
+ /* [retval][out] */ long __RPC_FAR *rating) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Rating(
+ /* [in] */ long rating) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_SampleRate(
+ /* [retval][out] */ long __RPC_FAR *sampleRate) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Size(
+ /* [retval][out] */ long __RPC_FAR *size) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Start(
+ /* [retval][out] */ long __RPC_FAR *start) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Start(
+ /* [in] */ long start) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Time(
+ /* [retval][out] */ BSTR __RPC_FAR *time) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_TrackCount(
+ /* [retval][out] */ long __RPC_FAR *trackCount) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_TrackCount(
+ /* [in] */ long trackCount) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_TrackNumber(
+ /* [retval][out] */ long __RPC_FAR *trackNumber) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_TrackNumber(
+ /* [in] */ long trackNumber) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_VolumeAdjustment(
+ /* [retval][out] */ long __RPC_FAR *volumeAdjustment) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_VolumeAdjustment(
+ /* [in] */ long volumeAdjustment) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Year(
+ /* [retval][out] */ long __RPC_FAR *year) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Year(
+ /* [in] */ long year) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Artwork(
+ /* [retval][out] */ IITArtworkCollection __RPC_FAR *__RPC_FAR *iArtworkCollection) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITTrackVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITTrack __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITTrack __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITTrack __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetITObjectIDs )(
+ IITTrack __RPC_FAR * This,
+ /* [out] */ long __RPC_FAR *sourceID,
+ /* [out] */ long __RPC_FAR *playlistID,
+ /* [out] */ long __RPC_FAR *trackID,
+ /* [out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Name )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Index )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SourceID )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sourceID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlaylistID )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playlistID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackID )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackDatabaseID )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Delete )(
+ IITTrack __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Play )(
+ IITTrack __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddArtworkFromFile )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITArtwork __RPC_FAR *__RPC_FAR *iArtwork);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Kind )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ ITTrackKind __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Playlist )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Album )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *album);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Album )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR album);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Artist )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *artist);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Artist )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR artist);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_BitRate )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *bitrate);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_BPM )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *beatsPerMinute);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_BPM )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long beatsPerMinute);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Comment )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *comment);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Comment )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR comment);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Compilation )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isCompilation);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Compilation )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeCompilation);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Composer )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *composer);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Composer )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR composer);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_DateAdded )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ DATE __RPC_FAR *dateAdded);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_DiscCount )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *discCount);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_DiscCount )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long discCount);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_DiscNumber )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *discNumber);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_DiscNumber )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long discNumber);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Duration )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *duration);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Enabled )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Enabled )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeEnabled);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_EQ )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *eq);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_EQ )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR eq);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Finish )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long finish);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Finish )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *finish);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Genre )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *genre);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Genre )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR genre);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Grouping )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *grouping);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Grouping )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR grouping);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_KindAsString )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ModificationDate )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ DATE __RPC_FAR *dateModified);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlayedCount )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playedCount);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_PlayedCount )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long playedCount);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlayedDate )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ DATE __RPC_FAR *playedDate);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_PlayedDate )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ DATE playedDate);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlayOrderIndex )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Rating )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *rating);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Rating )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long rating);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SampleRate )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sampleRate);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Size )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *size);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Start )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *start);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Start )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long start);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Time )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *time);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackCount )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackCount);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_TrackCount )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long trackCount);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackNumber )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackNumber);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_TrackNumber )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long trackNumber);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_VolumeAdjustment )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *volumeAdjustment);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_VolumeAdjustment )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long volumeAdjustment);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Year )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *year);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Year )(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long year);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Artwork )(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ IITArtworkCollection __RPC_FAR *__RPC_FAR *iArtworkCollection);
+
+ END_INTERFACE
+ } IITTrackVtbl;
+
+ interface IITTrack
+ {
+ CONST_VTBL struct IITTrackVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITTrack_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITTrack_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITTrack_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITTrack_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITTrack_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITTrack_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITTrack_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITTrack_GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID) \
+ (This)->lpVtbl -> GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID)
+
+#define IITTrack_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITTrack_put_Name(This,name) \
+ (This)->lpVtbl -> put_Name(This,name)
+
+#define IITTrack_get_Index(This,index) \
+ (This)->lpVtbl -> get_Index(This,index)
+
+#define IITTrack_get_SourceID(This,sourceID) \
+ (This)->lpVtbl -> get_SourceID(This,sourceID)
+
+#define IITTrack_get_PlaylistID(This,playlistID) \
+ (This)->lpVtbl -> get_PlaylistID(This,playlistID)
+
+#define IITTrack_get_TrackID(This,trackID) \
+ (This)->lpVtbl -> get_TrackID(This,trackID)
+
+#define IITTrack_get_TrackDatabaseID(This,databaseID) \
+ (This)->lpVtbl -> get_TrackDatabaseID(This,databaseID)
+
+
+#define IITTrack_Delete(This) \
+ (This)->lpVtbl -> Delete(This)
+
+#define IITTrack_Play(This) \
+ (This)->lpVtbl -> Play(This)
+
+#define IITTrack_AddArtworkFromFile(This,filePath,iArtwork) \
+ (This)->lpVtbl -> AddArtworkFromFile(This,filePath,iArtwork)
+
+#define IITTrack_get_Kind(This,kind) \
+ (This)->lpVtbl -> get_Kind(This,kind)
+
+#define IITTrack_get_Playlist(This,iPlaylist) \
+ (This)->lpVtbl -> get_Playlist(This,iPlaylist)
+
+#define IITTrack_get_Album(This,album) \
+ (This)->lpVtbl -> get_Album(This,album)
+
+#define IITTrack_put_Album(This,album) \
+ (This)->lpVtbl -> put_Album(This,album)
+
+#define IITTrack_get_Artist(This,artist) \
+ (This)->lpVtbl -> get_Artist(This,artist)
+
+#define IITTrack_put_Artist(This,artist) \
+ (This)->lpVtbl -> put_Artist(This,artist)
+
+#define IITTrack_get_BitRate(This,bitrate) \
+ (This)->lpVtbl -> get_BitRate(This,bitrate)
+
+#define IITTrack_get_BPM(This,beatsPerMinute) \
+ (This)->lpVtbl -> get_BPM(This,beatsPerMinute)
+
+#define IITTrack_put_BPM(This,beatsPerMinute) \
+ (This)->lpVtbl -> put_BPM(This,beatsPerMinute)
+
+#define IITTrack_get_Comment(This,comment) \
+ (This)->lpVtbl -> get_Comment(This,comment)
+
+#define IITTrack_put_Comment(This,comment) \
+ (This)->lpVtbl -> put_Comment(This,comment)
+
+#define IITTrack_get_Compilation(This,isCompilation) \
+ (This)->lpVtbl -> get_Compilation(This,isCompilation)
+
+#define IITTrack_put_Compilation(This,shouldBeCompilation) \
+ (This)->lpVtbl -> put_Compilation(This,shouldBeCompilation)
+
+#define IITTrack_get_Composer(This,composer) \
+ (This)->lpVtbl -> get_Composer(This,composer)
+
+#define IITTrack_put_Composer(This,composer) \
+ (This)->lpVtbl -> put_Composer(This,composer)
+
+#define IITTrack_get_DateAdded(This,dateAdded) \
+ (This)->lpVtbl -> get_DateAdded(This,dateAdded)
+
+#define IITTrack_get_DiscCount(This,discCount) \
+ (This)->lpVtbl -> get_DiscCount(This,discCount)
+
+#define IITTrack_put_DiscCount(This,discCount) \
+ (This)->lpVtbl -> put_DiscCount(This,discCount)
+
+#define IITTrack_get_DiscNumber(This,discNumber) \
+ (This)->lpVtbl -> get_DiscNumber(This,discNumber)
+
+#define IITTrack_put_DiscNumber(This,discNumber) \
+ (This)->lpVtbl -> put_DiscNumber(This,discNumber)
+
+#define IITTrack_get_Duration(This,duration) \
+ (This)->lpVtbl -> get_Duration(This,duration)
+
+#define IITTrack_get_Enabled(This,isEnabled) \
+ (This)->lpVtbl -> get_Enabled(This,isEnabled)
+
+#define IITTrack_put_Enabled(This,shouldBeEnabled) \
+ (This)->lpVtbl -> put_Enabled(This,shouldBeEnabled)
+
+#define IITTrack_get_EQ(This,eq) \
+ (This)->lpVtbl -> get_EQ(This,eq)
+
+#define IITTrack_put_EQ(This,eq) \
+ (This)->lpVtbl -> put_EQ(This,eq)
+
+#define IITTrack_put_Finish(This,finish) \
+ (This)->lpVtbl -> put_Finish(This,finish)
+
+#define IITTrack_get_Finish(This,finish) \
+ (This)->lpVtbl -> get_Finish(This,finish)
+
+#define IITTrack_get_Genre(This,genre) \
+ (This)->lpVtbl -> get_Genre(This,genre)
+
+#define IITTrack_put_Genre(This,genre) \
+ (This)->lpVtbl -> put_Genre(This,genre)
+
+#define IITTrack_get_Grouping(This,grouping) \
+ (This)->lpVtbl -> get_Grouping(This,grouping)
+
+#define IITTrack_put_Grouping(This,grouping) \
+ (This)->lpVtbl -> put_Grouping(This,grouping)
+
+#define IITTrack_get_KindAsString(This,kind) \
+ (This)->lpVtbl -> get_KindAsString(This,kind)
+
+#define IITTrack_get_ModificationDate(This,dateModified) \
+ (This)->lpVtbl -> get_ModificationDate(This,dateModified)
+
+#define IITTrack_get_PlayedCount(This,playedCount) \
+ (This)->lpVtbl -> get_PlayedCount(This,playedCount)
+
+#define IITTrack_put_PlayedCount(This,playedCount) \
+ (This)->lpVtbl -> put_PlayedCount(This,playedCount)
+
+#define IITTrack_get_PlayedDate(This,playedDate) \
+ (This)->lpVtbl -> get_PlayedDate(This,playedDate)
+
+#define IITTrack_put_PlayedDate(This,playedDate) \
+ (This)->lpVtbl -> put_PlayedDate(This,playedDate)
+
+#define IITTrack_get_PlayOrderIndex(This,index) \
+ (This)->lpVtbl -> get_PlayOrderIndex(This,index)
+
+#define IITTrack_get_Rating(This,rating) \
+ (This)->lpVtbl -> get_Rating(This,rating)
+
+#define IITTrack_put_Rating(This,rating) \
+ (This)->lpVtbl -> put_Rating(This,rating)
+
+#define IITTrack_get_SampleRate(This,sampleRate) \
+ (This)->lpVtbl -> get_SampleRate(This,sampleRate)
+
+#define IITTrack_get_Size(This,size) \
+ (This)->lpVtbl -> get_Size(This,size)
+
+#define IITTrack_get_Start(This,start) \
+ (This)->lpVtbl -> get_Start(This,start)
+
+#define IITTrack_put_Start(This,start) \
+ (This)->lpVtbl -> put_Start(This,start)
+
+#define IITTrack_get_Time(This,time) \
+ (This)->lpVtbl -> get_Time(This,time)
+
+#define IITTrack_get_TrackCount(This,trackCount) \
+ (This)->lpVtbl -> get_TrackCount(This,trackCount)
+
+#define IITTrack_put_TrackCount(This,trackCount) \
+ (This)->lpVtbl -> put_TrackCount(This,trackCount)
+
+#define IITTrack_get_TrackNumber(This,trackNumber) \
+ (This)->lpVtbl -> get_TrackNumber(This,trackNumber)
+
+#define IITTrack_put_TrackNumber(This,trackNumber) \
+ (This)->lpVtbl -> put_TrackNumber(This,trackNumber)
+
+#define IITTrack_get_VolumeAdjustment(This,volumeAdjustment) \
+ (This)->lpVtbl -> get_VolumeAdjustment(This,volumeAdjustment)
+
+#define IITTrack_put_VolumeAdjustment(This,volumeAdjustment) \
+ (This)->lpVtbl -> put_VolumeAdjustment(This,volumeAdjustment)
+
+#define IITTrack_get_Year(This,year) \
+ (This)->lpVtbl -> get_Year(This,year)
+
+#define IITTrack_put_Year(This,year) \
+ (This)->lpVtbl -> put_Year(This,year)
+
+#define IITTrack_get_Artwork(This,iArtworkCollection) \
+ (This)->lpVtbl -> get_Artwork(This,iArtworkCollection)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITTrack_Delete_Proxy(
+ IITTrack __RPC_FAR * This);
+
+
+void __RPC_STUB IITTrack_Delete_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITTrack_Play_Proxy(
+ IITTrack __RPC_FAR * This);
+
+
+void __RPC_STUB IITTrack_Play_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITTrack_AddArtworkFromFile_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITArtwork __RPC_FAR *__RPC_FAR *iArtwork);
+
+
+void __RPC_STUB IITTrack_AddArtworkFromFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Kind_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ ITTrackKind __RPC_FAR *kind);
+
+
+void __RPC_STUB IITTrack_get_Kind_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Playlist_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+
+void __RPC_STUB IITTrack_get_Playlist_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Album_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *album);
+
+
+void __RPC_STUB IITTrack_get_Album_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_Album_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR album);
+
+
+void __RPC_STUB IITTrack_put_Album_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Artist_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *artist);
+
+
+void __RPC_STUB IITTrack_get_Artist_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_Artist_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR artist);
+
+
+void __RPC_STUB IITTrack_put_Artist_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_BitRate_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *bitrate);
+
+
+void __RPC_STUB IITTrack_get_BitRate_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_BPM_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *beatsPerMinute);
+
+
+void __RPC_STUB IITTrack_get_BPM_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_BPM_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long beatsPerMinute);
+
+
+void __RPC_STUB IITTrack_put_BPM_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Comment_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *comment);
+
+
+void __RPC_STUB IITTrack_get_Comment_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_Comment_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR comment);
+
+
+void __RPC_STUB IITTrack_put_Comment_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Compilation_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isCompilation);
+
+
+void __RPC_STUB IITTrack_get_Compilation_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_Compilation_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeCompilation);
+
+
+void __RPC_STUB IITTrack_put_Compilation_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Composer_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *composer);
+
+
+void __RPC_STUB IITTrack_get_Composer_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_Composer_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR composer);
+
+
+void __RPC_STUB IITTrack_put_Composer_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_DateAdded_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ DATE __RPC_FAR *dateAdded);
+
+
+void __RPC_STUB IITTrack_get_DateAdded_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_DiscCount_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *discCount);
+
+
+void __RPC_STUB IITTrack_get_DiscCount_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_DiscCount_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long discCount);
+
+
+void __RPC_STUB IITTrack_put_DiscCount_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_DiscNumber_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *discNumber);
+
+
+void __RPC_STUB IITTrack_get_DiscNumber_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_DiscNumber_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long discNumber);
+
+
+void __RPC_STUB IITTrack_put_DiscNumber_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Duration_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *duration);
+
+
+void __RPC_STUB IITTrack_get_Duration_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Enabled_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled);
+
+
+void __RPC_STUB IITTrack_get_Enabled_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_Enabled_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeEnabled);
+
+
+void __RPC_STUB IITTrack_put_Enabled_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_EQ_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *eq);
+
+
+void __RPC_STUB IITTrack_get_EQ_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_EQ_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR eq);
+
+
+void __RPC_STUB IITTrack_put_EQ_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_Finish_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long finish);
+
+
+void __RPC_STUB IITTrack_put_Finish_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Finish_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *finish);
+
+
+void __RPC_STUB IITTrack_get_Finish_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Genre_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *genre);
+
+
+void __RPC_STUB IITTrack_get_Genre_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_Genre_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR genre);
+
+
+void __RPC_STUB IITTrack_put_Genre_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Grouping_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *grouping);
+
+
+void __RPC_STUB IITTrack_get_Grouping_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_Grouping_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ BSTR grouping);
+
+
+void __RPC_STUB IITTrack_put_Grouping_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_KindAsString_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *kind);
+
+
+void __RPC_STUB IITTrack_get_KindAsString_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_ModificationDate_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ DATE __RPC_FAR *dateModified);
+
+
+void __RPC_STUB IITTrack_get_ModificationDate_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_PlayedCount_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playedCount);
+
+
+void __RPC_STUB IITTrack_get_PlayedCount_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_PlayedCount_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long playedCount);
+
+
+void __RPC_STUB IITTrack_put_PlayedCount_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_PlayedDate_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ DATE __RPC_FAR *playedDate);
+
+
+void __RPC_STUB IITTrack_get_PlayedDate_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_PlayedDate_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ DATE playedDate);
+
+
+void __RPC_STUB IITTrack_put_PlayedDate_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_PlayOrderIndex_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+
+void __RPC_STUB IITTrack_get_PlayOrderIndex_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Rating_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *rating);
+
+
+void __RPC_STUB IITTrack_get_Rating_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_Rating_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long rating);
+
+
+void __RPC_STUB IITTrack_put_Rating_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_SampleRate_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sampleRate);
+
+
+void __RPC_STUB IITTrack_get_SampleRate_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Size_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *size);
+
+
+void __RPC_STUB IITTrack_get_Size_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Start_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *start);
+
+
+void __RPC_STUB IITTrack_get_Start_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_Start_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long start);
+
+
+void __RPC_STUB IITTrack_put_Start_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Time_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *time);
+
+
+void __RPC_STUB IITTrack_get_Time_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_TrackCount_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackCount);
+
+
+void __RPC_STUB IITTrack_get_TrackCount_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_TrackCount_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long trackCount);
+
+
+void __RPC_STUB IITTrack_put_TrackCount_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_TrackNumber_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackNumber);
+
+
+void __RPC_STUB IITTrack_get_TrackNumber_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_TrackNumber_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long trackNumber);
+
+
+void __RPC_STUB IITTrack_put_TrackNumber_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_VolumeAdjustment_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *volumeAdjustment);
+
+
+void __RPC_STUB IITTrack_get_VolumeAdjustment_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_VolumeAdjustment_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long volumeAdjustment);
+
+
+void __RPC_STUB IITTrack_put_VolumeAdjustment_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Year_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *year);
+
+
+void __RPC_STUB IITTrack_get_Year_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITTrack_put_Year_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [in] */ long year);
+
+
+void __RPC_STUB IITTrack_put_Year_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrack_get_Artwork_Proxy(
+ IITTrack __RPC_FAR * This,
+ /* [retval][out] */ IITArtworkCollection __RPC_FAR *__RPC_FAR *iArtworkCollection);
+
+
+void __RPC_STUB IITTrack_get_Artwork_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITTrack_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITTrackCollection_INTERFACE_DEFINED__
+#define __IITTrackCollection_INTERFACE_DEFINED__
+
+/* interface IITTrackCollection */
+/* [unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITTrackCollection;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("755D76F1-6B85-4ce4-8F5F-F88D9743DCD8")
+ IITTrackCollection : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
+ /* [retval][out] */ long __RPC_FAR *count) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Item(
+ /* [in] */ long index,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iTrack) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ItemByPlayOrder(
+ /* [in] */ long index,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iTrack) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ItemByName(
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iTrack) = 0;
+
+ virtual /* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITTrackCollectionVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITTrackCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITTrackCollection __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITTrackCollection __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITTrackCollection __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITTrackCollection __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITTrackCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITTrackCollection __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Count )(
+ IITTrackCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Item )(
+ IITTrackCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iTrack);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ItemByPlayOrder )(
+ IITTrackCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iTrack);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ItemByName )(
+ IITTrackCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iTrack);
+
+ /* [helpstring][restricted][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get__NewEnum )(
+ IITTrackCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+ END_INTERFACE
+ } IITTrackCollectionVtbl;
+
+ interface IITTrackCollection
+ {
+ CONST_VTBL struct IITTrackCollectionVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITTrackCollection_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITTrackCollection_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITTrackCollection_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITTrackCollection_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITTrackCollection_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITTrackCollection_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITTrackCollection_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITTrackCollection_get_Count(This,count) \
+ (This)->lpVtbl -> get_Count(This,count)
+
+#define IITTrackCollection_get_Item(This,index,iTrack) \
+ (This)->lpVtbl -> get_Item(This,index,iTrack)
+
+#define IITTrackCollection_get_ItemByPlayOrder(This,index,iTrack) \
+ (This)->lpVtbl -> get_ItemByPlayOrder(This,index,iTrack)
+
+#define IITTrackCollection_get_ItemByName(This,name,iTrack) \
+ (This)->lpVtbl -> get_ItemByName(This,name,iTrack)
+
+#define IITTrackCollection_get__NewEnum(This,iEnumerator) \
+ (This)->lpVtbl -> get__NewEnum(This,iEnumerator)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrackCollection_get_Count_Proxy(
+ IITTrackCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+
+void __RPC_STUB IITTrackCollection_get_Count_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IITTrackCollection_get_Item_Proxy(
+ IITTrackCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iTrack);
+
+
+void __RPC_STUB IITTrackCollection_get_Item_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrackCollection_get_ItemByPlayOrder_Proxy(
+ IITTrackCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iTrack);
+
+
+void __RPC_STUB IITTrackCollection_get_ItemByPlayOrder_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITTrackCollection_get_ItemByName_Proxy(
+ IITTrackCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iTrack);
+
+
+void __RPC_STUB IITTrackCollection_get_ItemByName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE IITTrackCollection_get__NewEnum_Proxy(
+ IITTrackCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+
+void __RPC_STUB IITTrackCollection_get__NewEnum_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITTrackCollection_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITVisual_INTERFACE_DEFINED__
+#define __IITVisual_INTERFACE_DEFINED__
+
+/* interface IITVisual */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITVisual;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("340F3315-ED72-4c09-9ACF-21EB4BDF9931")
+ IITVisual : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Name(
+ /* [retval][out] */ BSTR __RPC_FAR *name) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITVisualVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITVisual __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITVisual __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITVisual __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITVisual __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITVisual __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITVisual __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITVisual __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITVisual __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ END_INTERFACE
+ } IITVisualVtbl;
+
+ interface IITVisual
+ {
+ CONST_VTBL struct IITVisualVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITVisual_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITVisual_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITVisual_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITVisual_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITVisual_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITVisual_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITVisual_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITVisual_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITVisual_get_Name_Proxy(
+ IITVisual __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+
+void __RPC_STUB IITVisual_get_Name_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITVisual_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITVisualCollection_INTERFACE_DEFINED__
+#define __IITVisualCollection_INTERFACE_DEFINED__
+
+/* interface IITVisualCollection */
+/* [unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITVisualCollection;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("88A4CCDD-114F-4043-B69B-84D4E6274957")
+ IITVisualCollection : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
+ /* [retval][out] */ long __RPC_FAR *count) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Item(
+ /* [in] */ long index,
+ /* [retval][out] */ IITVisual __RPC_FAR *__RPC_FAR *iVisual) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ItemByName(
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITVisual __RPC_FAR *__RPC_FAR *iVisual) = 0;
+
+ virtual /* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITVisualCollectionVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITVisualCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITVisualCollection __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITVisualCollection __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITVisualCollection __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITVisualCollection __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITVisualCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITVisualCollection __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Count )(
+ IITVisualCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Item )(
+ IITVisualCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITVisual __RPC_FAR *__RPC_FAR *iVisual);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ItemByName )(
+ IITVisualCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITVisual __RPC_FAR *__RPC_FAR *iVisual);
+
+ /* [helpstring][restricted][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get__NewEnum )(
+ IITVisualCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+ END_INTERFACE
+ } IITVisualCollectionVtbl;
+
+ interface IITVisualCollection
+ {
+ CONST_VTBL struct IITVisualCollectionVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITVisualCollection_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITVisualCollection_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITVisualCollection_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITVisualCollection_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITVisualCollection_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITVisualCollection_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITVisualCollection_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITVisualCollection_get_Count(This,count) \
+ (This)->lpVtbl -> get_Count(This,count)
+
+#define IITVisualCollection_get_Item(This,index,iVisual) \
+ (This)->lpVtbl -> get_Item(This,index,iVisual)
+
+#define IITVisualCollection_get_ItemByName(This,name,iVisual) \
+ (This)->lpVtbl -> get_ItemByName(This,name,iVisual)
+
+#define IITVisualCollection_get__NewEnum(This,iEnumerator) \
+ (This)->lpVtbl -> get__NewEnum(This,iEnumerator)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITVisualCollection_get_Count_Proxy(
+ IITVisualCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+
+void __RPC_STUB IITVisualCollection_get_Count_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IITVisualCollection_get_Item_Proxy(
+ IITVisualCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITVisual __RPC_FAR *__RPC_FAR *iVisual);
+
+
+void __RPC_STUB IITVisualCollection_get_Item_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITVisualCollection_get_ItemByName_Proxy(
+ IITVisualCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITVisual __RPC_FAR *__RPC_FAR *iVisual);
+
+
+void __RPC_STUB IITVisualCollection_get_ItemByName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE IITVisualCollection_get__NewEnum_Proxy(
+ IITVisualCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+
+void __RPC_STUB IITVisualCollection_get__NewEnum_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITVisualCollection_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITWindow_INTERFACE_DEFINED__
+#define __IITWindow_INTERFACE_DEFINED__
+
+/* interface IITWindow */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITWindow;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("370D7BE0-3A89-4a42-B902-C75FC138BE09")
+ IITWindow : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Name(
+ /* [retval][out] */ BSTR __RPC_FAR *name) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Kind(
+ /* [retval][out] */ ITWindowKind __RPC_FAR *kind) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Visible(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isVisible) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Visible(
+ /* [in] */ VARIANT_BOOL shouldBeVisible) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Resizable(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isResizable) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Minimized(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMinimized) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Minimized(
+ /* [in] */ VARIANT_BOOL shouldBeMinimized) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Maximizable(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMaximizable) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Maximized(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMaximized) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Maximized(
+ /* [in] */ VARIANT_BOOL shouldBeMaximized) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Zoomable(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isZoomable) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Zoomed(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isZoomed) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Zoomed(
+ /* [in] */ VARIANT_BOOL shouldBeZoomed) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Top(
+ /* [retval][out] */ long __RPC_FAR *top) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Top(
+ /* [in] */ long top) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Left(
+ /* [retval][out] */ long __RPC_FAR *left) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Left(
+ /* [in] */ long left) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Bottom(
+ /* [retval][out] */ long __RPC_FAR *bottom) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Bottom(
+ /* [in] */ long bottom) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Right(
+ /* [retval][out] */ long __RPC_FAR *right) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Right(
+ /* [in] */ long right) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Width(
+ /* [retval][out] */ long __RPC_FAR *width) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Width(
+ /* [in] */ long width) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Height(
+ /* [retval][out] */ long __RPC_FAR *height) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Height(
+ /* [in] */ long height) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITWindowVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITWindow __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITWindow __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITWindow __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Kind )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ ITWindowKind __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Visible )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isVisible);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Visible )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeVisible);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Resizable )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isResizable);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Minimized )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMinimized);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Minimized )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeMinimized);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Maximizable )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMaximizable);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Maximized )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMaximized);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Maximized )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeMaximized);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Zoomable )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isZoomable);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Zoomed )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isZoomed);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Zoomed )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeZoomed);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Top )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *top);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Top )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ long top);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Left )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *left);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Left )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ long left);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Bottom )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *bottom);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Bottom )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ long bottom);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Right )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *right);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Right )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ long right);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Width )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *width);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Width )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ long width);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Height )(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *height);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Height )(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ long height);
+
+ END_INTERFACE
+ } IITWindowVtbl;
+
+ interface IITWindow
+ {
+ CONST_VTBL struct IITWindowVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITWindow_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITWindow_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITWindow_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITWindow_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITWindow_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITWindow_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITWindow_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITWindow_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITWindow_get_Kind(This,kind) \
+ (This)->lpVtbl -> get_Kind(This,kind)
+
+#define IITWindow_get_Visible(This,isVisible) \
+ (This)->lpVtbl -> get_Visible(This,isVisible)
+
+#define IITWindow_put_Visible(This,shouldBeVisible) \
+ (This)->lpVtbl -> put_Visible(This,shouldBeVisible)
+
+#define IITWindow_get_Resizable(This,isResizable) \
+ (This)->lpVtbl -> get_Resizable(This,isResizable)
+
+#define IITWindow_get_Minimized(This,isMinimized) \
+ (This)->lpVtbl -> get_Minimized(This,isMinimized)
+
+#define IITWindow_put_Minimized(This,shouldBeMinimized) \
+ (This)->lpVtbl -> put_Minimized(This,shouldBeMinimized)
+
+#define IITWindow_get_Maximizable(This,isMaximizable) \
+ (This)->lpVtbl -> get_Maximizable(This,isMaximizable)
+
+#define IITWindow_get_Maximized(This,isMaximized) \
+ (This)->lpVtbl -> get_Maximized(This,isMaximized)
+
+#define IITWindow_put_Maximized(This,shouldBeMaximized) \
+ (This)->lpVtbl -> put_Maximized(This,shouldBeMaximized)
+
+#define IITWindow_get_Zoomable(This,isZoomable) \
+ (This)->lpVtbl -> get_Zoomable(This,isZoomable)
+
+#define IITWindow_get_Zoomed(This,isZoomed) \
+ (This)->lpVtbl -> get_Zoomed(This,isZoomed)
+
+#define IITWindow_put_Zoomed(This,shouldBeZoomed) \
+ (This)->lpVtbl -> put_Zoomed(This,shouldBeZoomed)
+
+#define IITWindow_get_Top(This,top) \
+ (This)->lpVtbl -> get_Top(This,top)
+
+#define IITWindow_put_Top(This,top) \
+ (This)->lpVtbl -> put_Top(This,top)
+
+#define IITWindow_get_Left(This,left) \
+ (This)->lpVtbl -> get_Left(This,left)
+
+#define IITWindow_put_Left(This,left) \
+ (This)->lpVtbl -> put_Left(This,left)
+
+#define IITWindow_get_Bottom(This,bottom) \
+ (This)->lpVtbl -> get_Bottom(This,bottom)
+
+#define IITWindow_put_Bottom(This,bottom) \
+ (This)->lpVtbl -> put_Bottom(This,bottom)
+
+#define IITWindow_get_Right(This,right) \
+ (This)->lpVtbl -> get_Right(This,right)
+
+#define IITWindow_put_Right(This,right) \
+ (This)->lpVtbl -> put_Right(This,right)
+
+#define IITWindow_get_Width(This,width) \
+ (This)->lpVtbl -> get_Width(This,width)
+
+#define IITWindow_put_Width(This,width) \
+ (This)->lpVtbl -> put_Width(This,width)
+
+#define IITWindow_get_Height(This,height) \
+ (This)->lpVtbl -> get_Height(This,height)
+
+#define IITWindow_put_Height(This,height) \
+ (This)->lpVtbl -> put_Height(This,height)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Name_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+
+void __RPC_STUB IITWindow_get_Name_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Kind_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ ITWindowKind __RPC_FAR *kind);
+
+
+void __RPC_STUB IITWindow_get_Kind_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Visible_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isVisible);
+
+
+void __RPC_STUB IITWindow_get_Visible_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITWindow_put_Visible_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeVisible);
+
+
+void __RPC_STUB IITWindow_put_Visible_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Resizable_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isResizable);
+
+
+void __RPC_STUB IITWindow_get_Resizable_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Minimized_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMinimized);
+
+
+void __RPC_STUB IITWindow_get_Minimized_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITWindow_put_Minimized_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeMinimized);
+
+
+void __RPC_STUB IITWindow_put_Minimized_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Maximizable_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMaximizable);
+
+
+void __RPC_STUB IITWindow_get_Maximizable_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Maximized_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMaximized);
+
+
+void __RPC_STUB IITWindow_get_Maximized_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITWindow_put_Maximized_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeMaximized);
+
+
+void __RPC_STUB IITWindow_put_Maximized_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Zoomable_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isZoomable);
+
+
+void __RPC_STUB IITWindow_get_Zoomable_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Zoomed_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isZoomed);
+
+
+void __RPC_STUB IITWindow_get_Zoomed_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITWindow_put_Zoomed_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeZoomed);
+
+
+void __RPC_STUB IITWindow_put_Zoomed_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Top_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *top);
+
+
+void __RPC_STUB IITWindow_get_Top_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITWindow_put_Top_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ long top);
+
+
+void __RPC_STUB IITWindow_put_Top_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Left_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *left);
+
+
+void __RPC_STUB IITWindow_get_Left_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITWindow_put_Left_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ long left);
+
+
+void __RPC_STUB IITWindow_put_Left_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Bottom_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *bottom);
+
+
+void __RPC_STUB IITWindow_get_Bottom_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITWindow_put_Bottom_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ long bottom);
+
+
+void __RPC_STUB IITWindow_put_Bottom_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Right_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *right);
+
+
+void __RPC_STUB IITWindow_get_Right_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITWindow_put_Right_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ long right);
+
+
+void __RPC_STUB IITWindow_put_Right_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Width_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *width);
+
+
+void __RPC_STUB IITWindow_get_Width_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITWindow_put_Width_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ long width);
+
+
+void __RPC_STUB IITWindow_put_Width_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindow_get_Height_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *height);
+
+
+void __RPC_STUB IITWindow_get_Height_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITWindow_put_Height_Proxy(
+ IITWindow __RPC_FAR * This,
+ /* [in] */ long height);
+
+
+void __RPC_STUB IITWindow_put_Height_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITWindow_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITBrowserWindow_INTERFACE_DEFINED__
+#define __IITBrowserWindow_INTERFACE_DEFINED__
+
+/* interface IITBrowserWindow */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITBrowserWindow;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("C999F455-C4D5-4aa4-8277-F99753699974")
+ IITBrowserWindow : public IITWindow
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_MiniPlayer(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMiniPlayer) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_MiniPlayer(
+ /* [in] */ VARIANT_BOOL shouldBeMiniPlayer) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_SelectedTracks(
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_SelectedPlaylist(
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_SelectedPlaylist(
+ /* [in] */ VARIANT __RPC_FAR *iPlaylist) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITBrowserWindowVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITBrowserWindow __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITBrowserWindow __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Kind )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ ITWindowKind __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Visible )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isVisible);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Visible )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeVisible);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Resizable )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isResizable);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Minimized )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMinimized);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Minimized )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeMinimized);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Maximizable )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMaximizable);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Maximized )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMaximized);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Maximized )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeMaximized);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Zoomable )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isZoomable);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Zoomed )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isZoomed);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Zoomed )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeZoomed);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Top )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *top);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Top )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ long top);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Left )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *left);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Left )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ long left);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Bottom )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *bottom);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Bottom )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ long bottom);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Right )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *right);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Right )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ long right);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Width )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *width);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Width )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ long width);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Height )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *height);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Height )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ long height);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_MiniPlayer )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMiniPlayer);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_MiniPlayer )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeMiniPlayer);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SelectedTracks )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SelectedPlaylist )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_SelectedPlaylist )(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iPlaylist);
+
+ END_INTERFACE
+ } IITBrowserWindowVtbl;
+
+ interface IITBrowserWindow
+ {
+ CONST_VTBL struct IITBrowserWindowVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITBrowserWindow_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITBrowserWindow_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITBrowserWindow_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITBrowserWindow_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITBrowserWindow_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITBrowserWindow_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITBrowserWindow_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITBrowserWindow_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITBrowserWindow_get_Kind(This,kind) \
+ (This)->lpVtbl -> get_Kind(This,kind)
+
+#define IITBrowserWindow_get_Visible(This,isVisible) \
+ (This)->lpVtbl -> get_Visible(This,isVisible)
+
+#define IITBrowserWindow_put_Visible(This,shouldBeVisible) \
+ (This)->lpVtbl -> put_Visible(This,shouldBeVisible)
+
+#define IITBrowserWindow_get_Resizable(This,isResizable) \
+ (This)->lpVtbl -> get_Resizable(This,isResizable)
+
+#define IITBrowserWindow_get_Minimized(This,isMinimized) \
+ (This)->lpVtbl -> get_Minimized(This,isMinimized)
+
+#define IITBrowserWindow_put_Minimized(This,shouldBeMinimized) \
+ (This)->lpVtbl -> put_Minimized(This,shouldBeMinimized)
+
+#define IITBrowserWindow_get_Maximizable(This,isMaximizable) \
+ (This)->lpVtbl -> get_Maximizable(This,isMaximizable)
+
+#define IITBrowserWindow_get_Maximized(This,isMaximized) \
+ (This)->lpVtbl -> get_Maximized(This,isMaximized)
+
+#define IITBrowserWindow_put_Maximized(This,shouldBeMaximized) \
+ (This)->lpVtbl -> put_Maximized(This,shouldBeMaximized)
+
+#define IITBrowserWindow_get_Zoomable(This,isZoomable) \
+ (This)->lpVtbl -> get_Zoomable(This,isZoomable)
+
+#define IITBrowserWindow_get_Zoomed(This,isZoomed) \
+ (This)->lpVtbl -> get_Zoomed(This,isZoomed)
+
+#define IITBrowserWindow_put_Zoomed(This,shouldBeZoomed) \
+ (This)->lpVtbl -> put_Zoomed(This,shouldBeZoomed)
+
+#define IITBrowserWindow_get_Top(This,top) \
+ (This)->lpVtbl -> get_Top(This,top)
+
+#define IITBrowserWindow_put_Top(This,top) \
+ (This)->lpVtbl -> put_Top(This,top)
+
+#define IITBrowserWindow_get_Left(This,left) \
+ (This)->lpVtbl -> get_Left(This,left)
+
+#define IITBrowserWindow_put_Left(This,left) \
+ (This)->lpVtbl -> put_Left(This,left)
+
+#define IITBrowserWindow_get_Bottom(This,bottom) \
+ (This)->lpVtbl -> get_Bottom(This,bottom)
+
+#define IITBrowserWindow_put_Bottom(This,bottom) \
+ (This)->lpVtbl -> put_Bottom(This,bottom)
+
+#define IITBrowserWindow_get_Right(This,right) \
+ (This)->lpVtbl -> get_Right(This,right)
+
+#define IITBrowserWindow_put_Right(This,right) \
+ (This)->lpVtbl -> put_Right(This,right)
+
+#define IITBrowserWindow_get_Width(This,width) \
+ (This)->lpVtbl -> get_Width(This,width)
+
+#define IITBrowserWindow_put_Width(This,width) \
+ (This)->lpVtbl -> put_Width(This,width)
+
+#define IITBrowserWindow_get_Height(This,height) \
+ (This)->lpVtbl -> get_Height(This,height)
+
+#define IITBrowserWindow_put_Height(This,height) \
+ (This)->lpVtbl -> put_Height(This,height)
+
+
+#define IITBrowserWindow_get_MiniPlayer(This,isMiniPlayer) \
+ (This)->lpVtbl -> get_MiniPlayer(This,isMiniPlayer)
+
+#define IITBrowserWindow_put_MiniPlayer(This,shouldBeMiniPlayer) \
+ (This)->lpVtbl -> put_MiniPlayer(This,shouldBeMiniPlayer)
+
+#define IITBrowserWindow_get_SelectedTracks(This,iTrackCollection) \
+ (This)->lpVtbl -> get_SelectedTracks(This,iTrackCollection)
+
+#define IITBrowserWindow_get_SelectedPlaylist(This,iPlaylist) \
+ (This)->lpVtbl -> get_SelectedPlaylist(This,iPlaylist)
+
+#define IITBrowserWindow_put_SelectedPlaylist(This,iPlaylist) \
+ (This)->lpVtbl -> put_SelectedPlaylist(This,iPlaylist)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITBrowserWindow_get_MiniPlayer_Proxy(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMiniPlayer);
+
+
+void __RPC_STUB IITBrowserWindow_get_MiniPlayer_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITBrowserWindow_put_MiniPlayer_Proxy(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeMiniPlayer);
+
+
+void __RPC_STUB IITBrowserWindow_put_MiniPlayer_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITBrowserWindow_get_SelectedTracks_Proxy(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+
+void __RPC_STUB IITBrowserWindow_get_SelectedTracks_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITBrowserWindow_get_SelectedPlaylist_Proxy(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+
+void __RPC_STUB IITBrowserWindow_get_SelectedPlaylist_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITBrowserWindow_put_SelectedPlaylist_Proxy(
+ IITBrowserWindow __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iPlaylist);
+
+
+void __RPC_STUB IITBrowserWindow_put_SelectedPlaylist_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITBrowserWindow_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITWindowCollection_INTERFACE_DEFINED__
+#define __IITWindowCollection_INTERFACE_DEFINED__
+
+/* interface IITWindowCollection */
+/* [unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITWindowCollection;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("3D8DE381-6C0E-481f-A865-E2385F59FA43")
+ IITWindowCollection : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
+ /* [retval][out] */ long __RPC_FAR *count) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Item(
+ /* [in] */ long index,
+ /* [retval][out] */ IITWindow __RPC_FAR *__RPC_FAR *iWindow) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ItemByName(
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITWindow __RPC_FAR *__RPC_FAR *iWindow) = 0;
+
+ virtual /* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITWindowCollectionVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITWindowCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITWindowCollection __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITWindowCollection __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITWindowCollection __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITWindowCollection __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITWindowCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITWindowCollection __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Count )(
+ IITWindowCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Item )(
+ IITWindowCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITWindow __RPC_FAR *__RPC_FAR *iWindow);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ItemByName )(
+ IITWindowCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITWindow __RPC_FAR *__RPC_FAR *iWindow);
+
+ /* [helpstring][restricted][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get__NewEnum )(
+ IITWindowCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+ END_INTERFACE
+ } IITWindowCollectionVtbl;
+
+ interface IITWindowCollection
+ {
+ CONST_VTBL struct IITWindowCollectionVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITWindowCollection_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITWindowCollection_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITWindowCollection_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITWindowCollection_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITWindowCollection_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITWindowCollection_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITWindowCollection_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITWindowCollection_get_Count(This,count) \
+ (This)->lpVtbl -> get_Count(This,count)
+
+#define IITWindowCollection_get_Item(This,index,iWindow) \
+ (This)->lpVtbl -> get_Item(This,index,iWindow)
+
+#define IITWindowCollection_get_ItemByName(This,name,iWindow) \
+ (This)->lpVtbl -> get_ItemByName(This,name,iWindow)
+
+#define IITWindowCollection_get__NewEnum(This,iEnumerator) \
+ (This)->lpVtbl -> get__NewEnum(This,iEnumerator)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindowCollection_get_Count_Proxy(
+ IITWindowCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+
+void __RPC_STUB IITWindowCollection_get_Count_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IITWindowCollection_get_Item_Proxy(
+ IITWindowCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITWindow __RPC_FAR *__RPC_FAR *iWindow);
+
+
+void __RPC_STUB IITWindowCollection_get_Item_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITWindowCollection_get_ItemByName_Proxy(
+ IITWindowCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITWindow __RPC_FAR *__RPC_FAR *iWindow);
+
+
+void __RPC_STUB IITWindowCollection_get_ItemByName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE IITWindowCollection_get__NewEnum_Proxy(
+ IITWindowCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+
+void __RPC_STUB IITWindowCollection_get__NewEnum_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITWindowCollection_INTERFACE_DEFINED__ */
+
+
+#ifndef __IiTunes_INTERFACE_DEFINED__
+#define __IiTunes_INTERFACE_DEFINED__
+
+/* interface IiTunes */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+
+
+EXTERN_C const IID IID_IiTunes;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("9DD6680B-3EDC-40db-A771-E6FE4832E34A")
+ IiTunes : public IDispatch
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE BackTrack( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE FastForward( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE NextTrack( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Pause( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Play( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE PlayFile(
+ /* [in] */ BSTR filePath) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE PlayPause( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE PreviousTrack( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Resume( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Rewind( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Stop( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ConvertFile(
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ConvertFiles(
+ /* [in] */ VARIANT __RPC_FAR *filePaths,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ConvertTrack(
+ /* [in] */ VARIANT __RPC_FAR *iTrackToConvert,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ConvertTracks(
+ /* [in] */ VARIANT __RPC_FAR *iTracksToConvert,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CheckVersion(
+ /* [in] */ long majorVersion,
+ /* [in] */ long minorVersion,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isCompatible) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetITObjectByID(
+ /* [in] */ long sourceID,
+ /* [in] */ long playlistID,
+ /* [in] */ long trackID,
+ /* [in] */ long databaseID,
+ /* [retval][out] */ IITObject __RPC_FAR *__RPC_FAR *iObject) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CreatePlaylist(
+ /* [in] */ BSTR playlistName,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE OpenURL(
+ /* [in] */ BSTR url) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GotoMusicStoreHomePage( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UpdateIPod( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Authorize(
+ /* [in] */ long numElems,
+ /* [size_is][in] */ VARIANT __RPC_FAR data[ ],
+ /* [size_is][in] */ BSTR __RPC_FAR names[ ]) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Quit( void) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Sources(
+ /* [retval][out] */ IITSourceCollection __RPC_FAR *__RPC_FAR *iSourceCollection) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Encoders(
+ /* [retval][out] */ IITEncoderCollection __RPC_FAR *__RPC_FAR *iEncoderCollection) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_EQPresets(
+ /* [retval][out] */ IITEQPresetCollection __RPC_FAR *__RPC_FAR *iEQPresetCollection) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Visuals(
+ /* [retval][out] */ IITVisualCollection __RPC_FAR *__RPC_FAR *iVisualCollection) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Windows(
+ /* [retval][out] */ IITWindowCollection __RPC_FAR *__RPC_FAR *iWindowCollection) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_SoundVolume(
+ /* [retval][out] */ long __RPC_FAR *volume) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_SoundVolume(
+ /* [in] */ long volume) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Mute(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMuted) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Mute(
+ /* [in] */ VARIANT_BOOL shouldMute) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_PlayerState(
+ /* [retval][out] */ ITPlayerState __RPC_FAR *playerState) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_PlayerPosition(
+ /* [retval][out] */ long __RPC_FAR *playerPos) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_PlayerPosition(
+ /* [in] */ long playerPos) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_CurrentEncoder(
+ /* [retval][out] */ IITEncoder __RPC_FAR *__RPC_FAR *iEncoder) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_CurrentEncoder(
+ /* [in] */ IITEncoder __RPC_FAR *iEncoder) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_VisualsEnabled(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_VisualsEnabled(
+ /* [in] */ VARIANT_BOOL shouldEnable) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_FullScreenVisuals(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isFullScreen) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_FullScreenVisuals(
+ /* [in] */ VARIANT_BOOL shouldUseFullScreen) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_VisualSize(
+ /* [retval][out] */ ITVisualSize __RPC_FAR *visualSize) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_VisualSize(
+ /* [in] */ ITVisualSize visualSize) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_CurrentVisual(
+ /* [retval][out] */ IITVisual __RPC_FAR *__RPC_FAR *iVisual) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_CurrentVisual(
+ /* [in] */ IITVisual __RPC_FAR *iVisual) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_EQEnabled(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_EQEnabled(
+ /* [in] */ VARIANT_BOOL shouldEnable) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_CurrentEQPreset(
+ /* [retval][out] */ IITEQPreset __RPC_FAR *__RPC_FAR *iEQPreset) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_CurrentEQPreset(
+ /* [in] */ IITEQPreset __RPC_FAR *iEQPreset) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_CurrentStreamTitle(
+ /* [retval][out] */ BSTR __RPC_FAR *streamTitle) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_CurrentStreamURL(
+ /* [retval][out] */ BSTR __RPC_FAR *streamURL) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_BrowserWindow(
+ /* [retval][out] */ IITBrowserWindow __RPC_FAR *__RPC_FAR *iBrowserWindow) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_EQWindow(
+ /* [retval][out] */ IITWindow __RPC_FAR *__RPC_FAR *iEQWindow) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_LibrarySource(
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iLibrarySource) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_LibraryPlaylist(
+ /* [retval][out] */ IITLibraryPlaylist __RPC_FAR *__RPC_FAR *iLibraryPlaylist) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_CurrentTrack(
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iTrack) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_CurrentPlaylist(
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_SelectedTracks(
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Version(
+ /* [retval][out] */ BSTR __RPC_FAR *version) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetOptions(
+ /* [in] */ long options) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ConvertFile2(
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ConvertFiles2(
+ /* [in] */ VARIANT __RPC_FAR *filePaths,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ConvertTrack2(
+ /* [in] */ VARIANT __RPC_FAR *iTrackToConvert,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ConvertTracks2(
+ /* [in] */ VARIANT __RPC_FAR *iTracksToConvert,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_AppCommandMessageProcessingEnabled(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_AppCommandMessageProcessingEnabled(
+ /* [in] */ VARIANT_BOOL shouldEnable) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ForceToForegroundOnDialog(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *forceToForegroundOnDialog) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_ForceToForegroundOnDialog(
+ /* [in] */ VARIANT_BOOL forceToForegroundOnDialog) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CreateEQPreset(
+ /* [in] */ BSTR eqPresetName,
+ /* [retval][out] */ IITEQPreset __RPC_FAR *__RPC_FAR *iEQPreset) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CreatePlaylistInSource(
+ /* [in] */ BSTR playlistName,
+ /* [in] */ VARIANT __RPC_FAR *iSource,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetPlayerButtonsState(
+ /* [out] */ VARIANT_BOOL __RPC_FAR *previousEnabled,
+ /* [out] */ ITPlayButtonState __RPC_FAR *playPauseStopState,
+ /* [out] */ VARIANT_BOOL __RPC_FAR *nextEnabled) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE PlayerButtonClicked(
+ /* [in] */ ITPlayerButton playerButton,
+ /* [in] */ long playerButtonModifierKeys) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_CanSetShuffle(
+ /* [in] */ VARIANT __RPC_FAR *iPlaylist,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *canSetShuffle) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_CanSetSongRepeat(
+ /* [in] */ VARIANT __RPC_FAR *iPlaylist,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *canSetSongRepeat) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ConvertOperationStatus(
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SubscribeToPodcast(
+ /* [in] */ BSTR url) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UpdatePodcastFeeds( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CreateFolder(
+ /* [in] */ BSTR folderName,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iFolder) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CreateFolderInSource(
+ /* [in] */ BSTR folderName,
+ /* [in] */ VARIANT __RPC_FAR *iSource,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iFolder) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_SoundVolumeControlEnabled(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IiTunesVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IiTunes __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IiTunes __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IiTunes __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *BackTrack )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *FastForward )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *NextTrack )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Pause )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Play )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *PlayFile )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR filePath);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *PlayPause )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *PreviousTrack )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Resume )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Rewind )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Stop )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ConvertFile )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ConvertFiles )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *filePaths,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ConvertTrack )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iTrackToConvert,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ConvertTracks )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iTracksToConvert,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CheckVersion )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ long majorVersion,
+ /* [in] */ long minorVersion,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isCompatible);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetITObjectByID )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ long sourceID,
+ /* [in] */ long playlistID,
+ /* [in] */ long trackID,
+ /* [in] */ long databaseID,
+ /* [retval][out] */ IITObject __RPC_FAR *__RPC_FAR *iObject);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CreatePlaylist )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR playlistName,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *OpenURL )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR url);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GotoMusicStoreHomePage )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *UpdateIPod )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Authorize )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ long numElems,
+ /* [size_is][in] */ VARIANT __RPC_FAR data[ ],
+ /* [size_is][in] */ BSTR __RPC_FAR names[ ]);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Quit )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Sources )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITSourceCollection __RPC_FAR *__RPC_FAR *iSourceCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Encoders )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITEncoderCollection __RPC_FAR *__RPC_FAR *iEncoderCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_EQPresets )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITEQPresetCollection __RPC_FAR *__RPC_FAR *iEQPresetCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Visuals )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITVisualCollection __RPC_FAR *__RPC_FAR *iVisualCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Windows )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITWindowCollection __RPC_FAR *__RPC_FAR *iWindowCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SoundVolume )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *volume);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_SoundVolume )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ long volume);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Mute )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMuted);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Mute )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldMute);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlayerState )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ ITPlayerState __RPC_FAR *playerState);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlayerPosition )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playerPos);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_PlayerPosition )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ long playerPos);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_CurrentEncoder )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITEncoder __RPC_FAR *__RPC_FAR *iEncoder);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_CurrentEncoder )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ IITEncoder __RPC_FAR *iEncoder);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_VisualsEnabled )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_VisualsEnabled )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldEnable);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_FullScreenVisuals )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isFullScreen);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_FullScreenVisuals )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldUseFullScreen);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_VisualSize )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ ITVisualSize __RPC_FAR *visualSize);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_VisualSize )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ ITVisualSize visualSize);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_CurrentVisual )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITVisual __RPC_FAR *__RPC_FAR *iVisual);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_CurrentVisual )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ IITVisual __RPC_FAR *iVisual);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_EQEnabled )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_EQEnabled )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldEnable);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_CurrentEQPreset )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITEQPreset __RPC_FAR *__RPC_FAR *iEQPreset);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_CurrentEQPreset )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ IITEQPreset __RPC_FAR *iEQPreset);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_CurrentStreamTitle )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *streamTitle);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_CurrentStreamURL )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *streamURL);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_BrowserWindow )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITBrowserWindow __RPC_FAR *__RPC_FAR *iBrowserWindow);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_EQWindow )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITWindow __RPC_FAR *__RPC_FAR *iEQWindow);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_LibrarySource )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iLibrarySource);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_LibraryPlaylist )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITLibraryPlaylist __RPC_FAR *__RPC_FAR *iLibraryPlaylist);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_CurrentTrack )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iTrack);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_CurrentPlaylist )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SelectedTracks )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Version )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *version);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SetOptions )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ long options);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ConvertFile2 )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ConvertFiles2 )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *filePaths,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ConvertTrack2 )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iTrackToConvert,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ConvertTracks2 )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iTracksToConvert,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_AppCommandMessageProcessingEnabled )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_AppCommandMessageProcessingEnabled )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldEnable);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ForceToForegroundOnDialog )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *forceToForegroundOnDialog);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_ForceToForegroundOnDialog )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL forceToForegroundOnDialog);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CreateEQPreset )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR eqPresetName,
+ /* [retval][out] */ IITEQPreset __RPC_FAR *__RPC_FAR *iEQPreset);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CreatePlaylistInSource )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR playlistName,
+ /* [in] */ VARIANT __RPC_FAR *iSource,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetPlayerButtonsState )(
+ IiTunes __RPC_FAR * This,
+ /* [out] */ VARIANT_BOOL __RPC_FAR *previousEnabled,
+ /* [out] */ ITPlayButtonState __RPC_FAR *playPauseStopState,
+ /* [out] */ VARIANT_BOOL __RPC_FAR *nextEnabled);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *PlayerButtonClicked )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ ITPlayerButton playerButton,
+ /* [in] */ long playerButtonModifierKeys);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_CanSetShuffle )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iPlaylist,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *canSetShuffle);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_CanSetSongRepeat )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iPlaylist,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *canSetSongRepeat);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ConvertOperationStatus )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SubscribeToPodcast )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR url);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *UpdatePodcastFeeds )(
+ IiTunes __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CreateFolder )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR folderName,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iFolder);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CreateFolderInSource )(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR folderName,
+ /* [in] */ VARIANT __RPC_FAR *iSource,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iFolder);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SoundVolumeControlEnabled )(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled);
+
+ END_INTERFACE
+ } IiTunesVtbl;
+
+ interface IiTunes
+ {
+ CONST_VTBL struct IiTunesVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IiTunes_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IiTunes_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IiTunes_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IiTunes_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IiTunes_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IiTunes_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IiTunes_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IiTunes_BackTrack(This) \
+ (This)->lpVtbl -> BackTrack(This)
+
+#define IiTunes_FastForward(This) \
+ (This)->lpVtbl -> FastForward(This)
+
+#define IiTunes_NextTrack(This) \
+ (This)->lpVtbl -> NextTrack(This)
+
+#define IiTunes_Pause(This) \
+ (This)->lpVtbl -> Pause(This)
+
+#define IiTunes_Play(This) \
+ (This)->lpVtbl -> Play(This)
+
+#define IiTunes_PlayFile(This,filePath) \
+ (This)->lpVtbl -> PlayFile(This,filePath)
+
+#define IiTunes_PlayPause(This) \
+ (This)->lpVtbl -> PlayPause(This)
+
+#define IiTunes_PreviousTrack(This) \
+ (This)->lpVtbl -> PreviousTrack(This)
+
+#define IiTunes_Resume(This) \
+ (This)->lpVtbl -> Resume(This)
+
+#define IiTunes_Rewind(This) \
+ (This)->lpVtbl -> Rewind(This)
+
+#define IiTunes_Stop(This) \
+ (This)->lpVtbl -> Stop(This)
+
+#define IiTunes_ConvertFile(This,filePath,iStatus) \
+ (This)->lpVtbl -> ConvertFile(This,filePath,iStatus)
+
+#define IiTunes_ConvertFiles(This,filePaths,iStatus) \
+ (This)->lpVtbl -> ConvertFiles(This,filePaths,iStatus)
+
+#define IiTunes_ConvertTrack(This,iTrackToConvert,iStatus) \
+ (This)->lpVtbl -> ConvertTrack(This,iTrackToConvert,iStatus)
+
+#define IiTunes_ConvertTracks(This,iTracksToConvert,iStatus) \
+ (This)->lpVtbl -> ConvertTracks(This,iTracksToConvert,iStatus)
+
+#define IiTunes_CheckVersion(This,majorVersion,minorVersion,isCompatible) \
+ (This)->lpVtbl -> CheckVersion(This,majorVersion,minorVersion,isCompatible)
+
+#define IiTunes_GetITObjectByID(This,sourceID,playlistID,trackID,databaseID,iObject) \
+ (This)->lpVtbl -> GetITObjectByID(This,sourceID,playlistID,trackID,databaseID,iObject)
+
+#define IiTunes_CreatePlaylist(This,playlistName,iPlaylist) \
+ (This)->lpVtbl -> CreatePlaylist(This,playlistName,iPlaylist)
+
+#define IiTunes_OpenURL(This,url) \
+ (This)->lpVtbl -> OpenURL(This,url)
+
+#define IiTunes_GotoMusicStoreHomePage(This) \
+ (This)->lpVtbl -> GotoMusicStoreHomePage(This)
+
+#define IiTunes_UpdateIPod(This) \
+ (This)->lpVtbl -> UpdateIPod(This)
+
+#define IiTunes_Authorize(This,numElems,data,names) \
+ (This)->lpVtbl -> Authorize(This,numElems,data,names)
+
+#define IiTunes_Quit(This) \
+ (This)->lpVtbl -> Quit(This)
+
+#define IiTunes_get_Sources(This,iSourceCollection) \
+ (This)->lpVtbl -> get_Sources(This,iSourceCollection)
+
+#define IiTunes_get_Encoders(This,iEncoderCollection) \
+ (This)->lpVtbl -> get_Encoders(This,iEncoderCollection)
+
+#define IiTunes_get_EQPresets(This,iEQPresetCollection) \
+ (This)->lpVtbl -> get_EQPresets(This,iEQPresetCollection)
+
+#define IiTunes_get_Visuals(This,iVisualCollection) \
+ (This)->lpVtbl -> get_Visuals(This,iVisualCollection)
+
+#define IiTunes_get_Windows(This,iWindowCollection) \
+ (This)->lpVtbl -> get_Windows(This,iWindowCollection)
+
+#define IiTunes_get_SoundVolume(This,volume) \
+ (This)->lpVtbl -> get_SoundVolume(This,volume)
+
+#define IiTunes_put_SoundVolume(This,volume) \
+ (This)->lpVtbl -> put_SoundVolume(This,volume)
+
+#define IiTunes_get_Mute(This,isMuted) \
+ (This)->lpVtbl -> get_Mute(This,isMuted)
+
+#define IiTunes_put_Mute(This,shouldMute) \
+ (This)->lpVtbl -> put_Mute(This,shouldMute)
+
+#define IiTunes_get_PlayerState(This,playerState) \
+ (This)->lpVtbl -> get_PlayerState(This,playerState)
+
+#define IiTunes_get_PlayerPosition(This,playerPos) \
+ (This)->lpVtbl -> get_PlayerPosition(This,playerPos)
+
+#define IiTunes_put_PlayerPosition(This,playerPos) \
+ (This)->lpVtbl -> put_PlayerPosition(This,playerPos)
+
+#define IiTunes_get_CurrentEncoder(This,iEncoder) \
+ (This)->lpVtbl -> get_CurrentEncoder(This,iEncoder)
+
+#define IiTunes_put_CurrentEncoder(This,iEncoder) \
+ (This)->lpVtbl -> put_CurrentEncoder(This,iEncoder)
+
+#define IiTunes_get_VisualsEnabled(This,isEnabled) \
+ (This)->lpVtbl -> get_VisualsEnabled(This,isEnabled)
+
+#define IiTunes_put_VisualsEnabled(This,shouldEnable) \
+ (This)->lpVtbl -> put_VisualsEnabled(This,shouldEnable)
+
+#define IiTunes_get_FullScreenVisuals(This,isFullScreen) \
+ (This)->lpVtbl -> get_FullScreenVisuals(This,isFullScreen)
+
+#define IiTunes_put_FullScreenVisuals(This,shouldUseFullScreen) \
+ (This)->lpVtbl -> put_FullScreenVisuals(This,shouldUseFullScreen)
+
+#define IiTunes_get_VisualSize(This,visualSize) \
+ (This)->lpVtbl -> get_VisualSize(This,visualSize)
+
+#define IiTunes_put_VisualSize(This,visualSize) \
+ (This)->lpVtbl -> put_VisualSize(This,visualSize)
+
+#define IiTunes_get_CurrentVisual(This,iVisual) \
+ (This)->lpVtbl -> get_CurrentVisual(This,iVisual)
+
+#define IiTunes_put_CurrentVisual(This,iVisual) \
+ (This)->lpVtbl -> put_CurrentVisual(This,iVisual)
+
+#define IiTunes_get_EQEnabled(This,isEnabled) \
+ (This)->lpVtbl -> get_EQEnabled(This,isEnabled)
+
+#define IiTunes_put_EQEnabled(This,shouldEnable) \
+ (This)->lpVtbl -> put_EQEnabled(This,shouldEnable)
+
+#define IiTunes_get_CurrentEQPreset(This,iEQPreset) \
+ (This)->lpVtbl -> get_CurrentEQPreset(This,iEQPreset)
+
+#define IiTunes_put_CurrentEQPreset(This,iEQPreset) \
+ (This)->lpVtbl -> put_CurrentEQPreset(This,iEQPreset)
+
+#define IiTunes_get_CurrentStreamTitle(This,streamTitle) \
+ (This)->lpVtbl -> get_CurrentStreamTitle(This,streamTitle)
+
+#define IiTunes_get_CurrentStreamURL(This,streamURL) \
+ (This)->lpVtbl -> get_CurrentStreamURL(This,streamURL)
+
+#define IiTunes_get_BrowserWindow(This,iBrowserWindow) \
+ (This)->lpVtbl -> get_BrowserWindow(This,iBrowserWindow)
+
+#define IiTunes_get_EQWindow(This,iEQWindow) \
+ (This)->lpVtbl -> get_EQWindow(This,iEQWindow)
+
+#define IiTunes_get_LibrarySource(This,iLibrarySource) \
+ (This)->lpVtbl -> get_LibrarySource(This,iLibrarySource)
+
+#define IiTunes_get_LibraryPlaylist(This,iLibraryPlaylist) \
+ (This)->lpVtbl -> get_LibraryPlaylist(This,iLibraryPlaylist)
+
+#define IiTunes_get_CurrentTrack(This,iTrack) \
+ (This)->lpVtbl -> get_CurrentTrack(This,iTrack)
+
+#define IiTunes_get_CurrentPlaylist(This,iPlaylist) \
+ (This)->lpVtbl -> get_CurrentPlaylist(This,iPlaylist)
+
+#define IiTunes_get_SelectedTracks(This,iTrackCollection) \
+ (This)->lpVtbl -> get_SelectedTracks(This,iTrackCollection)
+
+#define IiTunes_get_Version(This,version) \
+ (This)->lpVtbl -> get_Version(This,version)
+
+#define IiTunes_SetOptions(This,options) \
+ (This)->lpVtbl -> SetOptions(This,options)
+
+#define IiTunes_ConvertFile2(This,filePath,iStatus) \
+ (This)->lpVtbl -> ConvertFile2(This,filePath,iStatus)
+
+#define IiTunes_ConvertFiles2(This,filePaths,iStatus) \
+ (This)->lpVtbl -> ConvertFiles2(This,filePaths,iStatus)
+
+#define IiTunes_ConvertTrack2(This,iTrackToConvert,iStatus) \
+ (This)->lpVtbl -> ConvertTrack2(This,iTrackToConvert,iStatus)
+
+#define IiTunes_ConvertTracks2(This,iTracksToConvert,iStatus) \
+ (This)->lpVtbl -> ConvertTracks2(This,iTracksToConvert,iStatus)
+
+#define IiTunes_get_AppCommandMessageProcessingEnabled(This,isEnabled) \
+ (This)->lpVtbl -> get_AppCommandMessageProcessingEnabled(This,isEnabled)
+
+#define IiTunes_put_AppCommandMessageProcessingEnabled(This,shouldEnable) \
+ (This)->lpVtbl -> put_AppCommandMessageProcessingEnabled(This,shouldEnable)
+
+#define IiTunes_get_ForceToForegroundOnDialog(This,forceToForegroundOnDialog) \
+ (This)->lpVtbl -> get_ForceToForegroundOnDialog(This,forceToForegroundOnDialog)
+
+#define IiTunes_put_ForceToForegroundOnDialog(This,forceToForegroundOnDialog) \
+ (This)->lpVtbl -> put_ForceToForegroundOnDialog(This,forceToForegroundOnDialog)
+
+#define IiTunes_CreateEQPreset(This,eqPresetName,iEQPreset) \
+ (This)->lpVtbl -> CreateEQPreset(This,eqPresetName,iEQPreset)
+
+#define IiTunes_CreatePlaylistInSource(This,playlistName,iSource,iPlaylist) \
+ (This)->lpVtbl -> CreatePlaylistInSource(This,playlistName,iSource,iPlaylist)
+
+#define IiTunes_GetPlayerButtonsState(This,previousEnabled,playPauseStopState,nextEnabled) \
+ (This)->lpVtbl -> GetPlayerButtonsState(This,previousEnabled,playPauseStopState,nextEnabled)
+
+#define IiTunes_PlayerButtonClicked(This,playerButton,playerButtonModifierKeys) \
+ (This)->lpVtbl -> PlayerButtonClicked(This,playerButton,playerButtonModifierKeys)
+
+#define IiTunes_get_CanSetShuffle(This,iPlaylist,canSetShuffle) \
+ (This)->lpVtbl -> get_CanSetShuffle(This,iPlaylist,canSetShuffle)
+
+#define IiTunes_get_CanSetSongRepeat(This,iPlaylist,canSetSongRepeat) \
+ (This)->lpVtbl -> get_CanSetSongRepeat(This,iPlaylist,canSetSongRepeat)
+
+#define IiTunes_get_ConvertOperationStatus(This,iStatus) \
+ (This)->lpVtbl -> get_ConvertOperationStatus(This,iStatus)
+
+#define IiTunes_SubscribeToPodcast(This,url) \
+ (This)->lpVtbl -> SubscribeToPodcast(This,url)
+
+#define IiTunes_UpdatePodcastFeeds(This) \
+ (This)->lpVtbl -> UpdatePodcastFeeds(This)
+
+#define IiTunes_CreateFolder(This,folderName,iFolder) \
+ (This)->lpVtbl -> CreateFolder(This,folderName,iFolder)
+
+#define IiTunes_CreateFolderInSource(This,folderName,iSource,iFolder) \
+ (This)->lpVtbl -> CreateFolderInSource(This,folderName,iSource,iFolder)
+
+#define IiTunes_get_SoundVolumeControlEnabled(This,isEnabled) \
+ (This)->lpVtbl -> get_SoundVolumeControlEnabled(This,isEnabled)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_BackTrack_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_BackTrack_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_FastForward_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_FastForward_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_NextTrack_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_NextTrack_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_Pause_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_Pause_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_Play_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_Play_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_PlayFile_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR filePath);
+
+
+void __RPC_STUB IiTunes_PlayFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_PlayPause_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_PlayPause_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_PreviousTrack_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_PreviousTrack_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_Resume_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_Resume_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_Rewind_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_Rewind_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_Stop_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_Stop_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_ConvertFile_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+
+void __RPC_STUB IiTunes_ConvertFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_ConvertFiles_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *filePaths,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+
+void __RPC_STUB IiTunes_ConvertFiles_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_ConvertTrack_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iTrackToConvert,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+
+void __RPC_STUB IiTunes_ConvertTrack_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_ConvertTracks_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iTracksToConvert,
+ /* [retval][out] */ IITOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+
+void __RPC_STUB IiTunes_ConvertTracks_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_CheckVersion_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ long majorVersion,
+ /* [in] */ long minorVersion,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isCompatible);
+
+
+void __RPC_STUB IiTunes_CheckVersion_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_GetITObjectByID_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ long sourceID,
+ /* [in] */ long playlistID,
+ /* [in] */ long trackID,
+ /* [in] */ long databaseID,
+ /* [retval][out] */ IITObject __RPC_FAR *__RPC_FAR *iObject);
+
+
+void __RPC_STUB IiTunes_GetITObjectByID_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_CreatePlaylist_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR playlistName,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+
+void __RPC_STUB IiTunes_CreatePlaylist_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_OpenURL_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR url);
+
+
+void __RPC_STUB IiTunes_OpenURL_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_GotoMusicStoreHomePage_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_GotoMusicStoreHomePage_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_UpdateIPod_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_UpdateIPod_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_Authorize_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ long numElems,
+ /* [size_is][in] */ VARIANT __RPC_FAR data[ ],
+ /* [size_is][in] */ BSTR __RPC_FAR names[ ]);
+
+
+void __RPC_STUB IiTunes_Authorize_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_Quit_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_Quit_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_Sources_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITSourceCollection __RPC_FAR *__RPC_FAR *iSourceCollection);
+
+
+void __RPC_STUB IiTunes_get_Sources_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_Encoders_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITEncoderCollection __RPC_FAR *__RPC_FAR *iEncoderCollection);
+
+
+void __RPC_STUB IiTunes_get_Encoders_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_EQPresets_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITEQPresetCollection __RPC_FAR *__RPC_FAR *iEQPresetCollection);
+
+
+void __RPC_STUB IiTunes_get_EQPresets_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_Visuals_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITVisualCollection __RPC_FAR *__RPC_FAR *iVisualCollection);
+
+
+void __RPC_STUB IiTunes_get_Visuals_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_Windows_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITWindowCollection __RPC_FAR *__RPC_FAR *iWindowCollection);
+
+
+void __RPC_STUB IiTunes_get_Windows_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_SoundVolume_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *volume);
+
+
+void __RPC_STUB IiTunes_get_SoundVolume_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IiTunes_put_SoundVolume_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ long volume);
+
+
+void __RPC_STUB IiTunes_put_SoundVolume_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_Mute_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMuted);
+
+
+void __RPC_STUB IiTunes_get_Mute_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IiTunes_put_Mute_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldMute);
+
+
+void __RPC_STUB IiTunes_put_Mute_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_PlayerState_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ ITPlayerState __RPC_FAR *playerState);
+
+
+void __RPC_STUB IiTunes_get_PlayerState_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_PlayerPosition_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playerPos);
+
+
+void __RPC_STUB IiTunes_get_PlayerPosition_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IiTunes_put_PlayerPosition_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ long playerPos);
+
+
+void __RPC_STUB IiTunes_put_PlayerPosition_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_CurrentEncoder_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITEncoder __RPC_FAR *__RPC_FAR *iEncoder);
+
+
+void __RPC_STUB IiTunes_get_CurrentEncoder_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IiTunes_put_CurrentEncoder_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ IITEncoder __RPC_FAR *iEncoder);
+
+
+void __RPC_STUB IiTunes_put_CurrentEncoder_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_VisualsEnabled_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled);
+
+
+void __RPC_STUB IiTunes_get_VisualsEnabled_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IiTunes_put_VisualsEnabled_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldEnable);
+
+
+void __RPC_STUB IiTunes_put_VisualsEnabled_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_FullScreenVisuals_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isFullScreen);
+
+
+void __RPC_STUB IiTunes_get_FullScreenVisuals_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IiTunes_put_FullScreenVisuals_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldUseFullScreen);
+
+
+void __RPC_STUB IiTunes_put_FullScreenVisuals_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_VisualSize_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ ITVisualSize __RPC_FAR *visualSize);
+
+
+void __RPC_STUB IiTunes_get_VisualSize_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IiTunes_put_VisualSize_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ ITVisualSize visualSize);
+
+
+void __RPC_STUB IiTunes_put_VisualSize_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_CurrentVisual_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITVisual __RPC_FAR *__RPC_FAR *iVisual);
+
+
+void __RPC_STUB IiTunes_get_CurrentVisual_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IiTunes_put_CurrentVisual_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ IITVisual __RPC_FAR *iVisual);
+
+
+void __RPC_STUB IiTunes_put_CurrentVisual_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_EQEnabled_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled);
+
+
+void __RPC_STUB IiTunes_get_EQEnabled_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IiTunes_put_EQEnabled_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldEnable);
+
+
+void __RPC_STUB IiTunes_put_EQEnabled_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_CurrentEQPreset_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITEQPreset __RPC_FAR *__RPC_FAR *iEQPreset);
+
+
+void __RPC_STUB IiTunes_get_CurrentEQPreset_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IiTunes_put_CurrentEQPreset_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ IITEQPreset __RPC_FAR *iEQPreset);
+
+
+void __RPC_STUB IiTunes_put_CurrentEQPreset_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_CurrentStreamTitle_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *streamTitle);
+
+
+void __RPC_STUB IiTunes_get_CurrentStreamTitle_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_CurrentStreamURL_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *streamURL);
+
+
+void __RPC_STUB IiTunes_get_CurrentStreamURL_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_BrowserWindow_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITBrowserWindow __RPC_FAR *__RPC_FAR *iBrowserWindow);
+
+
+void __RPC_STUB IiTunes_get_BrowserWindow_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_EQWindow_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITWindow __RPC_FAR *__RPC_FAR *iEQWindow);
+
+
+void __RPC_STUB IiTunes_get_EQWindow_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_LibrarySource_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iLibrarySource);
+
+
+void __RPC_STUB IiTunes_get_LibrarySource_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_LibraryPlaylist_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITLibraryPlaylist __RPC_FAR *__RPC_FAR *iLibraryPlaylist);
+
+
+void __RPC_STUB IiTunes_get_LibraryPlaylist_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_CurrentTrack_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITTrack __RPC_FAR *__RPC_FAR *iTrack);
+
+
+void __RPC_STUB IiTunes_get_CurrentTrack_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_CurrentPlaylist_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+
+void __RPC_STUB IiTunes_get_CurrentPlaylist_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_SelectedTracks_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+
+void __RPC_STUB IiTunes_get_SelectedTracks_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_Version_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *version);
+
+
+void __RPC_STUB IiTunes_get_Version_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_SetOptions_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ long options);
+
+
+void __RPC_STUB IiTunes_SetOptions_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_ConvertFile2_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+
+void __RPC_STUB IiTunes_ConvertFile2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_ConvertFiles2_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *filePaths,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+
+void __RPC_STUB IiTunes_ConvertFiles2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_ConvertTrack2_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iTrackToConvert,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+
+void __RPC_STUB IiTunes_ConvertTrack2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_ConvertTracks2_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iTracksToConvert,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+
+void __RPC_STUB IiTunes_ConvertTracks2_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_AppCommandMessageProcessingEnabled_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled);
+
+
+void __RPC_STUB IiTunes_get_AppCommandMessageProcessingEnabled_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IiTunes_put_AppCommandMessageProcessingEnabled_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldEnable);
+
+
+void __RPC_STUB IiTunes_put_AppCommandMessageProcessingEnabled_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_ForceToForegroundOnDialog_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *forceToForegroundOnDialog);
+
+
+void __RPC_STUB IiTunes_get_ForceToForegroundOnDialog_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IiTunes_put_ForceToForegroundOnDialog_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL forceToForegroundOnDialog);
+
+
+void __RPC_STUB IiTunes_put_ForceToForegroundOnDialog_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_CreateEQPreset_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR eqPresetName,
+ /* [retval][out] */ IITEQPreset __RPC_FAR *__RPC_FAR *iEQPreset);
+
+
+void __RPC_STUB IiTunes_CreateEQPreset_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_CreatePlaylistInSource_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR playlistName,
+ /* [in] */ VARIANT __RPC_FAR *iSource,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+
+void __RPC_STUB IiTunes_CreatePlaylistInSource_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_GetPlayerButtonsState_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [out] */ VARIANT_BOOL __RPC_FAR *previousEnabled,
+ /* [out] */ ITPlayButtonState __RPC_FAR *playPauseStopState,
+ /* [out] */ VARIANT_BOOL __RPC_FAR *nextEnabled);
+
+
+void __RPC_STUB IiTunes_GetPlayerButtonsState_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_PlayerButtonClicked_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ ITPlayerButton playerButton,
+ /* [in] */ long playerButtonModifierKeys);
+
+
+void __RPC_STUB IiTunes_PlayerButtonClicked_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_CanSetShuffle_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iPlaylist,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *canSetShuffle);
+
+
+void __RPC_STUB IiTunes_get_CanSetShuffle_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_CanSetSongRepeat_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ VARIANT __RPC_FAR *iPlaylist,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *canSetSongRepeat);
+
+
+void __RPC_STUB IiTunes_get_CanSetSongRepeat_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_ConvertOperationStatus_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ IITConvertOperationStatus __RPC_FAR *__RPC_FAR *iStatus);
+
+
+void __RPC_STUB IiTunes_get_ConvertOperationStatus_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_SubscribeToPodcast_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR url);
+
+
+void __RPC_STUB IiTunes_SubscribeToPodcast_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_UpdatePodcastFeeds_Proxy(
+ IiTunes __RPC_FAR * This);
+
+
+void __RPC_STUB IiTunes_UpdatePodcastFeeds_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_CreateFolder_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR folderName,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iFolder);
+
+
+void __RPC_STUB IiTunes_CreateFolder_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IiTunes_CreateFolderInSource_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [in] */ BSTR folderName,
+ /* [in] */ VARIANT __RPC_FAR *iSource,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iFolder);
+
+
+void __RPC_STUB IiTunes_CreateFolderInSource_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IiTunes_get_SoundVolumeControlEnabled_Proxy(
+ IiTunes __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled);
+
+
+void __RPC_STUB IiTunes_get_SoundVolumeControlEnabled_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IiTunes_INTERFACE_DEFINED__ */
+
+
+#ifndef ___IiTunesEvents_DISPINTERFACE_DEFINED__
+#define ___IiTunesEvents_DISPINTERFACE_DEFINED__
+
+/* dispinterface _IiTunesEvents */
+/* [helpstring][uuid] */
+
+
+EXTERN_C const IID DIID__IiTunesEvents;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("5846EB78-317E-4b6f-B0C3-11EE8C8FEEF2")
+ _IiTunesEvents : public IDispatch
+ {
+ };
+
+#else /* C style interface */
+
+ typedef struct _IiTunesEventsVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ _IiTunesEvents __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ _IiTunesEvents __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ _IiTunesEvents __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ _IiTunesEvents __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ _IiTunesEvents __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ _IiTunesEvents __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ _IiTunesEvents __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ END_INTERFACE
+ } _IiTunesEventsVtbl;
+
+ interface _IiTunesEvents
+ {
+ CONST_VTBL struct _IiTunesEventsVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define _IiTunesEvents_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define _IiTunesEvents_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define _IiTunesEvents_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define _IiTunesEvents_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define _IiTunesEvents_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define _IiTunesEvents_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define _IiTunesEvents_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+#endif /* ___IiTunesEvents_DISPINTERFACE_DEFINED__ */
+
+
+#ifndef ___IITConvertOperationStatusEvents_DISPINTERFACE_DEFINED__
+#define ___IITConvertOperationStatusEvents_DISPINTERFACE_DEFINED__
+
+/* dispinterface _IITConvertOperationStatusEvents */
+/* [helpstring][uuid] */
+
+
+EXTERN_C const IID DIID__IITConvertOperationStatusEvents;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("5C47A705-8E8A-45a1-9EED-71C993F0BF60")
+ _IITConvertOperationStatusEvents : public IDispatch
+ {
+ };
+
+#else /* C style interface */
+
+ typedef struct _IITConvertOperationStatusEventsVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ _IITConvertOperationStatusEvents __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ _IITConvertOperationStatusEvents __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ _IITConvertOperationStatusEvents __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ _IITConvertOperationStatusEvents __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ _IITConvertOperationStatusEvents __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ _IITConvertOperationStatusEvents __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ _IITConvertOperationStatusEvents __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ END_INTERFACE
+ } _IITConvertOperationStatusEventsVtbl;
+
+ interface _IITConvertOperationStatusEvents
+ {
+ CONST_VTBL struct _IITConvertOperationStatusEventsVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define _IITConvertOperationStatusEvents_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define _IITConvertOperationStatusEvents_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define _IITConvertOperationStatusEvents_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define _IITConvertOperationStatusEvents_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define _IITConvertOperationStatusEvents_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define _IITConvertOperationStatusEvents_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define _IITConvertOperationStatusEvents_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+#endif /* ___IITConvertOperationStatusEvents_DISPINTERFACE_DEFINED__ */
+
+
+EXTERN_C const CLSID CLSID_iTunesApp;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("DC0C2640-1415-4644-875C-6F4D769839BA")
+iTunesApp;
+#endif
+
+EXTERN_C const CLSID CLSID_iTunesConvertOperationStatus;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("D06596AD-C900-41b2-BC68-1B486450FC56")
+iTunesConvertOperationStatus;
+#endif
+
+#ifndef __IITArtwork_INTERFACE_DEFINED__
+#define __IITArtwork_INTERFACE_DEFINED__
+
+/* interface IITArtwork */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITArtwork;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("D0A6C1F8-BF3D-4cd8-AC47-FE32BDD17257")
+ IITArtwork : public IDispatch
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Delete( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetArtworkFromFile(
+ /* [in] */ BSTR filePath) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SaveArtworkToFile(
+ /* [in] */ BSTR filePath) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Format(
+ /* [retval][out] */ ITArtworkFormat __RPC_FAR *format) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITArtworkVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITArtwork __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITArtwork __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITArtwork __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITArtwork __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITArtwork __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITArtwork __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITArtwork __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Delete )(
+ IITArtwork __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SetArtworkFromFile )(
+ IITArtwork __RPC_FAR * This,
+ /* [in] */ BSTR filePath);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SaveArtworkToFile )(
+ IITArtwork __RPC_FAR * This,
+ /* [in] */ BSTR filePath);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Format )(
+ IITArtwork __RPC_FAR * This,
+ /* [retval][out] */ ITArtworkFormat __RPC_FAR *format);
+
+ END_INTERFACE
+ } IITArtworkVtbl;
+
+ interface IITArtwork
+ {
+ CONST_VTBL struct IITArtworkVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITArtwork_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITArtwork_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITArtwork_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITArtwork_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITArtwork_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITArtwork_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITArtwork_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITArtwork_Delete(This) \
+ (This)->lpVtbl -> Delete(This)
+
+#define IITArtwork_SetArtworkFromFile(This,filePath) \
+ (This)->lpVtbl -> SetArtworkFromFile(This,filePath)
+
+#define IITArtwork_SaveArtworkToFile(This,filePath) \
+ (This)->lpVtbl -> SaveArtworkToFile(This,filePath)
+
+#define IITArtwork_get_Format(This,format) \
+ (This)->lpVtbl -> get_Format(This,format)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITArtwork_Delete_Proxy(
+ IITArtwork __RPC_FAR * This);
+
+
+void __RPC_STUB IITArtwork_Delete_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITArtwork_SetArtworkFromFile_Proxy(
+ IITArtwork __RPC_FAR * This,
+ /* [in] */ BSTR filePath);
+
+
+void __RPC_STUB IITArtwork_SetArtworkFromFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITArtwork_SaveArtworkToFile_Proxy(
+ IITArtwork __RPC_FAR * This,
+ /* [in] */ BSTR filePath);
+
+
+void __RPC_STUB IITArtwork_SaveArtworkToFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITArtwork_get_Format_Proxy(
+ IITArtwork __RPC_FAR * This,
+ /* [retval][out] */ ITArtworkFormat __RPC_FAR *format);
+
+
+void __RPC_STUB IITArtwork_get_Format_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITArtwork_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITArtworkCollection_INTERFACE_DEFINED__
+#define __IITArtworkCollection_INTERFACE_DEFINED__
+
+/* interface IITArtworkCollection */
+/* [unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITArtworkCollection;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("BF2742D7-418C-4858-9AF9-2981B062D23E")
+ IITArtworkCollection : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
+ /* [retval][out] */ long __RPC_FAR *count) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Item(
+ /* [in] */ long index,
+ /* [retval][out] */ IITArtwork __RPC_FAR *__RPC_FAR *iArtwork) = 0;
+
+ virtual /* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITArtworkCollectionVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITArtworkCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITArtworkCollection __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITArtworkCollection __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITArtworkCollection __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITArtworkCollection __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITArtworkCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITArtworkCollection __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Count )(
+ IITArtworkCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Item )(
+ IITArtworkCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITArtwork __RPC_FAR *__RPC_FAR *iArtwork);
+
+ /* [helpstring][restricted][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get__NewEnum )(
+ IITArtworkCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+ END_INTERFACE
+ } IITArtworkCollectionVtbl;
+
+ interface IITArtworkCollection
+ {
+ CONST_VTBL struct IITArtworkCollectionVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITArtworkCollection_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITArtworkCollection_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITArtworkCollection_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITArtworkCollection_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITArtworkCollection_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITArtworkCollection_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITArtworkCollection_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITArtworkCollection_get_Count(This,count) \
+ (This)->lpVtbl -> get_Count(This,count)
+
+#define IITArtworkCollection_get_Item(This,index,iArtwork) \
+ (This)->lpVtbl -> get_Item(This,index,iArtwork)
+
+#define IITArtworkCollection_get__NewEnum(This,iEnumerator) \
+ (This)->lpVtbl -> get__NewEnum(This,iEnumerator)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITArtworkCollection_get_Count_Proxy(
+ IITArtworkCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+
+void __RPC_STUB IITArtworkCollection_get_Count_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IITArtworkCollection_get_Item_Proxy(
+ IITArtworkCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITArtwork __RPC_FAR *__RPC_FAR *iArtwork);
+
+
+void __RPC_STUB IITArtworkCollection_get_Item_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE IITArtworkCollection_get__NewEnum_Proxy(
+ IITArtworkCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+
+void __RPC_STUB IITArtworkCollection_get__NewEnum_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITArtworkCollection_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITURLTrack_INTERFACE_DEFINED__
+#define __IITURLTrack_INTERFACE_DEFINED__
+
+/* interface IITURLTrack */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITURLTrack;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("1116E3B5-29FD-4393-A7BD-454E5E327900")
+ IITURLTrack : public IITTrack
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_URL(
+ /* [retval][out] */ BSTR __RPC_FAR *url) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_URL(
+ /* [in] */ BSTR url) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Podcast(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isPodcast) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UpdatePodcastFeed( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE DownloadPodcastEpisode( void) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Category(
+ /* [retval][out] */ BSTR __RPC_FAR *category) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Category(
+ /* [in] */ BSTR category) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Description(
+ /* [retval][out] */ BSTR __RPC_FAR *description) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Description(
+ /* [in] */ BSTR description) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_LongDescription(
+ /* [retval][out] */ BSTR __RPC_FAR *longDescription) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_LongDescription(
+ /* [in] */ BSTR longDescription) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITURLTrackVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITURLTrack __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITURLTrack __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITURLTrack __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetITObjectIDs )(
+ IITURLTrack __RPC_FAR * This,
+ /* [out] */ long __RPC_FAR *sourceID,
+ /* [out] */ long __RPC_FAR *playlistID,
+ /* [out] */ long __RPC_FAR *trackID,
+ /* [out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Name )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Index )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SourceID )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sourceID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlaylistID )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playlistID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackID )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackDatabaseID )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Delete )(
+ IITURLTrack __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Play )(
+ IITURLTrack __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddArtworkFromFile )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITArtwork __RPC_FAR *__RPC_FAR *iArtwork);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Kind )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ ITTrackKind __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Playlist )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Album )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *album);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Album )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR album);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Artist )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *artist);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Artist )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR artist);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_BitRate )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *bitrate);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_BPM )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *beatsPerMinute);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_BPM )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ long beatsPerMinute);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Comment )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *comment);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Comment )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR comment);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Compilation )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isCompilation);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Compilation )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeCompilation);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Composer )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *composer);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Composer )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR composer);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_DateAdded )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ DATE __RPC_FAR *dateAdded);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_DiscCount )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *discCount);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_DiscCount )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ long discCount);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_DiscNumber )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *discNumber);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_DiscNumber )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ long discNumber);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Duration )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *duration);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Enabled )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Enabled )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeEnabled);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_EQ )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *eq);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_EQ )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR eq);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Finish )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ long finish);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Finish )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *finish);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Genre )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *genre);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Genre )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR genre);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Grouping )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *grouping);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Grouping )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR grouping);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_KindAsString )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ModificationDate )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ DATE __RPC_FAR *dateModified);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlayedCount )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playedCount);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_PlayedCount )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ long playedCount);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlayedDate )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ DATE __RPC_FAR *playedDate);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_PlayedDate )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ DATE playedDate);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlayOrderIndex )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Rating )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *rating);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Rating )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ long rating);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SampleRate )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sampleRate);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Size )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *size);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Start )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *start);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Start )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ long start);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Time )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *time);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackCount )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackCount);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_TrackCount )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ long trackCount);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackNumber )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackNumber);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_TrackNumber )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ long trackNumber);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_VolumeAdjustment )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *volumeAdjustment);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_VolumeAdjustment )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ long volumeAdjustment);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Year )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *year);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Year )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ long year);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Artwork )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ IITArtworkCollection __RPC_FAR *__RPC_FAR *iArtworkCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_URL )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *url);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_URL )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR url);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Podcast )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isPodcast);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *UpdatePodcastFeed )(
+ IITURLTrack __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *DownloadPodcastEpisode )(
+ IITURLTrack __RPC_FAR * This);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Category )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *category);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Category )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR category);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Description )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *description);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Description )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR description);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_LongDescription )(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *longDescription);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_LongDescription )(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR longDescription);
+
+ END_INTERFACE
+ } IITURLTrackVtbl;
+
+ interface IITURLTrack
+ {
+ CONST_VTBL struct IITURLTrackVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITURLTrack_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITURLTrack_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITURLTrack_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITURLTrack_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITURLTrack_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITURLTrack_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITURLTrack_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITURLTrack_GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID) \
+ (This)->lpVtbl -> GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID)
+
+#define IITURLTrack_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITURLTrack_put_Name(This,name) \
+ (This)->lpVtbl -> put_Name(This,name)
+
+#define IITURLTrack_get_Index(This,index) \
+ (This)->lpVtbl -> get_Index(This,index)
+
+#define IITURLTrack_get_SourceID(This,sourceID) \
+ (This)->lpVtbl -> get_SourceID(This,sourceID)
+
+#define IITURLTrack_get_PlaylistID(This,playlistID) \
+ (This)->lpVtbl -> get_PlaylistID(This,playlistID)
+
+#define IITURLTrack_get_TrackID(This,trackID) \
+ (This)->lpVtbl -> get_TrackID(This,trackID)
+
+#define IITURLTrack_get_TrackDatabaseID(This,databaseID) \
+ (This)->lpVtbl -> get_TrackDatabaseID(This,databaseID)
+
+
+#define IITURLTrack_Delete(This) \
+ (This)->lpVtbl -> Delete(This)
+
+#define IITURLTrack_Play(This) \
+ (This)->lpVtbl -> Play(This)
+
+#define IITURLTrack_AddArtworkFromFile(This,filePath,iArtwork) \
+ (This)->lpVtbl -> AddArtworkFromFile(This,filePath,iArtwork)
+
+#define IITURLTrack_get_Kind(This,kind) \
+ (This)->lpVtbl -> get_Kind(This,kind)
+
+#define IITURLTrack_get_Playlist(This,iPlaylist) \
+ (This)->lpVtbl -> get_Playlist(This,iPlaylist)
+
+#define IITURLTrack_get_Album(This,album) \
+ (This)->lpVtbl -> get_Album(This,album)
+
+#define IITURLTrack_put_Album(This,album) \
+ (This)->lpVtbl -> put_Album(This,album)
+
+#define IITURLTrack_get_Artist(This,artist) \
+ (This)->lpVtbl -> get_Artist(This,artist)
+
+#define IITURLTrack_put_Artist(This,artist) \
+ (This)->lpVtbl -> put_Artist(This,artist)
+
+#define IITURLTrack_get_BitRate(This,bitrate) \
+ (This)->lpVtbl -> get_BitRate(This,bitrate)
+
+#define IITURLTrack_get_BPM(This,beatsPerMinute) \
+ (This)->lpVtbl -> get_BPM(This,beatsPerMinute)
+
+#define IITURLTrack_put_BPM(This,beatsPerMinute) \
+ (This)->lpVtbl -> put_BPM(This,beatsPerMinute)
+
+#define IITURLTrack_get_Comment(This,comment) \
+ (This)->lpVtbl -> get_Comment(This,comment)
+
+#define IITURLTrack_put_Comment(This,comment) \
+ (This)->lpVtbl -> put_Comment(This,comment)
+
+#define IITURLTrack_get_Compilation(This,isCompilation) \
+ (This)->lpVtbl -> get_Compilation(This,isCompilation)
+
+#define IITURLTrack_put_Compilation(This,shouldBeCompilation) \
+ (This)->lpVtbl -> put_Compilation(This,shouldBeCompilation)
+
+#define IITURLTrack_get_Composer(This,composer) \
+ (This)->lpVtbl -> get_Composer(This,composer)
+
+#define IITURLTrack_put_Composer(This,composer) \
+ (This)->lpVtbl -> put_Composer(This,composer)
+
+#define IITURLTrack_get_DateAdded(This,dateAdded) \
+ (This)->lpVtbl -> get_DateAdded(This,dateAdded)
+
+#define IITURLTrack_get_DiscCount(This,discCount) \
+ (This)->lpVtbl -> get_DiscCount(This,discCount)
+
+#define IITURLTrack_put_DiscCount(This,discCount) \
+ (This)->lpVtbl -> put_DiscCount(This,discCount)
+
+#define IITURLTrack_get_DiscNumber(This,discNumber) \
+ (This)->lpVtbl -> get_DiscNumber(This,discNumber)
+
+#define IITURLTrack_put_DiscNumber(This,discNumber) \
+ (This)->lpVtbl -> put_DiscNumber(This,discNumber)
+
+#define IITURLTrack_get_Duration(This,duration) \
+ (This)->lpVtbl -> get_Duration(This,duration)
+
+#define IITURLTrack_get_Enabled(This,isEnabled) \
+ (This)->lpVtbl -> get_Enabled(This,isEnabled)
+
+#define IITURLTrack_put_Enabled(This,shouldBeEnabled) \
+ (This)->lpVtbl -> put_Enabled(This,shouldBeEnabled)
+
+#define IITURLTrack_get_EQ(This,eq) \
+ (This)->lpVtbl -> get_EQ(This,eq)
+
+#define IITURLTrack_put_EQ(This,eq) \
+ (This)->lpVtbl -> put_EQ(This,eq)
+
+#define IITURLTrack_put_Finish(This,finish) \
+ (This)->lpVtbl -> put_Finish(This,finish)
+
+#define IITURLTrack_get_Finish(This,finish) \
+ (This)->lpVtbl -> get_Finish(This,finish)
+
+#define IITURLTrack_get_Genre(This,genre) \
+ (This)->lpVtbl -> get_Genre(This,genre)
+
+#define IITURLTrack_put_Genre(This,genre) \
+ (This)->lpVtbl -> put_Genre(This,genre)
+
+#define IITURLTrack_get_Grouping(This,grouping) \
+ (This)->lpVtbl -> get_Grouping(This,grouping)
+
+#define IITURLTrack_put_Grouping(This,grouping) \
+ (This)->lpVtbl -> put_Grouping(This,grouping)
+
+#define IITURLTrack_get_KindAsString(This,kind) \
+ (This)->lpVtbl -> get_KindAsString(This,kind)
+
+#define IITURLTrack_get_ModificationDate(This,dateModified) \
+ (This)->lpVtbl -> get_ModificationDate(This,dateModified)
+
+#define IITURLTrack_get_PlayedCount(This,playedCount) \
+ (This)->lpVtbl -> get_PlayedCount(This,playedCount)
+
+#define IITURLTrack_put_PlayedCount(This,playedCount) \
+ (This)->lpVtbl -> put_PlayedCount(This,playedCount)
+
+#define IITURLTrack_get_PlayedDate(This,playedDate) \
+ (This)->lpVtbl -> get_PlayedDate(This,playedDate)
+
+#define IITURLTrack_put_PlayedDate(This,playedDate) \
+ (This)->lpVtbl -> put_PlayedDate(This,playedDate)
+
+#define IITURLTrack_get_PlayOrderIndex(This,index) \
+ (This)->lpVtbl -> get_PlayOrderIndex(This,index)
+
+#define IITURLTrack_get_Rating(This,rating) \
+ (This)->lpVtbl -> get_Rating(This,rating)
+
+#define IITURLTrack_put_Rating(This,rating) \
+ (This)->lpVtbl -> put_Rating(This,rating)
+
+#define IITURLTrack_get_SampleRate(This,sampleRate) \
+ (This)->lpVtbl -> get_SampleRate(This,sampleRate)
+
+#define IITURLTrack_get_Size(This,size) \
+ (This)->lpVtbl -> get_Size(This,size)
+
+#define IITURLTrack_get_Start(This,start) \
+ (This)->lpVtbl -> get_Start(This,start)
+
+#define IITURLTrack_put_Start(This,start) \
+ (This)->lpVtbl -> put_Start(This,start)
+
+#define IITURLTrack_get_Time(This,time) \
+ (This)->lpVtbl -> get_Time(This,time)
+
+#define IITURLTrack_get_TrackCount(This,trackCount) \
+ (This)->lpVtbl -> get_TrackCount(This,trackCount)
+
+#define IITURLTrack_put_TrackCount(This,trackCount) \
+ (This)->lpVtbl -> put_TrackCount(This,trackCount)
+
+#define IITURLTrack_get_TrackNumber(This,trackNumber) \
+ (This)->lpVtbl -> get_TrackNumber(This,trackNumber)
+
+#define IITURLTrack_put_TrackNumber(This,trackNumber) \
+ (This)->lpVtbl -> put_TrackNumber(This,trackNumber)
+
+#define IITURLTrack_get_VolumeAdjustment(This,volumeAdjustment) \
+ (This)->lpVtbl -> get_VolumeAdjustment(This,volumeAdjustment)
+
+#define IITURLTrack_put_VolumeAdjustment(This,volumeAdjustment) \
+ (This)->lpVtbl -> put_VolumeAdjustment(This,volumeAdjustment)
+
+#define IITURLTrack_get_Year(This,year) \
+ (This)->lpVtbl -> get_Year(This,year)
+
+#define IITURLTrack_put_Year(This,year) \
+ (This)->lpVtbl -> put_Year(This,year)
+
+#define IITURLTrack_get_Artwork(This,iArtworkCollection) \
+ (This)->lpVtbl -> get_Artwork(This,iArtworkCollection)
+
+
+#define IITURLTrack_get_URL(This,url) \
+ (This)->lpVtbl -> get_URL(This,url)
+
+#define IITURLTrack_put_URL(This,url) \
+ (This)->lpVtbl -> put_URL(This,url)
+
+#define IITURLTrack_get_Podcast(This,isPodcast) \
+ (This)->lpVtbl -> get_Podcast(This,isPodcast)
+
+#define IITURLTrack_UpdatePodcastFeed(This) \
+ (This)->lpVtbl -> UpdatePodcastFeed(This)
+
+#define IITURLTrack_DownloadPodcastEpisode(This) \
+ (This)->lpVtbl -> DownloadPodcastEpisode(This)
+
+#define IITURLTrack_get_Category(This,category) \
+ (This)->lpVtbl -> get_Category(This,category)
+
+#define IITURLTrack_put_Category(This,category) \
+ (This)->lpVtbl -> put_Category(This,category)
+
+#define IITURLTrack_get_Description(This,description) \
+ (This)->lpVtbl -> get_Description(This,description)
+
+#define IITURLTrack_put_Description(This,description) \
+ (This)->lpVtbl -> put_Description(This,description)
+
+#define IITURLTrack_get_LongDescription(This,longDescription) \
+ (This)->lpVtbl -> get_LongDescription(This,longDescription)
+
+#define IITURLTrack_put_LongDescription(This,longDescription) \
+ (This)->lpVtbl -> put_LongDescription(This,longDescription)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITURLTrack_get_URL_Proxy(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *url);
+
+
+void __RPC_STUB IITURLTrack_get_URL_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITURLTrack_put_URL_Proxy(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR url);
+
+
+void __RPC_STUB IITURLTrack_put_URL_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITURLTrack_get_Podcast_Proxy(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isPodcast);
+
+
+void __RPC_STUB IITURLTrack_get_Podcast_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITURLTrack_UpdatePodcastFeed_Proxy(
+ IITURLTrack __RPC_FAR * This);
+
+
+void __RPC_STUB IITURLTrack_UpdatePodcastFeed_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITURLTrack_DownloadPodcastEpisode_Proxy(
+ IITURLTrack __RPC_FAR * This);
+
+
+void __RPC_STUB IITURLTrack_DownloadPodcastEpisode_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITURLTrack_get_Category_Proxy(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *category);
+
+
+void __RPC_STUB IITURLTrack_get_Category_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITURLTrack_put_Category_Proxy(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR category);
+
+
+void __RPC_STUB IITURLTrack_put_Category_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITURLTrack_get_Description_Proxy(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *description);
+
+
+void __RPC_STUB IITURLTrack_get_Description_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITURLTrack_put_Description_Proxy(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR description);
+
+
+void __RPC_STUB IITURLTrack_put_Description_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITURLTrack_get_LongDescription_Proxy(
+ IITURLTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *longDescription);
+
+
+void __RPC_STUB IITURLTrack_get_LongDescription_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITURLTrack_put_LongDescription_Proxy(
+ IITURLTrack __RPC_FAR * This,
+ /* [in] */ BSTR longDescription);
+
+
+void __RPC_STUB IITURLTrack_put_LongDescription_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITURLTrack_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITAudioCDPlaylist_INTERFACE_DEFINED__
+#define __IITAudioCDPlaylist_INTERFACE_DEFINED__
+
+/* interface IITAudioCDPlaylist */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITAudioCDPlaylist;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("CF496DF3-0FED-4d7d-9BD8-529B6E8A082E")
+ IITAudioCDPlaylist : public IITPlaylist
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Artist(
+ /* [retval][out] */ BSTR __RPC_FAR *artist) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Compilation(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isCompiliation) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Composer(
+ /* [retval][out] */ BSTR __RPC_FAR *composer) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_DiscCount(
+ /* [retval][out] */ long __RPC_FAR *discCount) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_DiscNumber(
+ /* [retval][out] */ long __RPC_FAR *discNumber) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Genre(
+ /* [retval][out] */ BSTR __RPC_FAR *genre) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Year(
+ /* [retval][out] */ long __RPC_FAR *year) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITAudioCDPlaylistVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITAudioCDPlaylist __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITAudioCDPlaylist __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetITObjectIDs )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [out] */ long __RPC_FAR *sourceID,
+ /* [out] */ long __RPC_FAR *playlistID,
+ /* [out] */ long __RPC_FAR *trackID,
+ /* [out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Name )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Index )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SourceID )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sourceID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlaylistID )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playlistID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackID )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackDatabaseID )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Delete )(
+ IITAudioCDPlaylist __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *PlayFirstTrack )(
+ IITAudioCDPlaylist __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Print )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL showPrintDialog,
+ /* [in] */ ITPlaylistPrintKind printKind,
+ /* [in] */ BSTR theme);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Search )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [in] */ BSTR searchText,
+ /* [in] */ ITPlaylistSearchField searchFields,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Kind )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ ITPlaylistKind __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Source )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ IITSource __RPC_FAR *__RPC_FAR *iSource);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Duration )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *duration);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Shuffle )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isShuffle);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Shuffle )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldShuffle);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Size )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *size);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SongRepeat )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ ITPlaylistRepeatMode __RPC_FAR *repeatMode);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_SongRepeat )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [in] */ ITPlaylistRepeatMode repeatMode);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Time )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *time);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Visible )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isVisible);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Tracks )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Artist )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *artist);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Compilation )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isCompiliation);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Composer )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *composer);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_DiscCount )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *discCount);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_DiscNumber )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *discNumber);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Genre )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *genre);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Year )(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *year);
+
+ END_INTERFACE
+ } IITAudioCDPlaylistVtbl;
+
+ interface IITAudioCDPlaylist
+ {
+ CONST_VTBL struct IITAudioCDPlaylistVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITAudioCDPlaylist_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITAudioCDPlaylist_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITAudioCDPlaylist_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITAudioCDPlaylist_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITAudioCDPlaylist_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITAudioCDPlaylist_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITAudioCDPlaylist_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITAudioCDPlaylist_GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID) \
+ (This)->lpVtbl -> GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID)
+
+#define IITAudioCDPlaylist_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITAudioCDPlaylist_put_Name(This,name) \
+ (This)->lpVtbl -> put_Name(This,name)
+
+#define IITAudioCDPlaylist_get_Index(This,index) \
+ (This)->lpVtbl -> get_Index(This,index)
+
+#define IITAudioCDPlaylist_get_SourceID(This,sourceID) \
+ (This)->lpVtbl -> get_SourceID(This,sourceID)
+
+#define IITAudioCDPlaylist_get_PlaylistID(This,playlistID) \
+ (This)->lpVtbl -> get_PlaylistID(This,playlistID)
+
+#define IITAudioCDPlaylist_get_TrackID(This,trackID) \
+ (This)->lpVtbl -> get_TrackID(This,trackID)
+
+#define IITAudioCDPlaylist_get_TrackDatabaseID(This,databaseID) \
+ (This)->lpVtbl -> get_TrackDatabaseID(This,databaseID)
+
+
+#define IITAudioCDPlaylist_Delete(This) \
+ (This)->lpVtbl -> Delete(This)
+
+#define IITAudioCDPlaylist_PlayFirstTrack(This) \
+ (This)->lpVtbl -> PlayFirstTrack(This)
+
+#define IITAudioCDPlaylist_Print(This,showPrintDialog,printKind,theme) \
+ (This)->lpVtbl -> Print(This,showPrintDialog,printKind,theme)
+
+#define IITAudioCDPlaylist_Search(This,searchText,searchFields,iTrackCollection) \
+ (This)->lpVtbl -> Search(This,searchText,searchFields,iTrackCollection)
+
+#define IITAudioCDPlaylist_get_Kind(This,kind) \
+ (This)->lpVtbl -> get_Kind(This,kind)
+
+#define IITAudioCDPlaylist_get_Source(This,iSource) \
+ (This)->lpVtbl -> get_Source(This,iSource)
+
+#define IITAudioCDPlaylist_get_Duration(This,duration) \
+ (This)->lpVtbl -> get_Duration(This,duration)
+
+#define IITAudioCDPlaylist_get_Shuffle(This,isShuffle) \
+ (This)->lpVtbl -> get_Shuffle(This,isShuffle)
+
+#define IITAudioCDPlaylist_put_Shuffle(This,shouldShuffle) \
+ (This)->lpVtbl -> put_Shuffle(This,shouldShuffle)
+
+#define IITAudioCDPlaylist_get_Size(This,size) \
+ (This)->lpVtbl -> get_Size(This,size)
+
+#define IITAudioCDPlaylist_get_SongRepeat(This,repeatMode) \
+ (This)->lpVtbl -> get_SongRepeat(This,repeatMode)
+
+#define IITAudioCDPlaylist_put_SongRepeat(This,repeatMode) \
+ (This)->lpVtbl -> put_SongRepeat(This,repeatMode)
+
+#define IITAudioCDPlaylist_get_Time(This,time) \
+ (This)->lpVtbl -> get_Time(This,time)
+
+#define IITAudioCDPlaylist_get_Visible(This,isVisible) \
+ (This)->lpVtbl -> get_Visible(This,isVisible)
+
+#define IITAudioCDPlaylist_get_Tracks(This,iTrackCollection) \
+ (This)->lpVtbl -> get_Tracks(This,iTrackCollection)
+
+
+#define IITAudioCDPlaylist_get_Artist(This,artist) \
+ (This)->lpVtbl -> get_Artist(This,artist)
+
+#define IITAudioCDPlaylist_get_Compilation(This,isCompiliation) \
+ (This)->lpVtbl -> get_Compilation(This,isCompiliation)
+
+#define IITAudioCDPlaylist_get_Composer(This,composer) \
+ (This)->lpVtbl -> get_Composer(This,composer)
+
+#define IITAudioCDPlaylist_get_DiscCount(This,discCount) \
+ (This)->lpVtbl -> get_DiscCount(This,discCount)
+
+#define IITAudioCDPlaylist_get_DiscNumber(This,discNumber) \
+ (This)->lpVtbl -> get_DiscNumber(This,discNumber)
+
+#define IITAudioCDPlaylist_get_Genre(This,genre) \
+ (This)->lpVtbl -> get_Genre(This,genre)
+
+#define IITAudioCDPlaylist_get_Year(This,year) \
+ (This)->lpVtbl -> get_Year(This,year)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITAudioCDPlaylist_get_Artist_Proxy(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *artist);
+
+
+void __RPC_STUB IITAudioCDPlaylist_get_Artist_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITAudioCDPlaylist_get_Compilation_Proxy(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isCompiliation);
+
+
+void __RPC_STUB IITAudioCDPlaylist_get_Compilation_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITAudioCDPlaylist_get_Composer_Proxy(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *composer);
+
+
+void __RPC_STUB IITAudioCDPlaylist_get_Composer_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITAudioCDPlaylist_get_DiscCount_Proxy(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *discCount);
+
+
+void __RPC_STUB IITAudioCDPlaylist_get_DiscCount_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITAudioCDPlaylist_get_DiscNumber_Proxy(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *discNumber);
+
+
+void __RPC_STUB IITAudioCDPlaylist_get_DiscNumber_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITAudioCDPlaylist_get_Genre_Proxy(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *genre);
+
+
+void __RPC_STUB IITAudioCDPlaylist_get_Genre_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITAudioCDPlaylist_get_Year_Proxy(
+ IITAudioCDPlaylist __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *year);
+
+
+void __RPC_STUB IITAudioCDPlaylist_get_Year_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITAudioCDPlaylist_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITPlaylistCollection_INTERFACE_DEFINED__
+#define __IITPlaylistCollection_INTERFACE_DEFINED__
+
+/* interface IITPlaylistCollection */
+/* [unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITPlaylistCollection;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("FF194254-909D-4437-9C50-3AAC2AE6305C")
+ IITPlaylistCollection : public IDispatch
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
+ /* [retval][out] */ long __RPC_FAR *count) = 0;
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Item(
+ /* [in] */ long index,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ItemByName(
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist) = 0;
+
+ virtual /* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITPlaylistCollectionVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITPlaylistCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITPlaylistCollection __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITPlaylistCollection __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITPlaylistCollection __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITPlaylistCollection __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITPlaylistCollection __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITPlaylistCollection __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Count )(
+ IITPlaylistCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+ /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Item )(
+ IITPlaylistCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ItemByName )(
+ IITPlaylistCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+ /* [helpstring][restricted][id][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get__NewEnum )(
+ IITPlaylistCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+ END_INTERFACE
+ } IITPlaylistCollectionVtbl;
+
+ interface IITPlaylistCollection
+ {
+ CONST_VTBL struct IITPlaylistCollectionVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITPlaylistCollection_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITPlaylistCollection_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITPlaylistCollection_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITPlaylistCollection_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITPlaylistCollection_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITPlaylistCollection_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITPlaylistCollection_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITPlaylistCollection_get_Count(This,count) \
+ (This)->lpVtbl -> get_Count(This,count)
+
+#define IITPlaylistCollection_get_Item(This,index,iPlaylist) \
+ (This)->lpVtbl -> get_Item(This,index,iPlaylist)
+
+#define IITPlaylistCollection_get_ItemByName(This,name,iPlaylist) \
+ (This)->lpVtbl -> get_ItemByName(This,name,iPlaylist)
+
+#define IITPlaylistCollection_get__NewEnum(This,iEnumerator) \
+ (This)->lpVtbl -> get__NewEnum(This,iEnumerator)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylistCollection_get_Count_Proxy(
+ IITPlaylistCollection __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *count);
+
+
+void __RPC_STUB IITPlaylistCollection_get_Count_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylistCollection_get_Item_Proxy(
+ IITPlaylistCollection __RPC_FAR * This,
+ /* [in] */ long index,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+
+void __RPC_STUB IITPlaylistCollection_get_Item_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylistCollection_get_ItemByName_Proxy(
+ IITPlaylistCollection __RPC_FAR * This,
+ /* [in] */ BSTR name,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+
+void __RPC_STUB IITPlaylistCollection_get_ItemByName_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][restricted][id][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylistCollection_get__NewEnum_Proxy(
+ IITPlaylistCollection __RPC_FAR * This,
+ /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *iEnumerator);
+
+
+void __RPC_STUB IITPlaylistCollection_get__NewEnum_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITPlaylistCollection_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITIPodSource_INTERFACE_DEFINED__
+#define __IITIPodSource_INTERFACE_DEFINED__
+
+/* interface IITIPodSource */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITIPodSource;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("CF4D8ACE-1720-4fb9-B0AE-9877249E89B0")
+ IITIPodSource : public IITSource
+ {
+ public:
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UpdateIPod( void) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE EjectIPod( void) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_SoftwareVersion(
+ /* [retval][out] */ BSTR __RPC_FAR *softwareVersion) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITIPodSourceVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITIPodSource __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITIPodSource __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITIPodSource __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITIPodSource __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITIPodSource __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITIPodSource __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITIPodSource __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetITObjectIDs )(
+ IITIPodSource __RPC_FAR * This,
+ /* [out] */ long __RPC_FAR *sourceID,
+ /* [out] */ long __RPC_FAR *playlistID,
+ /* [out] */ long __RPC_FAR *trackID,
+ /* [out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITIPodSource __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Name )(
+ IITIPodSource __RPC_FAR * This,
+ /* [in] */ BSTR name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Index )(
+ IITIPodSource __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SourceID )(
+ IITIPodSource __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sourceID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlaylistID )(
+ IITIPodSource __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playlistID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackID )(
+ IITIPodSource __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackDatabaseID )(
+ IITIPodSource __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Kind )(
+ IITIPodSource __RPC_FAR * This,
+ /* [retval][out] */ ITSourceKind __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Capacity )(
+ IITIPodSource __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *capacity);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_FreeSpace )(
+ IITIPodSource __RPC_FAR * This,
+ /* [retval][out] */ double __RPC_FAR *freespace);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Playlists )(
+ IITIPodSource __RPC_FAR * This,
+ /* [retval][out] */ IITPlaylistCollection __RPC_FAR *__RPC_FAR *iPlaylistCollection);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *UpdateIPod )(
+ IITIPodSource __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *EjectIPod )(
+ IITIPodSource __RPC_FAR * This);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SoftwareVersion )(
+ IITIPodSource __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *softwareVersion);
+
+ END_INTERFACE
+ } IITIPodSourceVtbl;
+
+ interface IITIPodSource
+ {
+ CONST_VTBL struct IITIPodSourceVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITIPodSource_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITIPodSource_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITIPodSource_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITIPodSource_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITIPodSource_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITIPodSource_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITIPodSource_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITIPodSource_GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID) \
+ (This)->lpVtbl -> GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID)
+
+#define IITIPodSource_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITIPodSource_put_Name(This,name) \
+ (This)->lpVtbl -> put_Name(This,name)
+
+#define IITIPodSource_get_Index(This,index) \
+ (This)->lpVtbl -> get_Index(This,index)
+
+#define IITIPodSource_get_SourceID(This,sourceID) \
+ (This)->lpVtbl -> get_SourceID(This,sourceID)
+
+#define IITIPodSource_get_PlaylistID(This,playlistID) \
+ (This)->lpVtbl -> get_PlaylistID(This,playlistID)
+
+#define IITIPodSource_get_TrackID(This,trackID) \
+ (This)->lpVtbl -> get_TrackID(This,trackID)
+
+#define IITIPodSource_get_TrackDatabaseID(This,databaseID) \
+ (This)->lpVtbl -> get_TrackDatabaseID(This,databaseID)
+
+
+#define IITIPodSource_get_Kind(This,kind) \
+ (This)->lpVtbl -> get_Kind(This,kind)
+
+#define IITIPodSource_get_Capacity(This,capacity) \
+ (This)->lpVtbl -> get_Capacity(This,capacity)
+
+#define IITIPodSource_get_FreeSpace(This,freespace) \
+ (This)->lpVtbl -> get_FreeSpace(This,freespace)
+
+#define IITIPodSource_get_Playlists(This,iPlaylistCollection) \
+ (This)->lpVtbl -> get_Playlists(This,iPlaylistCollection)
+
+
+#define IITIPodSource_UpdateIPod(This) \
+ (This)->lpVtbl -> UpdateIPod(This)
+
+#define IITIPodSource_EjectIPod(This) \
+ (This)->lpVtbl -> EjectIPod(This)
+
+#define IITIPodSource_get_SoftwareVersion(This,softwareVersion) \
+ (This)->lpVtbl -> get_SoftwareVersion(This,softwareVersion)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITIPodSource_UpdateIPod_Proxy(
+ IITIPodSource __RPC_FAR * This);
+
+
+void __RPC_STUB IITIPodSource_UpdateIPod_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITIPodSource_EjectIPod_Proxy(
+ IITIPodSource __RPC_FAR * This);
+
+
+void __RPC_STUB IITIPodSource_EjectIPod_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITIPodSource_get_SoftwareVersion_Proxy(
+ IITIPodSource __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *softwareVersion);
+
+
+void __RPC_STUB IITIPodSource_get_SoftwareVersion_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITIPodSource_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITFileOrCDTrack_INTERFACE_DEFINED__
+#define __IITFileOrCDTrack_INTERFACE_DEFINED__
+
+/* interface IITFileOrCDTrack */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITFileOrCDTrack;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("00D7FE99-7868-4cc7-AD9E-ACFD70D09566")
+ IITFileOrCDTrack : public IITTrack
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Location(
+ /* [retval][out] */ BSTR __RPC_FAR *location) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UpdateInfoFromFile( void) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Podcast(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isPodcast) = 0;
+
+ virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UpdatePodcastFeed( void) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_RememberBookmark(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *rememberBookmark) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_RememberBookmark(
+ /* [in] */ VARIANT_BOOL shouldRememberBookmark) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ExcludeFromShuffle(
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *excludeFromShuffle) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_ExcludeFromShuffle(
+ /* [in] */ VARIANT_BOOL shouldExcludeFromShuffle) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Lyrics(
+ /* [retval][out] */ BSTR __RPC_FAR *lyrics) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Lyrics(
+ /* [in] */ BSTR lyrics) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Category(
+ /* [retval][out] */ BSTR __RPC_FAR *category) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Category(
+ /* [in] */ BSTR category) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Description(
+ /* [retval][out] */ BSTR __RPC_FAR *description) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_Description(
+ /* [in] */ BSTR description) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_LongDescription(
+ /* [retval][out] */ BSTR __RPC_FAR *longDescription) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_LongDescription(
+ /* [in] */ BSTR longDescription) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_BookmarkTime(
+ /* [retval][out] */ long __RPC_FAR *bookmarkTime) = 0;
+
+ virtual /* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_BookmarkTime(
+ /* [in] */ long bookmarkTime) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITFileOrCDTrackVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITFileOrCDTrack __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITFileOrCDTrack __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetITObjectIDs )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [out] */ long __RPC_FAR *sourceID,
+ /* [out] */ long __RPC_FAR *playlistID,
+ /* [out] */ long __RPC_FAR *trackID,
+ /* [out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Name )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Index )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SourceID )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sourceID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlaylistID )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playlistID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackID )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackID);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackDatabaseID )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *databaseID);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Delete )(
+ IITFileOrCDTrack __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Play )(
+ IITFileOrCDTrack __RPC_FAR * This);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddArtworkFromFile )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR filePath,
+ /* [retval][out] */ IITArtwork __RPC_FAR *__RPC_FAR *iArtwork);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Kind )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ ITTrackKind __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Playlist )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Album )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *album);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Album )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR album);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Artist )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *artist);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Artist )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR artist);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_BitRate )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *bitrate);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_BPM )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *beatsPerMinute);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_BPM )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ long beatsPerMinute);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Comment )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *comment);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Comment )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR comment);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Compilation )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isCompilation);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Compilation )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeCompilation);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Composer )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *composer);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Composer )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR composer);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_DateAdded )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ DATE __RPC_FAR *dateAdded);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_DiscCount )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *discCount);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_DiscCount )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ long discCount);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_DiscNumber )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *discNumber);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_DiscNumber )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ long discNumber);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Duration )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *duration);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Enabled )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isEnabled);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Enabled )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeEnabled);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_EQ )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *eq);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_EQ )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR eq);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Finish )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ long finish);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Finish )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *finish);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Genre )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *genre);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Genre )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR genre);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Grouping )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *grouping);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Grouping )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR grouping);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_KindAsString )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ModificationDate )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ DATE __RPC_FAR *dateModified);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlayedCount )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *playedCount);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_PlayedCount )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ long playedCount);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlayedDate )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ DATE __RPC_FAR *playedDate);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_PlayedDate )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ DATE playedDate);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_PlayOrderIndex )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *index);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Rating )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *rating);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Rating )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ long rating);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SampleRate )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *sampleRate);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Size )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *size);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Start )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *start);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Start )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ long start);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Time )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *time);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackCount )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackCount);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_TrackCount )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ long trackCount);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_TrackNumber )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *trackNumber);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_TrackNumber )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ long trackNumber);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_VolumeAdjustment )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *volumeAdjustment);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_VolumeAdjustment )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ long volumeAdjustment);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Year )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *year);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Year )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ long year);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Artwork )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ IITArtworkCollection __RPC_FAR *__RPC_FAR *iArtworkCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Location )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *location);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *UpdateInfoFromFile )(
+ IITFileOrCDTrack __RPC_FAR * This);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Podcast )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isPodcast);
+
+ /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *UpdatePodcastFeed )(
+ IITFileOrCDTrack __RPC_FAR * This);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_RememberBookmark )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *rememberBookmark);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_RememberBookmark )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldRememberBookmark);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_ExcludeFromShuffle )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *excludeFromShuffle);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_ExcludeFromShuffle )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldExcludeFromShuffle);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Lyrics )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *lyrics);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Lyrics )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR lyrics);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Category )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *category);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Category )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR category);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Description )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *description);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Description )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR description);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_LongDescription )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *longDescription);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_LongDescription )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR longDescription);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_BookmarkTime )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *bookmarkTime);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_BookmarkTime )(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ long bookmarkTime);
+
+ END_INTERFACE
+ } IITFileOrCDTrackVtbl;
+
+ interface IITFileOrCDTrack
+ {
+ CONST_VTBL struct IITFileOrCDTrackVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITFileOrCDTrack_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITFileOrCDTrack_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITFileOrCDTrack_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITFileOrCDTrack_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITFileOrCDTrack_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITFileOrCDTrack_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITFileOrCDTrack_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITFileOrCDTrack_GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID) \
+ (This)->lpVtbl -> GetITObjectIDs(This,sourceID,playlistID,trackID,databaseID)
+
+#define IITFileOrCDTrack_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITFileOrCDTrack_put_Name(This,name) \
+ (This)->lpVtbl -> put_Name(This,name)
+
+#define IITFileOrCDTrack_get_Index(This,index) \
+ (This)->lpVtbl -> get_Index(This,index)
+
+#define IITFileOrCDTrack_get_SourceID(This,sourceID) \
+ (This)->lpVtbl -> get_SourceID(This,sourceID)
+
+#define IITFileOrCDTrack_get_PlaylistID(This,playlistID) \
+ (This)->lpVtbl -> get_PlaylistID(This,playlistID)
+
+#define IITFileOrCDTrack_get_TrackID(This,trackID) \
+ (This)->lpVtbl -> get_TrackID(This,trackID)
+
+#define IITFileOrCDTrack_get_TrackDatabaseID(This,databaseID) \
+ (This)->lpVtbl -> get_TrackDatabaseID(This,databaseID)
+
+
+#define IITFileOrCDTrack_Delete(This) \
+ (This)->lpVtbl -> Delete(This)
+
+#define IITFileOrCDTrack_Play(This) \
+ (This)->lpVtbl -> Play(This)
+
+#define IITFileOrCDTrack_AddArtworkFromFile(This,filePath,iArtwork) \
+ (This)->lpVtbl -> AddArtworkFromFile(This,filePath,iArtwork)
+
+#define IITFileOrCDTrack_get_Kind(This,kind) \
+ (This)->lpVtbl -> get_Kind(This,kind)
+
+#define IITFileOrCDTrack_get_Playlist(This,iPlaylist) \
+ (This)->lpVtbl -> get_Playlist(This,iPlaylist)
+
+#define IITFileOrCDTrack_get_Album(This,album) \
+ (This)->lpVtbl -> get_Album(This,album)
+
+#define IITFileOrCDTrack_put_Album(This,album) \
+ (This)->lpVtbl -> put_Album(This,album)
+
+#define IITFileOrCDTrack_get_Artist(This,artist) \
+ (This)->lpVtbl -> get_Artist(This,artist)
+
+#define IITFileOrCDTrack_put_Artist(This,artist) \
+ (This)->lpVtbl -> put_Artist(This,artist)
+
+#define IITFileOrCDTrack_get_BitRate(This,bitrate) \
+ (This)->lpVtbl -> get_BitRate(This,bitrate)
+
+#define IITFileOrCDTrack_get_BPM(This,beatsPerMinute) \
+ (This)->lpVtbl -> get_BPM(This,beatsPerMinute)
+
+#define IITFileOrCDTrack_put_BPM(This,beatsPerMinute) \
+ (This)->lpVtbl -> put_BPM(This,beatsPerMinute)
+
+#define IITFileOrCDTrack_get_Comment(This,comment) \
+ (This)->lpVtbl -> get_Comment(This,comment)
+
+#define IITFileOrCDTrack_put_Comment(This,comment) \
+ (This)->lpVtbl -> put_Comment(This,comment)
+
+#define IITFileOrCDTrack_get_Compilation(This,isCompilation) \
+ (This)->lpVtbl -> get_Compilation(This,isCompilation)
+
+#define IITFileOrCDTrack_put_Compilation(This,shouldBeCompilation) \
+ (This)->lpVtbl -> put_Compilation(This,shouldBeCompilation)
+
+#define IITFileOrCDTrack_get_Composer(This,composer) \
+ (This)->lpVtbl -> get_Composer(This,composer)
+
+#define IITFileOrCDTrack_put_Composer(This,composer) \
+ (This)->lpVtbl -> put_Composer(This,composer)
+
+#define IITFileOrCDTrack_get_DateAdded(This,dateAdded) \
+ (This)->lpVtbl -> get_DateAdded(This,dateAdded)
+
+#define IITFileOrCDTrack_get_DiscCount(This,discCount) \
+ (This)->lpVtbl -> get_DiscCount(This,discCount)
+
+#define IITFileOrCDTrack_put_DiscCount(This,discCount) \
+ (This)->lpVtbl -> put_DiscCount(This,discCount)
+
+#define IITFileOrCDTrack_get_DiscNumber(This,discNumber) \
+ (This)->lpVtbl -> get_DiscNumber(This,discNumber)
+
+#define IITFileOrCDTrack_put_DiscNumber(This,discNumber) \
+ (This)->lpVtbl -> put_DiscNumber(This,discNumber)
+
+#define IITFileOrCDTrack_get_Duration(This,duration) \
+ (This)->lpVtbl -> get_Duration(This,duration)
+
+#define IITFileOrCDTrack_get_Enabled(This,isEnabled) \
+ (This)->lpVtbl -> get_Enabled(This,isEnabled)
+
+#define IITFileOrCDTrack_put_Enabled(This,shouldBeEnabled) \
+ (This)->lpVtbl -> put_Enabled(This,shouldBeEnabled)
+
+#define IITFileOrCDTrack_get_EQ(This,eq) \
+ (This)->lpVtbl -> get_EQ(This,eq)
+
+#define IITFileOrCDTrack_put_EQ(This,eq) \
+ (This)->lpVtbl -> put_EQ(This,eq)
+
+#define IITFileOrCDTrack_put_Finish(This,finish) \
+ (This)->lpVtbl -> put_Finish(This,finish)
+
+#define IITFileOrCDTrack_get_Finish(This,finish) \
+ (This)->lpVtbl -> get_Finish(This,finish)
+
+#define IITFileOrCDTrack_get_Genre(This,genre) \
+ (This)->lpVtbl -> get_Genre(This,genre)
+
+#define IITFileOrCDTrack_put_Genre(This,genre) \
+ (This)->lpVtbl -> put_Genre(This,genre)
+
+#define IITFileOrCDTrack_get_Grouping(This,grouping) \
+ (This)->lpVtbl -> get_Grouping(This,grouping)
+
+#define IITFileOrCDTrack_put_Grouping(This,grouping) \
+ (This)->lpVtbl -> put_Grouping(This,grouping)
+
+#define IITFileOrCDTrack_get_KindAsString(This,kind) \
+ (This)->lpVtbl -> get_KindAsString(This,kind)
+
+#define IITFileOrCDTrack_get_ModificationDate(This,dateModified) \
+ (This)->lpVtbl -> get_ModificationDate(This,dateModified)
+
+#define IITFileOrCDTrack_get_PlayedCount(This,playedCount) \
+ (This)->lpVtbl -> get_PlayedCount(This,playedCount)
+
+#define IITFileOrCDTrack_put_PlayedCount(This,playedCount) \
+ (This)->lpVtbl -> put_PlayedCount(This,playedCount)
+
+#define IITFileOrCDTrack_get_PlayedDate(This,playedDate) \
+ (This)->lpVtbl -> get_PlayedDate(This,playedDate)
+
+#define IITFileOrCDTrack_put_PlayedDate(This,playedDate) \
+ (This)->lpVtbl -> put_PlayedDate(This,playedDate)
+
+#define IITFileOrCDTrack_get_PlayOrderIndex(This,index) \
+ (This)->lpVtbl -> get_PlayOrderIndex(This,index)
+
+#define IITFileOrCDTrack_get_Rating(This,rating) \
+ (This)->lpVtbl -> get_Rating(This,rating)
+
+#define IITFileOrCDTrack_put_Rating(This,rating) \
+ (This)->lpVtbl -> put_Rating(This,rating)
+
+#define IITFileOrCDTrack_get_SampleRate(This,sampleRate) \
+ (This)->lpVtbl -> get_SampleRate(This,sampleRate)
+
+#define IITFileOrCDTrack_get_Size(This,size) \
+ (This)->lpVtbl -> get_Size(This,size)
+
+#define IITFileOrCDTrack_get_Start(This,start) \
+ (This)->lpVtbl -> get_Start(This,start)
+
+#define IITFileOrCDTrack_put_Start(This,start) \
+ (This)->lpVtbl -> put_Start(This,start)
+
+#define IITFileOrCDTrack_get_Time(This,time) \
+ (This)->lpVtbl -> get_Time(This,time)
+
+#define IITFileOrCDTrack_get_TrackCount(This,trackCount) \
+ (This)->lpVtbl -> get_TrackCount(This,trackCount)
+
+#define IITFileOrCDTrack_put_TrackCount(This,trackCount) \
+ (This)->lpVtbl -> put_TrackCount(This,trackCount)
+
+#define IITFileOrCDTrack_get_TrackNumber(This,trackNumber) \
+ (This)->lpVtbl -> get_TrackNumber(This,trackNumber)
+
+#define IITFileOrCDTrack_put_TrackNumber(This,trackNumber) \
+ (This)->lpVtbl -> put_TrackNumber(This,trackNumber)
+
+#define IITFileOrCDTrack_get_VolumeAdjustment(This,volumeAdjustment) \
+ (This)->lpVtbl -> get_VolumeAdjustment(This,volumeAdjustment)
+
+#define IITFileOrCDTrack_put_VolumeAdjustment(This,volumeAdjustment) \
+ (This)->lpVtbl -> put_VolumeAdjustment(This,volumeAdjustment)
+
+#define IITFileOrCDTrack_get_Year(This,year) \
+ (This)->lpVtbl -> get_Year(This,year)
+
+#define IITFileOrCDTrack_put_Year(This,year) \
+ (This)->lpVtbl -> put_Year(This,year)
+
+#define IITFileOrCDTrack_get_Artwork(This,iArtworkCollection) \
+ (This)->lpVtbl -> get_Artwork(This,iArtworkCollection)
+
+
+#define IITFileOrCDTrack_get_Location(This,location) \
+ (This)->lpVtbl -> get_Location(This,location)
+
+#define IITFileOrCDTrack_UpdateInfoFromFile(This) \
+ (This)->lpVtbl -> UpdateInfoFromFile(This)
+
+#define IITFileOrCDTrack_get_Podcast(This,isPodcast) \
+ (This)->lpVtbl -> get_Podcast(This,isPodcast)
+
+#define IITFileOrCDTrack_UpdatePodcastFeed(This) \
+ (This)->lpVtbl -> UpdatePodcastFeed(This)
+
+#define IITFileOrCDTrack_get_RememberBookmark(This,rememberBookmark) \
+ (This)->lpVtbl -> get_RememberBookmark(This,rememberBookmark)
+
+#define IITFileOrCDTrack_put_RememberBookmark(This,shouldRememberBookmark) \
+ (This)->lpVtbl -> put_RememberBookmark(This,shouldRememberBookmark)
+
+#define IITFileOrCDTrack_get_ExcludeFromShuffle(This,excludeFromShuffle) \
+ (This)->lpVtbl -> get_ExcludeFromShuffle(This,excludeFromShuffle)
+
+#define IITFileOrCDTrack_put_ExcludeFromShuffle(This,shouldExcludeFromShuffle) \
+ (This)->lpVtbl -> put_ExcludeFromShuffle(This,shouldExcludeFromShuffle)
+
+#define IITFileOrCDTrack_get_Lyrics(This,lyrics) \
+ (This)->lpVtbl -> get_Lyrics(This,lyrics)
+
+#define IITFileOrCDTrack_put_Lyrics(This,lyrics) \
+ (This)->lpVtbl -> put_Lyrics(This,lyrics)
+
+#define IITFileOrCDTrack_get_Category(This,category) \
+ (This)->lpVtbl -> get_Category(This,category)
+
+#define IITFileOrCDTrack_put_Category(This,category) \
+ (This)->lpVtbl -> put_Category(This,category)
+
+#define IITFileOrCDTrack_get_Description(This,description) \
+ (This)->lpVtbl -> get_Description(This,description)
+
+#define IITFileOrCDTrack_put_Description(This,description) \
+ (This)->lpVtbl -> put_Description(This,description)
+
+#define IITFileOrCDTrack_get_LongDescription(This,longDescription) \
+ (This)->lpVtbl -> get_LongDescription(This,longDescription)
+
+#define IITFileOrCDTrack_put_LongDescription(This,longDescription) \
+ (This)->lpVtbl -> put_LongDescription(This,longDescription)
+
+#define IITFileOrCDTrack_get_BookmarkTime(This,bookmarkTime) \
+ (This)->lpVtbl -> get_BookmarkTime(This,bookmarkTime)
+
+#define IITFileOrCDTrack_put_BookmarkTime(This,bookmarkTime) \
+ (This)->lpVtbl -> put_BookmarkTime(This,bookmarkTime)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_get_Location_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *location);
+
+
+void __RPC_STUB IITFileOrCDTrack_get_Location_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_UpdateInfoFromFile_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This);
+
+
+void __RPC_STUB IITFileOrCDTrack_UpdateInfoFromFile_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_get_Podcast_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isPodcast);
+
+
+void __RPC_STUB IITFileOrCDTrack_get_Podcast_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_UpdatePodcastFeed_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This);
+
+
+void __RPC_STUB IITFileOrCDTrack_UpdatePodcastFeed_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_get_RememberBookmark_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *rememberBookmark);
+
+
+void __RPC_STUB IITFileOrCDTrack_get_RememberBookmark_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_put_RememberBookmark_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldRememberBookmark);
+
+
+void __RPC_STUB IITFileOrCDTrack_put_RememberBookmark_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_get_ExcludeFromShuffle_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *excludeFromShuffle);
+
+
+void __RPC_STUB IITFileOrCDTrack_get_ExcludeFromShuffle_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_put_ExcludeFromShuffle_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldExcludeFromShuffle);
+
+
+void __RPC_STUB IITFileOrCDTrack_put_ExcludeFromShuffle_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_get_Lyrics_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *lyrics);
+
+
+void __RPC_STUB IITFileOrCDTrack_get_Lyrics_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_put_Lyrics_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR lyrics);
+
+
+void __RPC_STUB IITFileOrCDTrack_put_Lyrics_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_get_Category_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *category);
+
+
+void __RPC_STUB IITFileOrCDTrack_get_Category_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_put_Category_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR category);
+
+
+void __RPC_STUB IITFileOrCDTrack_put_Category_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_get_Description_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *description);
+
+
+void __RPC_STUB IITFileOrCDTrack_get_Description_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_put_Description_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR description);
+
+
+void __RPC_STUB IITFileOrCDTrack_put_Description_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_get_LongDescription_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *longDescription);
+
+
+void __RPC_STUB IITFileOrCDTrack_get_LongDescription_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_put_LongDescription_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ BSTR longDescription);
+
+
+void __RPC_STUB IITFileOrCDTrack_put_LongDescription_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_get_BookmarkTime_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *bookmarkTime);
+
+
+void __RPC_STUB IITFileOrCDTrack_get_BookmarkTime_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propput] */ HRESULT STDMETHODCALLTYPE IITFileOrCDTrack_put_BookmarkTime_Proxy(
+ IITFileOrCDTrack __RPC_FAR * This,
+ /* [in] */ long bookmarkTime);
+
+
+void __RPC_STUB IITFileOrCDTrack_put_BookmarkTime_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITFileOrCDTrack_INTERFACE_DEFINED__ */
+
+
+#ifndef __IITPlaylistWindow_INTERFACE_DEFINED__
+#define __IITPlaylistWindow_INTERFACE_DEFINED__
+
+/* interface IITPlaylistWindow */
+/* [hidden][unique][helpstring][dual][uuid][object] */
+
+
+EXTERN_C const IID IID_IITPlaylistWindow;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("349CBB45-2E5A-4822-8E4A-A75555A186F7")
+ IITPlaylistWindow : public IITWindow
+ {
+ public:
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_SelectedTracks(
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection) = 0;
+
+ virtual /* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Playlist(
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IITPlaylistWindowVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
+ IITPlaylistWindow __RPC_FAR * This);
+
+ ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
+ IITPlaylistWindow __RPC_FAR * This);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Name )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ BSTR __RPC_FAR *name);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Kind )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ ITWindowKind __RPC_FAR *kind);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Visible )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isVisible);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Visible )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeVisible);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Resizable )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isResizable);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Minimized )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMinimized);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Minimized )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeMinimized);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Maximizable )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMaximizable);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Maximized )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isMaximized);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Maximized )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeMaximized);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Zoomable )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isZoomable);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Zoomed )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ VARIANT_BOOL __RPC_FAR *isZoomed);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Zoomed )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ VARIANT_BOOL shouldBeZoomed);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Top )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *top);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Top )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ long top);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Left )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *left);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Left )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ long left);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Bottom )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *bottom);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Bottom )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ long bottom);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Right )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *right);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Right )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ long right);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Width )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *width);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Width )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ long width);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Height )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ long __RPC_FAR *height);
+
+ /* [helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Height )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [in] */ long height);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_SelectedTracks )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+ /* [helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Playlist )(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+ END_INTERFACE
+ } IITPlaylistWindowVtbl;
+
+ interface IITPlaylistWindow
+ {
+ CONST_VTBL struct IITPlaylistWindowVtbl __RPC_FAR *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IITPlaylistWindow_QueryInterface(This,riid,ppvObject) \
+ (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
+
+#define IITPlaylistWindow_AddRef(This) \
+ (This)->lpVtbl -> AddRef(This)
+
+#define IITPlaylistWindow_Release(This) \
+ (This)->lpVtbl -> Release(This)
+
+
+#define IITPlaylistWindow_GetTypeInfoCount(This,pctinfo) \
+ (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
+
+#define IITPlaylistWindow_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
+
+#define IITPlaylistWindow_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
+
+#define IITPlaylistWindow_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
+
+
+#define IITPlaylistWindow_get_Name(This,name) \
+ (This)->lpVtbl -> get_Name(This,name)
+
+#define IITPlaylistWindow_get_Kind(This,kind) \
+ (This)->lpVtbl -> get_Kind(This,kind)
+
+#define IITPlaylistWindow_get_Visible(This,isVisible) \
+ (This)->lpVtbl -> get_Visible(This,isVisible)
+
+#define IITPlaylistWindow_put_Visible(This,shouldBeVisible) \
+ (This)->lpVtbl -> put_Visible(This,shouldBeVisible)
+
+#define IITPlaylistWindow_get_Resizable(This,isResizable) \
+ (This)->lpVtbl -> get_Resizable(This,isResizable)
+
+#define IITPlaylistWindow_get_Minimized(This,isMinimized) \
+ (This)->lpVtbl -> get_Minimized(This,isMinimized)
+
+#define IITPlaylistWindow_put_Minimized(This,shouldBeMinimized) \
+ (This)->lpVtbl -> put_Minimized(This,shouldBeMinimized)
+
+#define IITPlaylistWindow_get_Maximizable(This,isMaximizable) \
+ (This)->lpVtbl -> get_Maximizable(This,isMaximizable)
+
+#define IITPlaylistWindow_get_Maximized(This,isMaximized) \
+ (This)->lpVtbl -> get_Maximized(This,isMaximized)
+
+#define IITPlaylistWindow_put_Maximized(This,shouldBeMaximized) \
+ (This)->lpVtbl -> put_Maximized(This,shouldBeMaximized)
+
+#define IITPlaylistWindow_get_Zoomable(This,isZoomable) \
+ (This)->lpVtbl -> get_Zoomable(This,isZoomable)
+
+#define IITPlaylistWindow_get_Zoomed(This,isZoomed) \
+ (This)->lpVtbl -> get_Zoomed(This,isZoomed)
+
+#define IITPlaylistWindow_put_Zoomed(This,shouldBeZoomed) \
+ (This)->lpVtbl -> put_Zoomed(This,shouldBeZoomed)
+
+#define IITPlaylistWindow_get_Top(This,top) \
+ (This)->lpVtbl -> get_Top(This,top)
+
+#define IITPlaylistWindow_put_Top(This,top) \
+ (This)->lpVtbl -> put_Top(This,top)
+
+#define IITPlaylistWindow_get_Left(This,left) \
+ (This)->lpVtbl -> get_Left(This,left)
+
+#define IITPlaylistWindow_put_Left(This,left) \
+ (This)->lpVtbl -> put_Left(This,left)
+
+#define IITPlaylistWindow_get_Bottom(This,bottom) \
+ (This)->lpVtbl -> get_Bottom(This,bottom)
+
+#define IITPlaylistWindow_put_Bottom(This,bottom) \
+ (This)->lpVtbl -> put_Bottom(This,bottom)
+
+#define IITPlaylistWindow_get_Right(This,right) \
+ (This)->lpVtbl -> get_Right(This,right)
+
+#define IITPlaylistWindow_put_Right(This,right) \
+ (This)->lpVtbl -> put_Right(This,right)
+
+#define IITPlaylistWindow_get_Width(This,width) \
+ (This)->lpVtbl -> get_Width(This,width)
+
+#define IITPlaylistWindow_put_Width(This,width) \
+ (This)->lpVtbl -> put_Width(This,width)
+
+#define IITPlaylistWindow_get_Height(This,height) \
+ (This)->lpVtbl -> get_Height(This,height)
+
+#define IITPlaylistWindow_put_Height(This,height) \
+ (This)->lpVtbl -> put_Height(This,height)
+
+
+#define IITPlaylistWindow_get_SelectedTracks(This,iTrackCollection) \
+ (This)->lpVtbl -> get_SelectedTracks(This,iTrackCollection)
+
+#define IITPlaylistWindow_get_Playlist(This,iPlaylist) \
+ (This)->lpVtbl -> get_Playlist(This,iPlaylist)
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylistWindow_get_SelectedTracks_Proxy(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ IITTrackCollection __RPC_FAR *__RPC_FAR *iTrackCollection);
+
+
+void __RPC_STUB IITPlaylistWindow_get_SelectedTracks_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+/* [helpstring][propget] */ HRESULT STDMETHODCALLTYPE IITPlaylistWindow_get_Playlist_Proxy(
+ IITPlaylistWindow __RPC_FAR * This,
+ /* [retval][out] */ IITPlaylist __RPC_FAR *__RPC_FAR *iPlaylist);
+
+
+void __RPC_STUB IITPlaylistWindow_get_Playlist_Stub(
+ IRpcStubBuffer *This,
+ IRpcChannelBuffer *_pRpcChannelBuffer,
+ PRPC_MESSAGE _pRpcMessage,
+ DWORD *_pdwStubPhase);
+
+
+
+#endif /* __IITPlaylistWindow_INTERFACE_DEFINED__ */
+
+#endif /* __iTunesLib_LIBRARY_DEFINED__ */
+
+/* Additional Prototypes for ALL interfaces */
+
+/* end of Additional Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Plugins/listeningto/players/iTunesCOMInterface_i.c b/Plugins/listeningto/players/iTunesCOMInterface_i.c
new file mode 100644
index 0000000..67e71f6
--- /dev/null
+++ b/Plugins/listeningto/players/iTunesCOMInterface_i.c
@@ -0,0 +1,140 @@
+/* this file contains the actual definitions of */
+/* the IIDs and CLSIDs */
+
+/* link this file in with the server and any clients */
+
+
+/* File created by MIDL compiler version 5.01.0164 */
+/* at Tue Sep 06 13:11:55 2005
+ */
+/* Compiler settings for iTunesCOMInterface.idl:
+ Oicf (OptLev=i2), W1, Zp8, env=Win32, ms_ext, c_ext
+ error checks: allocation ref bounds_check enum stub_data
+*/
+//@@MIDL_FILE_HEADING( )
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+
+#ifndef __IID_DEFINED__
+#define __IID_DEFINED__
+
+typedef struct _IID
+{
+ unsigned long x;
+ unsigned short s1;
+ unsigned short s2;
+ unsigned char c[8];
+} IID;
+
+#endif // __IID_DEFINED__
+
+#ifndef CLSID_DEFINED
+#define CLSID_DEFINED
+typedef IID CLSID;
+#endif // CLSID_DEFINED
+
+const IID LIBID_iTunesLib = {0x9E93C96F,0xCF0D,0x43f6,{0x8B,0xA8,0xB8,0x07,0xA3,0x37,0x07,0x12}};
+
+
+const IID IID_IITObject = {0x9FAB0E27,0x70D7,0x4e3a,{0x99,0x65,0xB0,0xC8,0xB8,0x86,0x9B,0xB6}};
+
+
+const IID IID_IITSource = {0xAEC1C4D3,0xAEF1,0x4255,{0xB8,0x92,0x3E,0x3D,0x13,0xAD,0xFD,0xF9}};
+
+
+const IID IID_IITSourceCollection = {0x2FF6CE20,0xFF87,0x4183,{0xB0,0xB3,0xF3,0x23,0xD0,0x47,0xAF,0x41}};
+
+
+const IID IID_IITEncoder = {0x1CF95A1C,0x55FE,0x4f45,{0xA2,0xD3,0x85,0xAC,0x6C,0x50,0x4A,0x73}};
+
+
+const IID IID_IITEncoderCollection = {0x8862BCA9,0x168D,0x4549,{0xA9,0xD5,0xAD,0xB3,0x5E,0x55,0x3B,0xA6}};
+
+
+const IID IID_IITEQPreset = {0x5BE75F4F,0x68FA,0x4212,{0xAC,0xB7,0xBE,0x44,0xEA,0x56,0x97,0x59}};
+
+
+const IID IID_IITEQPresetCollection = {0xAEF4D111,0x3331,0x48da,{0xB0,0xC2,0xB4,0x68,0xD5,0xD6,0x1D,0x08}};
+
+
+const IID IID_IITPlaylist = {0x3D5E072F,0x2A77,0x4b17,{0x9E,0x73,0xE0,0x3B,0x77,0xCC,0xCC,0xA9}};
+
+
+const IID IID_IITOperationStatus = {0x206479C9,0xFE32,0x4f9b,{0xA1,0x8A,0x47,0x5A,0xC9,0x39,0xB4,0x79}};
+
+
+const IID IID_IITConvertOperationStatus = {0x7063AAF6,0xABA0,0x493b,{0xB4,0xFC,0x92,0x0A,0x9F,0x10,0x58,0x75}};
+
+
+const IID IID_IITLibraryPlaylist = {0x53AE1704,0x491C,0x4289,{0x94,0xA0,0x95,0x88,0x15,0x67,0x5A,0x3D}};
+
+
+const IID IID_IITUserPlaylist = {0x0A504DED,0xA0B5,0x465a,{0x8A,0x94,0x50,0xE2,0x0D,0x7D,0xF6,0x92}};
+
+
+const IID IID_IITTrack = {0x4CB0915D,0x1E54,0x4727,{0xBA,0xF3,0xCE,0x6C,0xC9,0xA2,0x25,0xA1}};
+
+
+const IID IID_IITTrackCollection = {0x755D76F1,0x6B85,0x4ce4,{0x8F,0x5F,0xF8,0x8D,0x97,0x43,0xDC,0xD8}};
+
+
+const IID IID_IITVisual = {0x340F3315,0xED72,0x4c09,{0x9A,0xCF,0x21,0xEB,0x4B,0xDF,0x99,0x31}};
+
+
+const IID IID_IITVisualCollection = {0x88A4CCDD,0x114F,0x4043,{0xB6,0x9B,0x84,0xD4,0xE6,0x27,0x49,0x57}};
+
+
+const IID IID_IITWindow = {0x370D7BE0,0x3A89,0x4a42,{0xB9,0x02,0xC7,0x5F,0xC1,0x38,0xBE,0x09}};
+
+
+const IID IID_IITBrowserWindow = {0xC999F455,0xC4D5,0x4aa4,{0x82,0x77,0xF9,0x97,0x53,0x69,0x99,0x74}};
+
+
+const IID IID_IITWindowCollection = {0x3D8DE381,0x6C0E,0x481f,{0xA8,0x65,0xE2,0x38,0x5F,0x59,0xFA,0x43}};
+
+
+const IID IID_IiTunes = {0x9DD6680B,0x3EDC,0x40db,{0xA7,0x71,0xE6,0xFE,0x48,0x32,0xE3,0x4A}};
+
+
+const IID DIID__IiTunesEvents = {0x5846EB78,0x317E,0x4b6f,{0xB0,0xC3,0x11,0xEE,0x8C,0x8F,0xEE,0xF2}};
+
+
+const IID DIID__IITConvertOperationStatusEvents = {0x5C47A705,0x8E8A,0x45a1,{0x9E,0xED,0x71,0xC9,0x93,0xF0,0xBF,0x60}};
+
+
+const CLSID CLSID_iTunesApp = {0xDC0C2640,0x1415,0x4644,{0x87,0x5C,0x6F,0x4D,0x76,0x98,0x39,0xBA}};
+
+
+const CLSID CLSID_iTunesConvertOperationStatus = {0xD06596AD,0xC900,0x41b2,{0xBC,0x68,0x1B,0x48,0x64,0x50,0xFC,0x56}};
+
+
+const IID IID_IITArtwork = {0xD0A6C1F8,0xBF3D,0x4cd8,{0xAC,0x47,0xFE,0x32,0xBD,0xD1,0x72,0x57}};
+
+
+const IID IID_IITArtworkCollection = {0xBF2742D7,0x418C,0x4858,{0x9A,0xF9,0x29,0x81,0xB0,0x62,0xD2,0x3E}};
+
+
+const IID IID_IITURLTrack = {0x1116E3B5,0x29FD,0x4393,{0xA7,0xBD,0x45,0x4E,0x5E,0x32,0x79,0x00}};
+
+
+const IID IID_IITAudioCDPlaylist = {0xCF496DF3,0x0FED,0x4d7d,{0x9B,0xD8,0x52,0x9B,0x6E,0x8A,0x08,0x2E}};
+
+
+const IID IID_IITPlaylistCollection = {0xFF194254,0x909D,0x4437,{0x9C,0x50,0x3A,0xAC,0x2A,0xE6,0x30,0x5C}};
+
+
+const IID IID_IITIPodSource = {0xCF4D8ACE,0x1720,0x4fb9,{0xB0,0xAE,0x98,0x77,0x24,0x9E,0x89,0xB0}};
+
+
+const IID IID_IITFileOrCDTrack = {0x00D7FE99,0x7868,0x4cc7,{0xAD,0x9E,0xAC,0xFD,0x70,0xD0,0x95,0x66}};
+
+
+const IID IID_IITPlaylistWindow = {0x349CBB45,0x2E5A,0x4822,{0x8E,0x4A,0xA7,0x55,0x55,0xA1,0x86,0xF7}};
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/Plugins/listeningto/players/itunes.cpp b/Plugins/listeningto/players/itunes.cpp
new file mode 100644
index 0000000..b00e6e4
--- /dev/null
+++ b/Plugins/listeningto/players/itunes.cpp
@@ -0,0 +1,188 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "..\\commons.h"
+
+
+extern "C"
+{
+#include "iTunesCOMInterface_i.c"
+}
+
+
+
+ITunes::ITunes()
+{
+ name = _T("iTunes");
+ needPoll = TRUE;
+
+ filename[0] = L'\0';
+
+ hwnd = NULL;
+ iTunesApp = NULL;
+ track = NULL;
+ file = NULL;
+ ret = NULL;
+}
+
+
+void ITunes::FindWindow()
+{
+ hwnd = ::FindWindow(_T("iTunes"), _T("iTunes"));
+}
+
+
+void ITunes::FreeTempData()
+{
+#define RELEASE(_x_) if (_x_ != NULL) { _x_->Release(); _x_ = NULL; }
+
+ RELEASE(file);
+ RELEASE(track);
+ RELEASE(iTunesApp);
+
+ if (ret != NULL)
+ {
+ SysFreeString(ret);
+ ret = NULL;
+ }
+}
+
+
+#define CALL(_F_) hr = _F_; if (FAILED(hr)) return FALSE
+
+// Init data and put filename playing in ret and ->fi.filename
+BOOL ITunes::InitAndGetFilename()
+{
+ HRESULT hr;
+
+ // Find window
+ FindWindow();
+ if (hwnd == NULL)
+ return FALSE;
+
+ CALL( CoCreateInstance(CLSID_iTunesApp, NULL, CLSCTX_LOCAL_SERVER, __uuidof(iTunesApp), (void **)&iTunesApp) );
+
+ ITPlayerState state;
+ CALL( iTunesApp->get_PlayerState(&state) );
+ if (state == ITPlayerStateStopped)
+ return FALSE;
+
+ CALL( iTunesApp->get_CurrentTrack(&track) );
+ if (track == NULL)
+ return FALSE;
+
+ CALL( track->QueryInterface(__uuidof(file), (void **)&file) );
+
+ CALL( file->get_Location(&ret) );
+
+ return !IsEmpty(ret);
+}
+
+
+BOOL ITunes::FillCache()
+{
+ HRESULT hr;
+ long lret;
+
+ CALL( track->get_Album(&ret) );
+ listening_info.ptszAlbum = U2T(ret);
+
+ CALL( track->get_Artist(&ret) );
+ listening_info.ptszArtist = U2T(ret);
+
+ CALL( track->get_Name(&ret) );
+ listening_info.ptszTitle = U2T(ret);
+
+ CALL( track->get_Year(&lret) );
+ if (lret > 0)
+ {
+ listening_info.ptszYear = (TCHAR*) mir_alloc(10 * sizeof(TCHAR));
+ _itot(lret, listening_info.ptszYear, 10);
+ }
+
+ CALL( track->get_TrackNumber(&lret) );
+ if (lret > 0)
+ {
+ listening_info.ptszTrack = (TCHAR*) mir_alloc(10 * sizeof(TCHAR));
+ _itot(lret, listening_info.ptszTrack, 10);
+ }
+
+ CALL( track->get_Genre(&ret) );
+ listening_info.ptszGenre = U2T(ret);
+
+ CALL( track->get_Duration(&lret) );
+ if (lret > 0)
+ {
+ listening_info.ptszLength = (TCHAR*) mir_alloc(10 * sizeof(TCHAR));
+
+ int s = lret % 60;
+ int m = (lret / 60) % 60;
+ int h = (lret / 60) / 60;
+
+ if (h > 0)
+ mir_sntprintf(listening_info.ptszLength, 9, _T("%d:%02d:%02d"), h, m, s);
+ else
+ mir_sntprintf(listening_info.ptszLength, 9, _T("%d:%02d"), m, s);
+ }
+
+ listening_info.ptszType = mir_tstrdup(_T("Music"));
+
+ if (listening_info.ptszTitle == NULL)
+ {
+ // Get from filename
+ WCHAR *p = wcsrchr(filename, '\\');
+ if (p != NULL)
+ p++;
+ else
+ p = filename;
+
+ listening_info.ptszTitle = mir_u2t(p);
+
+ TCHAR *pt = _tcsrchr(listening_info.ptszTitle, '.');
+ if (pt != NULL)
+ *p = _T('\0');
+ }
+
+ listening_info.ptszPlayer = mir_tstrdup(name);
+
+ listening_info.cbSize = sizeof(listening_info);
+ listening_info.dwFlags = LTI_TCHAR;
+
+ return TRUE;
+}
+
+
+BOOL ITunes::GetListeningInfo(LISTENINGTOINFO *lti)
+{
+ FreeData();
+
+ if (InitAndGetFilename() && strcmpnullW(filename, ret) != 0)
+ {
+ // Fill the data cache
+ wcscpy(filename, ret);
+
+ if (!FillCache())
+ FreeData();
+ }
+
+ FreeTempData();
+
+ return Player::GetListeningInfo(lti);
+}
diff --git a/Plugins/listeningto/players/itunes.h b/Plugins/listeningto/players/itunes.h
new file mode 100644
index 0000000..bce9318
--- /dev/null
+++ b/Plugins/listeningto/players/itunes.h
@@ -0,0 +1,48 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+extern "C"
+{
+#include "iTunesCOMInterface.h"
+}
+
+
+class ITunes : public Player
+{
+protected:
+ WCHAR filename[1024];
+
+ HWND hwnd;
+ IiTunes *iTunesApp;
+ IITTrack *track;
+ IITFileOrCDTrack *file;
+ BSTR ret;
+
+ void FindWindow();
+ BOOL InitTempData();
+ void FreeTempData();
+ BOOL InitAndGetFilename();
+ int GetMetadata(char *metadata, TCHAR **data);
+ BOOL FillCache();
+
+public:
+ ITunes();
+
+ virtual BOOL GetListeningInfo(LISTENINGTOINFO *lti);
+};
diff --git a/Plugins/listeningto/players/mlt_winamp/GEN.H b/Plugins/listeningto/players/mlt_winamp/GEN.H
new file mode 100644
index 0000000..d22f220
--- /dev/null
+++ b/Plugins/listeningto/players/mlt_winamp/GEN.H
@@ -0,0 +1,22 @@
+#define GEN_INIT_SUCCESS 0
+
+
+typedef struct {
+ int version;
+ char *description;
+ int (*init)();
+ void (*config)();
+ void (*quit)();
+ HWND hwndParent;
+ HINSTANCE hDllInstance;
+} winampGeneralPurposePlugin;
+
+#define GPPHDR_VER 0x10
+#ifdef __cplusplus
+extern "C" {
+#endif
+//extern winampGeneralPurposePlugin *gen_plugins[256];
+typedef winampGeneralPurposePlugin * (*winampGeneralPurposePluginGetter)();
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/players/mlt_winamp/mlt_winamp.cpp b/Plugins/listeningto/players/mlt_winamp/mlt_winamp.cpp
new file mode 100644
index 0000000..948ded1
--- /dev/null
+++ b/Plugins/listeningto/players/mlt_winamp/mlt_winamp.cpp
@@ -0,0 +1,465 @@
+/*
+Copyright (C) 2006 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <process.h>
+#include "..\..\m_listeningto.h"
+
+#include "wa_ipc.h"
+#include "GEN.h"
+
+// Plugin data //////////////////////////////////////////////////////////////////////////
+
+int init();
+void quit();
+void config();
+
+winampGeneralPurposePlugin plugin = {
+ GPPHDR_VER,
+ "Miranda ListeningTo Winamp Plugin", // Plug-in description
+ init,
+ config,
+ quit,
+};
+
+
+// Globals //////////////////////////////////////////////////////////////////////////////
+
+
+#define MIRANDA_DW_PROTECTION 0x8754
+
+#define MESSAGE_WINDOWCLASS MIRANDA_WINDOWCLASS ".Winamp"
+
+#define DATA_SIZE 1024
+
+#define WA_STATE_CHANGE 0x0000029A
+
+WNDPROC oldWndProc = NULL;
+WNDPROC oldMainWndProc = NULL;
+HMENU hMenuCreated = NULL;
+HWND hMsgWnd = NULL;
+HWND hPlWnd = NULL;
+HINSTANCE hInst = NULL;
+
+// Message window proc
+LRESULT CALLBACK MsgWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+// Playlist window message processor
+LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+
+
+// Functions ////////////////////////////////////////////////////////////////////////////
+
+
+void WindowThread(void *param)
+{
+ // Create window
+ WNDCLASS wc = {0};
+ wc.lpfnWndProc = MsgWndProc;
+ wc.hInstance = hInst;
+ wc.lpszClassName = MESSAGE_WINDOWCLASS;
+
+ RegisterClass(&wc);
+
+ hMsgWnd = CreateWindow(MESSAGE_WINDOWCLASS, _T("Miranda ListeningTo Winamp Plugin"),
+ 0, 0, 0, 0, 0, NULL, NULL, hInst, NULL);
+
+ if (hMsgWnd != NULL)
+ if (FindWindow(MIRANDA_WINDOWCLASS, NULL) != NULL)
+ SetTimer(hMsgWnd, 0, 5000, NULL);
+
+ MSG msg;
+ BOOL bRet;
+ while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
+ {
+ if (bRet == -1)
+ {
+ // handle the error and possibly exit
+ break;
+ }
+ else
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+
+ _endthread();
+}
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
+{
+ if (fdwReason == DLL_PROCESS_ATTACH)
+ {
+ hInst = hInstDll;
+
+ plugin.hwndParent = NULL;
+
+ _beginthread(WindowThread, 0, NULL);
+ }
+
+ return TRUE;
+}
+
+
+// Winamp interface function
+extern "C" winampGeneralPurposePlugin * winampGetGeneralPurposePlugin()
+{
+ KillTimer(hMsgWnd, 0);
+
+ return &plugin;
+}
+
+BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
+{
+ // Find the windows
+ char class_name[1024];
+ if (GetClassName(hwnd, class_name, sizeof(class_name)))
+ {
+ class_name[sizeof(class_name)-1] = '\0';
+
+ if (strcmpi(MIRANDA_WINDOWCLASS, class_name) == 0)
+ {
+ COPYDATASTRUCT *cds = (COPYDATASTRUCT *)lParam;
+ SendMessage(hwnd, WM_COPYDATA, (WPARAM) plugin.hwndParent, (LPARAM) cds);
+ }
+ }
+
+ return TRUE;
+}
+
+inline void SendData(WCHAR *text)
+{
+ static WCHAR lastMsg[1024] = L"";
+
+ if (wcscmp(lastMsg, text) == 0)
+ return;
+
+ // Prepare the struct
+ COPYDATASTRUCT cds;
+ cds.dwData = MIRANDA_DW_PROTECTION;
+ cds.lpData = text;
+ cds.cbData = (wcslen(text) + 1) * sizeof(WCHAR);
+
+ EnumWindows(EnumWindowsProc, (LPARAM) &cds);
+
+ wcsncpy(lastMsg, text, 1024);
+ lastMsg[1023] = L'\0';
+}
+
+
+void Concat(WCHAR *data, size_t &size, char *str, size_t len = 0)
+{
+ if (size < 3 * sizeof(WCHAR))
+ return;
+
+ if (str != NULL)
+ {
+ if (len == 0)
+ len = strlen(str);
+
+ if (size >= len + 3)
+ {
+ MultiByteToWideChar(CP_ACP, 0, str, len * sizeof(char), &data[DATA_SIZE - size], size * sizeof(WCHAR));
+ size -= len;
+ data[DATA_SIZE - size] = L'\0';
+ }
+ }
+
+ wcscat(data, L"\\0");
+ size -= 2;
+}
+
+
+void GetMetadata(extendedFileInfoStruct *efi, char *field, WCHAR *data, size_t &size)
+{
+ efi->ret[0] = '\0';
+ efi->metadata = field;
+ if (SendMessage(plugin.hwndParent, WM_WA_IPC, (WPARAM) efi, IPC_GET_EXTENDED_FILE_INFO_HOOKABLE) && efi->ret[0] != '\0')
+ {
+ Concat(data, size, efi->ret);
+ }
+ else
+ {
+ Concat(data, size, NULL);
+ }
+}
+
+
+void SendDataToMiranda(char *filename, char *title)
+{
+ extendedFileInfoStruct efi;
+ char tmp[256];
+
+ efi.ret = tmp;
+ efi.retlen = sizeof(tmp);
+ efi.filename = filename;
+
+ WCHAR data[DATA_SIZE];
+ size_t size = DATA_SIZE;
+ data[0] = L'\0';
+
+ // L"<Status 0-stoped 1-playing>\\0<Player>\\0<Type>\\0<Title>\\0<Artist>\\0<Album>\\0<Track>\\0<Year>\\0<Genre>\\0<Length (secs)>\\0\\0"
+ Concat(data, size, "1");
+ Concat(data, size, "Winamp");
+
+ int version = SendMessage(plugin.hwndParent, WM_WA_IPC, 0, IPC_GETVERSION);
+ BOOL is_radio = (strstr(filename, "://") != 0) && (strncmp(filename, "cda://", 6) != 0);
+
+ if (is_radio)
+ Concat(data, size, "Radio");
+ else if (WINAMP_VERSION_MAJOR(version) >= 5 && SendMessage(plugin.hwndParent, WM_WA_IPC, 0, IPC_IS_PLAYING_VIDEO))
+ Concat(data, size, "Video");
+ else
+ Concat(data, size, "Music");
+
+ efi.ret[0] = '\0';
+ efi.metadata = "TITLE";
+ if (SendMessage(plugin.hwndParent, WM_WA_IPC, (WPARAM) &efi, IPC_GET_EXTENDED_FILE_INFO_HOOKABLE) && efi.ret[0] != '\0')
+ {
+ Concat(data, size, efi.ret);
+ }
+ else if (title != NULL && title[0] != '\0' && strcmpi(title, filename) != 0)
+ {
+ Concat(data, size, title);
+ }
+ else
+ {
+ char *name = strrchr(filename, '\\');
+ if (name == NULL)
+ strrchr(filename, '/');
+
+ if (name == NULL)
+ {
+ Concat(data, size, NULL);
+ }
+ else
+ {
+ char *dot = strrchr(name, '.');
+ Concat(data, size, name + 1, dot == NULL ? 0 : dot - name - 1);
+ }
+ }
+
+ GetMetadata(&efi, "ARTIST", data, size);
+ GetMetadata(&efi, "ALBUM", data, size);
+ GetMetadata(&efi, "TRACK", data, size);
+ GetMetadata(&efi, "YEAR", data, size);
+ GetMetadata(&efi, "GENRE", data, size);
+
+ efi.ret[0] = '\0';
+ efi.metadata = "LENGTH";
+ if (SendMessage(plugin.hwndParent, WM_WA_IPC, (WPARAM) &efi, IPC_GET_EXTENDED_FILE_INFO_HOOKABLE)
+ && efi.ret[0] != '\0' && efi.ret[1] != '\0')
+ {
+ char tmp[10];
+ itoa(atoi(efi.ret) / 1000, tmp, 10);
+ Concat(data, size, tmp);
+ }
+ else
+ {
+ Concat(data, size, NULL);
+ }
+ Concat(data, size, NULL);
+
+ SendData(data);
+}
+
+
+// Message window proc
+LRESULT CALLBACK MsgWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static BOOL last_was_stop = TRUE;
+ static DWORD last_notification = 0;
+ static char last_filename[1024] = {0};
+
+ switch(message)
+ {
+ case WM_TIMER:
+ {
+ KillTimer(hwnd, wParam);
+
+ if (wParam == 0)
+ {
+ // Startup
+ if (plugin.hwndParent == NULL)
+ {
+ plugin.hwndParent = FindWindow("Winamp v1.x", NULL);
+ if (plugin.hwndParent != NULL)
+ {
+ init();
+
+ // If playing, show current song
+ if (SendMessage(plugin.hwndParent, WM_WA_IPC, 0, IPC_ISPLAYING) == 1)
+ if (FindWindow(MIRANDA_WINDOWCLASS, NULL) != NULL)
+ SetTimer(hMsgWnd, 1, 500, NULL);
+ }
+ }
+ }
+ else if (wParam == 1)
+ {
+ // Song change
+ if (SendMessage(plugin.hwndParent, WM_WA_IPC, 0, IPC_ISPLAYING) == 1)
+ {
+ int track = SendMessage(plugin.hwndParent, WM_WA_IPC, 0, IPC_GETLISTPOS);
+ char *filename = (char *) SendMessage(plugin.hwndParent, WM_WA_IPC, track, IPC_GETPLAYLISTFILE);
+
+ if (filename == NULL || filename[0] == '\0')
+ {
+ if (!last_was_stop)
+ {
+ last_was_stop = TRUE;
+
+ if (FindWindow(MIRANDA_WINDOWCLASS, NULL) != NULL)
+ SendData(L"0\\0Winamp\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0");
+ }
+ }
+ else
+ {
+ BOOL is_radio = (strstr(filename, "://") != 0);
+ if (last_was_stop || is_radio || strcmpi(last_filename, filename) != 0)
+ {
+ last_was_stop = FALSE;
+ strncpy(last_filename, filename, sizeof(last_filename));
+ last_filename[sizeof(last_filename) - 1] = '\0';
+
+ // Miranda is running?
+ if (FindWindow(MIRANDA_WINDOWCLASS, NULL) != NULL)
+ SendDataToMiranda(last_filename, (char *) SendMessage(plugin.hwndParent, WM_WA_IPC, track, IPC_GETPLAYLISTTITLE));
+
+ if (is_radio)
+ // To try to get info from radio stations
+ SetTimer(hMsgWnd, 1, 3000, NULL);
+ }
+ }
+ }
+ else
+ {
+ if (!last_was_stop)
+ {
+ last_was_stop = TRUE;
+
+ if (FindWindow(MIRANDA_WINDOWCLASS, NULL) != NULL)
+ SendData(L"0\\0Winamp\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0");
+ }
+ }
+ }
+
+ break;
+ }
+ }
+
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+// Playlist window message processor
+LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case WM_USER:
+ {
+ if(wParam == WA_STATE_CHANGE)
+ {
+ int type = HIWORD(lParam);
+ if(type == 0x4000 || type == 0)
+ {
+ KillTimer(hMsgWnd, 1);
+ SetTimer(hMsgWnd, 1, 1000, NULL);
+ }
+ }
+ break;
+ }
+ }
+
+ return CallWindowProc(oldWndProc, hwnd, message, wParam, lParam);
+}
+
+
+LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case WM_COMMAND:
+ {
+ switch(wParam)
+ {
+ case 40045: // Play
+ case 40046: // Pause
+ {
+ KillTimer(hMsgWnd, 1);
+ SetTimer(hMsgWnd, 1, 500, NULL);
+ break;
+ }
+ }
+ break;
+ }
+ case WM_WA_IPC:
+ {
+ switch(lParam)
+ {
+ case IPC_PLAYING_FILE:
+ {
+ KillTimer(hMsgWnd, 1);
+ SetTimer(hMsgWnd, 1, 500, NULL);
+ break;
+ }
+ }
+ break;
+ }
+ case WM_CLOSE:
+ {
+ PostMessage(hMsgWnd, WM_TIMER, 1, 0);
+ PostMessage(hMsgWnd, WM_CLOSE, 0, 0);
+ break;
+ }
+ }
+
+ return CallWindowProc(oldMainWndProc, hwnd, message, wParam, lParam);
+}
+
+
+void quit()
+{
+ if (oldMainWndProc != NULL)
+ SetWindowLong(plugin.hwndParent, GWL_WNDPROC, (LONG) oldMainWndProc);
+
+ if (oldWndProc != NULL)
+ SetWindowLong(hPlWnd, GWL_WNDPROC, (LONG) oldWndProc);
+}
+
+
+int init()
+{
+ KillTimer(hMsgWnd, 0);
+
+ oldMainWndProc = (WNDPROC)SetWindowLong(plugin.hwndParent, GWL_WNDPROC, (LONG) MainWndProc);
+
+ hPlWnd = (HWND) SendMessage(plugin.hwndParent, WM_WA_IPC, IPC_GETWND_PE, IPC_GETWND);
+ oldWndProc = (WNDPROC) SetWindowLong(hPlWnd, GWL_WNDPROC, (LONG)WndProc);
+
+ return 0;
+}
+
+void config() {
+ MessageBox(NULL, _T("Copyright (C) 2006 Ricardo Pescuma Domenecci"), _T("Miranda ListeningTo Winamp Plugin"), 0);
+}
diff --git a/Plugins/listeningto/players/mlt_winamp/mlt_winamp.def b/Plugins/listeningto/players/mlt_winamp/mlt_winamp.def
new file mode 100644
index 0000000..bd6c52c
--- /dev/null
+++ b/Plugins/listeningto/players/mlt_winamp/mlt_winamp.def
@@ -0,0 +1,4 @@
+DESCRIPTION 'Miranda ListeningTo Winamp Plugin'
+
+EXPORTS
+ winampGetGeneralPurposePlugin
diff --git a/Plugins/listeningto/players/mlt_winamp/mlt_winamp.dsp b/Plugins/listeningto/players/mlt_winamp/mlt_winamp.dsp
new file mode 100644
index 0000000..65c0805
--- /dev/null
+++ b/Plugins/listeningto/players/mlt_winamp/mlt_winamp.dsp
@@ -0,0 +1,140 @@
+# Microsoft Developer Studio Project File - Name="mlt_winamp" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mlt_winamp - Win32 Debug Winamp
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mlt_winamp.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mlt_winamp.mak" CFG="mlt_winamp - Win32 Debug Winamp"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mlt_winamp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mlt_winamp - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mlt_winamp - Win32 Debug Winamp" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mlt_winamp - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MLT_WINAMP_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MLT_WINAMP_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\..\..\bin\release\Plugins\listeningto\gen_mlt.dll"
+
+!ELSEIF "$(CFG)" == "mlt_winamp - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MLT_WINAMP_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x416 /d "_DEBUG"
+# ADD RSC /l 0x416 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib /nologo /dll /debug /machine:I386 /out:"..\..\..\..\bin\debug unicode\Plugins\listeningto\gen_mlt.dll" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "mlt_winamp - Win32 Debug Winamp"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "mlt_winamp___Win32_Debug_Winamp0"
+# PROP BASE Intermediate_Dir "mlt_winamp___Win32_Debug_Winamp0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x416 /d "_DEBUG"
+# ADD RSC /l 0x416 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib /nologo /dll /debug /machine:I386 /out:"..\..\..\..\bin\debug unicode\Plugins\listeningto\mlt_winamp.dll" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Winamp\plugins\gen_mlt.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "mlt_winamp - Win32 Release"
+# Name "mlt_winamp - Win32 Debug"
+# Name "mlt_winamp - Win32 Debug Winamp"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\mlt_winamp.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mlt_winamp.def
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/Plugins/listeningto/players/mlt_winamp/mlt_winamp.dsw b/Plugins/listeningto/players/mlt_winamp/mlt_winamp.dsw
new file mode 100644
index 0000000..9cc7b29
--- /dev/null
+++ b/Plugins/listeningto/players/mlt_winamp/mlt_winamp.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "mlt_winamp"=.\mlt_winamp.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/Plugins/listeningto/players/mlt_winamp/wa_ipc.h b/Plugins/listeningto/players/mlt_winamp/wa_ipc.h
new file mode 100644
index 0000000..df29611
--- /dev/null
+++ b/Plugins/listeningto/players/mlt_winamp/wa_ipc.h
@@ -0,0 +1,1607 @@
+/*
+** Copyright (C) 2006 Nullsoft, Inc.
+**
+** This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held
+** liable for any damages arising from the use of this software.
+**
+** Permission is granted to anyone to use this software for any purpose, including commercial applications, and to
+** alter it and redistribute it freely, subject to the following restrictions:
+**
+** 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
+** If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+**
+** 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+**
+** 3. This notice may not be removed or altered from any source distribution.
+**
+*/
+
+#ifndef _WA_IPC_H_
+#define _WA_IPC_H_
+
+#include <windows.h>
+#include <stddef.h>
+#if (_MSC_VER <= 1200)
+typedef int intptr_t;
+#endif
+/*
+** This is the modern replacement for the classic 'frontend.h'. Most of these
+** updates are designed for in-process use, i.e. from a plugin.
+**
+*/
+
+/* message used to sent many messages to winamp's main window.
+** most all of the IPC_* messages involve sending the message in the form of:
+** result = SendMessage(hwnd_winamp,WM_WA_IPC,(parameter),IPC_*);
+**
+** When you use SendMessage(hwnd_winamp,WM_WA_IPC,(parameter),IPC_*) and specify a IPC_*
+** which is not currently implemented/supported by the Winamp version being used then it
+** will return 1 for 'result'. This is a good way of helping to check if an api being
+** used which returns a function pointer, etc is even going to be valid.
+*/
+#define WM_WA_IPC WM_USER
+/* but some of them use WM_COPYDATA. be afraid.
+*/
+
+#define WINAMP_VERSION_MAJOR(winampVersion) ((winampVersion & 0x0000FF00) >> 12)
+#define WINAMP_VERSION_MINOR(winampVersion) (winampVersion & 0x000000FF) // returns, i.e. 0x12 for 5.12 and 0x10 for 5.1...
+
+#define IPC_GETVERSION 0
+/* int version = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVERSION);
+**
+** The version returned will be 0x20yx for Winamp 2.yx.
+** Versions previous to Winamp 2.0 typically (but not always) use 0x1zyx for 1.zx.
+** Just a bit weird but that's the way it goes.
+**
+** For Winamp 5.x it uses the format 0x50yx for Winamp 5.yx
+** e.g. 5.01 -> 0x5001
+** 5.09 -> 0x5009
+** 5.1 -> 0x5010
+**
+** Notes: For 5.02 this api will return the same value as for a 5.01 build.
+** For 5.07 this api will return the same value as for a 5.06 build.
+*/
+#define IPC_GETVERSIONSTRING 1
+
+#define IPC_GETREGISTEREDVERSION 770
+
+
+typedef struct {
+ const char *filename;
+ const char *title;
+ int length;
+} enqueueFileWithMetaStruct; // send this to a IPC_PLAYFILE in a non WM_COPYDATA,
+// and you get the nice desired result. if title is NULL, it is treated as a "thing",
+// otherwise it's assumed to be a file (for speed)
+
+typedef struct {
+ const wchar_t *filename;
+ const wchar_t *title;
+ int length;
+} enqueueFileWithMetaStructW;
+
+#define IPC_PLAYFILE 100 // dont be fooled, this is really the same as enqueufile
+#define IPC_ENQUEUEFILE 100
+#define IPC_PLAYFILEW 1100
+/* This is sent as a WM_COPYDATA with IPC_PLAYFILE as the dwData member and the string
+** of the file / playlist to be enqueued into the playlist editor as the lpData member.
+** This will just enqueue the file or files since you can use this to enqueue a playlist.
+** It will not clear the current playlist or change the playback state.
+**
+** COPYDATASTRUCT cds = {0};
+** cds.dwData = IPC_ENQUEUEFILE;
+** cds.lpData = (void*)"c:\\test\\folder\\test.mp3";
+** cds.cbData = lstrlen((char*)cds.lpData)+1; // include space for null char
+** SendMessage(hwnd_winamp,WM_COPYDATA,0,(LPARAM)&cds);
+**
+**
+** With 2.9+ and all of the 5.x versions you can send this as a normal WM_WA_IPC
+** (non WM_COPYDATA) with an enqueueFileWithMetaStruct as the param.
+** If the title member is null then it is treated as a "thing" otherwise it will be
+** assumed to be a file (for speed).
+**
+** enqueueFileWithMetaStruct eFWMS = {0};
+** eFWMS.filename = "c:\\test\\folder\\test.mp3";
+** eFWMS.title = "Whipping Good";
+** eFWMS.length = 300; // this is the number of seconds for the track
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)&eFWMS,IPC_ENQUEUEFILE);
+*/
+
+
+#define IPC_DELETE 101
+#define IPC_DELETE_INT 1101
+/* SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_DELETE);
+** Use this api to clear Winamp's internal playlist.
+** You should not need to use IPC_DELETE_INT since it is used internally by Winamp when
+** it is dealing with some lame Windows Explorer issues (hard to believe that!).
+*/
+
+
+#define IPC_STARTPLAY 102
+#define IPC_STARTPLAY_INT 1102
+/* SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_STARTPLAY);
+** Sending this will start playback and is almost the same as hitting the play button.
+** The IPC_STARTPLAY_INT version is used internally and you should not need to use it
+** since it won't be any fun.
+*/
+
+#define IPC_CHDIR 103
+/* This is sent as a WM_COPYDATA type message with IPC_CHDIR as the dwData value and the
+** directory you want to change to as the lpData member.
+**
+** COPYDATASTRUCT cds = {0};
+** cds.dwData = IPC_CHDIR;
+** cds.lpData = (void*)"c:\\download";
+** cds.cbData = lstrlen((char*)cds.lpData)+1; // include space for null char
+** SendMessage(hwnd_winamp,WM_COPYDATA,0,(LPARAM)&cds);
+**
+** The above example will make Winamp change to the directory 'C:\download'.
+*/
+
+
+#define IPC_ISPLAYING 104
+/* int res = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING);
+** This is sent to retrieve the current playback state of Winamp.
+** If it returns 1, Winamp is playing.
+** If it returns 3, Winamp is paused.
+** If it returns 0, Winamp is not playing.
+*/
+
+
+#define IPC_GETOUTPUTTIME 105
+/* int res = SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETOUTPUTTIME);
+** This api can return two different sets of information about current playback status.
+**
+** If mode = 0 then it will return the position (in ms) of the currently playing track.
+** Will return -1 if Winamp is not playing.
+**
+** If mode = 1 then it will return the current track length (in seconds).
+** Will return -1 if there are no tracks (or possibly if Winamp cannot get the length).
+*/
+
+
+
+#define IPC_JUMPTOTIME 106
+/* (requires Winamp 1.60+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,ms,IPC_JUMPTOTIME);
+** This api sets the current position (in milliseconds) for the currently playing song.
+** The resulting playback position may only be an approximate time since some playback
+** formats do not provide exact seeking e.g. mp3
+** This returns -1 if Winamp is not playing, 1 on end of file, or 0 if it was successful.
+*/
+
+#define IPC_GETMODULENAME 109
+#define IPC_EX_ISRIGHTEXE 666
+/* usually shouldnt bother using these, but here goes:
+** send a WM_COPYDATA with IPC_GETMODULENAME, and an internal
+** flag gets set, which if you send a normal WM_WA_IPC message with
+** IPC_EX_ISRIGHTEXE, it returns whether or not that filename
+** matches. lame, I know.
+*/
+
+#define IPC_WRITEPLAYLIST 120
+/* (requires Winamp 1.666+)
+** int cur = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_WRITEPLAYLIST);
+**
+** IPC_WRITEPLAYLIST will write the current playlist to '<winampdir>\\Winamp.m3u' and
+** will also return the current playlist position (see IPC_GETLISTPOS).
+**
+** This is kinda obsoleted by some of the newer 2.x api items but it still is good for
+** use with a front-end program (instead of a plug-in) and you want to see what is in the
+** current playlist.
+**
+** This api will only save out extended file information in the #EXTINF entry if Winamp
+** has already read the data such as if the file was played of scrolled into view. If
+** Winamp has not read the data then you will only find the file with its filepath entry
+** (as is the base requirements for a m3u playlist).
+*/
+
+
+#define IPC_SETPLAYLISTPOS 121
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,position,IPC_SETPLAYLISTPOS)
+** IPC_SETPLAYLISTPOS sets the playlist position to the specified 'position'.
+** It will not change playback status or anything else. It will just set the current
+** position in the playlist and will update the playlist view if necessary.
+**
+** If you use SendMessage(hwnd_winamp,WM_COMMAND,MAKEWPARAM(WINAMP_BUTTON2,0),0);
+** after using IPC_SETPLAYLISTPOS then Winamp will start playing the file at 'position'.
+*/
+
+
+#define IPC_SETVOLUME 122
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,volume,IPC_SETVOLUME);
+** IPC_SETVOLUME sets the volume of Winamp (between the range of 0 to 255).
+**
+** If you pass 'volume' as -666 then the message will return the current volume.
+** int curvol = SendMessage(hwnd_winamp,WM_WA_IPC,-666,IPC_SETVOLUME);
+*/
+
+
+#define IPC_SETPANNING 123
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,panning,IPC_SETPANNING);
+** IPC_SETPANNING sets the panning of Winamp from 0 (left) to 255 (right).
+**
+** At least in 5.x+ this works from -127 (left) to 127 (right).
+**
+** If you pass 'panning' as -666 to this api then it will return the current panning.
+** int curpan = SendMessage(hwnd_winamp,WM_WA_IPC,-666,IPC_SETPANNING);
+*/
+
+
+#define IPC_GETLISTLENGTH 124
+/* (requires Winamp 2.0+)
+** int length = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTLENGTH);
+** IPC_GETLISTLENGTH returns the length of the current playlist as the number of tracks.
+*/
+
+
+#define IPC_GETLISTPOS 125
+/* (requires Winamp 2.05+)
+** int pos=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS);
+** IPC_GETLISTPOS returns the current playlist position (which is shown in the playlist
+** editor as a differently coloured text entry e.g is yellow for the classic skin).
+**
+** This api is a lot like IPC_WRITEPLAYLIST but a lot faster since it does not have to
+** write out the whole of the current playlist first.
+*/
+
+
+#define IPC_GETINFO 126
+/* (requires Winamp 2.05+)
+** int inf=SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETINFO);
+** IPC_GETINFO returns info about the current playing song. The value
+** it returns depends on the value of 'mode'.
+** Mode Meaning
+** ------------------
+** 0 Samplerate, in kilohertz (i.e. 44)
+** 1 Bitrate (i.e. 128)
+** 2 Channels (i.e. 2)
+** 3 (5+) Video LOWORD=w HIWORD=h
+** 4 (5+) > 65536, string (video description)
+** 5 (5.25+) Samplerate, in hertz (i.e. 44100)
+*/
+
+
+#define IPC_GETEQDATA 127
+/* (requires Winamp 2.05+)
+** int data=SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA);
+** IPC_GETEQDATA queries the status of the EQ.
+** The value returned depends on what 'pos' is set to:
+** Value Meaning
+** ------------------
+** 0-9 The 10 bands of EQ data. 0-63 (+20db - -20db)
+** 10 The preamp value. 0-63 (+20db - -20db)
+** 11 Enabled. zero if disabled, nonzero if enabled.
+** 12 Autoload. zero if disabled, nonzero if enabled.
+*/
+
+
+#define IPC_SETEQDATA 128
+/* (requires Winamp 2.05+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA);
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SETEQDATA);
+** IPC_SETEQDATA sets the value of the last position retrieved
+** by IPC_GETEQDATA. This is pretty lame, and we should provide
+** an extended version that lets you do a MAKELPARAM(pos,value).
+** someday...
+
+ new (2.92+):
+ if the high byte is set to 0xDB, then the third byte specifies
+ which band, and the bottom word specifies the value.
+*/
+
+#define IPC_ADDBOOKMARK 129
+#define IPC_ADDBOOKMARKW 131
+/* (requires Winamp 2.4+)
+** This is sent as a WM_COPYDATA using IPC_ADDBOOKMARK as the dwData value and the
+** directory you want to change to as the lpData member. This will add the specified
+** file / url to the Winamp bookmark list.
+**
+** COPYDATASTRUCT cds = {0};
+** cds.dwData = IPC_ADDBOOKMARK;
+** cds.lpData = (void*)"http://www.blah.com/listen.pls";
+** cds.cbData = lstrlen((char*)cds.lpData)+1; // include space for null char
+** SendMessage(hwnd_winamp,WM_COPYDATA,0,(LPARAM)&cds);
+**
+**
+** In Winamp 5.0+ we use this as a normal WM_WA_IPC and the string is null separated as
+** the filename and then the title of the entry.
+**
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)(char*)"filename\0title\0",IPC_ADDBOOKMARK);
+**
+** This will notify the library / bookmark editor that a bookmark was added.
+** Note that using this message in this context does not actually add the bookmark.
+** Do not use, it is essentially just a notification type message :)
+*/
+
+
+#define IPC_INSTALLPLUGIN 130
+/* This is not implemented (and is very unlikely to be done due to safety concerns).
+** If it was then you could do a WM_COPYDATA with a path to a .wpz and it would then
+** install the plugin for you.
+**
+** COPYDATASTRUCT cds = {0};
+** cds.dwData = IPC_INSTALLPLUGIN;
+** cds.lpData = (void*)"c:\\path\\to\\file.wpz";
+** cds.cbData = lstrlen((char*)cds.lpData)+1; // include space for null char
+** SendMessage(hwnd_winamp,WM_COPYDATA,0,(LPARAM)&cds);
+*/
+
+
+#define IPC_RESTARTWINAMP 135
+/* (requires Winamp 2.2+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_RESTARTWINAMP);
+** IPC_RESTARTWINAMP will restart Winamp (isn't that obvious ? :) )
+** If this fails to make Winamp start after closing then there is a good chance one (or
+** more) of the currently installed plugins caused Winamp to crash on exit (either as a
+** silent crash or a full crash log report before it could call itself start again.
+*/
+
+
+#define IPC_ISFULLSTOP 400
+/* (requires winamp 2.7+ I think)
+** int ret=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISFULLSTOP);
+** This is useful for when you're an output plugin and you want to see if the stop/close
+** happening is a full stop or if you are just between tracks. This returns non zero if
+** it is a full stop or zero if it is just a new track.
+*/
+
+
+#define IPC_INETAVAILABLE 242
+/* (requires Winamp 2.05+)
+** int val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_INETAVAILABLE);
+** IPC_INETAVAILABLE will return 1 if an Internet connection is available for Winamp and
+** relates to the internet connection type setting on the main general preferences page
+** in the Winamp preferences.
+*/
+
+
+#define IPC_UPDTITLE 243
+/* (requires Winamp 2.2+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_UPDTITLE);
+** IPC_UPDTITLE will ask Winamp to update the information about the current title and
+** causes GetFileInfo(..) in the input plugin associated with the current playlist entry
+** to be called. This can be called such as when an input plugin is buffering a file so
+** that it can cause the buffer percentage to appear in the playlist.
+*/
+
+
+#define IPC_REFRESHPLCACHE 247
+/* (requires Winamp 2.2+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_REFRESHPLCACHE);
+** IPC_REFRESHPLCACHE will flush the playlist cache buffer and you send this if you want
+** Winamp to go refetch the titles for all of the entries in the current playlist.
+*/
+
+
+#define IPC_GET_SHUFFLE 250
+/* (requires Winamp 2.4+)
+** int val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_SHUFFLE);
+** IPC_GET_SHUFFLE returns the status of the shuffle option.
+** If set then it will return 1 and if not set then it will return 0.
+*/
+
+
+#define IPC_GET_REPEAT 251
+/* (requires Winamp 2.4+)
+** int val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_REPEAT);
+** IPC_GET_REPEAT returns the status of the repeat option.
+** If set then it will return 1 and if not set then it will return 0.
+*/
+
+
+#define IPC_SET_SHUFFLE 252
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_SHUFFLE);
+** IPC_SET_SHUFFLE sets the status of the shuffle option.
+** If 'value' is 1 then shuffle is turned on.
+** If 'value' is 0 then shuffle is turned off.
+*/
+
+
+#define IPC_SET_REPEAT 253
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_REPEAT);
+** IPC_SET_REPEAT sets the status of the repeat option.
+** If 'value' is 1 then shuffle is turned on.
+** If 'value' is 0 then shuffle is turned off.
+*/
+
+
+#define IPC_ENABLEDISABLE_ALL_WINDOWS 259 // 0xdeadbeef to disable
+/* (requires Winamp 2.9+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(enable?0:0xdeadbeef),IPC_ENABLEDISABLE_ALL_WINDOWS);
+** Sending this message with 0xdeadbeef as the param will disable all winamp windows and
+** any other values will enable all of the Winamp windows again. When disabled you won't
+** get any response on clicking or trying to do anything to the Winamp windows. If the
+** taskbar icon is shown then you may still have control ;)
+*/
+
+
+#define IPC_GETWND 260
+/* (requires Winamp 2.9+)
+** HWND h=SendMessage(hwnd_winamp,WM_WA_IPC,IPC_GETWND_xxx,IPC_GETWND);
+** returns the HWND of the window specified.
+*/
+ #define IPC_GETWND_EQ 0 // use one of these for the param
+ #define IPC_GETWND_PE 1
+ #define IPC_GETWND_MB 2
+ #define IPC_GETWND_VIDEO 3
+#define IPC_ISWNDVISIBLE 261 // same param as IPC_GETWND
+
+
+
+
+/************************************************************************
+***************** in-process only (WE LOVE PLUGINS)
+************************************************************************/
+
+#define IPC_SETSKINW 199
+#define IPC_SETSKIN 200
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"skinname",IPC_SETSKIN);
+** IPC_SETSKIN sets the current skin to "skinname". Note that skinname
+** can be the name of a skin, a skin .zip file, with or without path.
+** If path isn't specified, the default search path is the winamp skins
+** directory.
+*/
+
+
+#define IPC_GETSKIN 201
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)skinname_buffer,IPC_GETSKIN);
+** IPC_GETSKIN puts the directory where skin bitmaps can be found
+** into skinname_buffer.
+** skinname_buffer must be MAX_PATH characters in length.
+** When using a .zip'd skin file, it'll return a temporary directory
+** where the ZIP was decompressed.
+*/
+
+
+#define IPC_EXECPLUG 202
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"vis_file.dll",IPC_EXECPLUG);
+** IPC_EXECPLUG executes a visualization plug-in pointed to by WPARAM.
+** the format of this string can be:
+** "vis_whatever.dll"
+** "vis_whatever.dll,0" // (first mod, file in winamp plug-in dir)
+** "C:\\dir\\vis_whatever.dll,1"
+*/
+
+
+#define IPC_GETPLAYLISTFILE 211
+#define IPC_GETPLAYLISTFILEW 214
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE);
+** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index].
+** returns a pointer to it. returns NULL on error.
+*/
+
+
+#define IPC_GETPLAYLISTTITLE 212
+#define IPC_GETPLAYLISTTITLEW 213
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTTITLE);
+**
+** IPC_GETPLAYLISTTITLE gets the title of the playlist entry [index].
+** returns a pointer to it. returns NULL on error.
+*/
+
+
+#define IPC_GETHTTPGETTER 240
+/* retrieves a function pointer to a HTTP retrieval function.
+** if this is unsupported, returns 1 or 0.
+** the function should be:
+** int (*httpRetrieveFile)(HWND hwnd, char *url, char *file, char *dlgtitle);
+** if you call this function, with a parent window, a URL, an output file, and a dialog title,
+** it will return 0 on successful download, 1 on error.
+*/
+
+
+#define IPC_MBOPEN 241
+/* (requires Winamp 2.05+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_MBOPEN);
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)url,IPC_MBOPEN);
+** IPC_MBOPEN will open a new URL in the minibrowser. if url is NULL, it will open the Minibrowser window.
+*/
+
+
+
+#define IPC_CHANGECURRENTFILE 245
+/* (requires Winamp 2.05+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)file,IPC_CHANGECURRENTFILE);
+** IPC_CHANGECURRENTFILE will set the current playlist item.
+*/
+
+
+#define IPC_GETMBURL 246
+/* (requires Winamp 2.2+)
+** char buffer[4096]; // Urls can be VERY long
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)buffer,IPC_GETMBURL);
+** IPC_GETMBURL will retrieve the current Minibrowser URL into buffer.
+** buffer must be at least 4096 bytes long.
+*/
+
+
+#define IPC_MBBLOCK 248
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_MBBLOCK);
+**
+** IPC_MBBLOCK will block the Minibrowser from updates if value is set to 1
+*/
+
+#define IPC_MBOPENREAL 249
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)url,IPC_MBOPENREAL);
+**
+** IPC_MBOPENREAL works the same as IPC_MBOPEN except that it will works even if
+** IPC_MBBLOCK has been set to 1
+*/
+
+#define IPC_ADJUST_OPTIONSMENUPOS 280
+/* (requires Winamp 2.9+)
+** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_OPTIONSMENUPOS);
+** moves where winamp expects the Options menu in the main menu. Useful if you wish to insert a
+** menu item above the options/skins/vis menus.
+*/
+
+#define IPC_GET_HMENU 281
+/* (requires Winamp 2.9+)
+** HMENU hMenu=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)0,IPC_GET_HMENU);
+** values for data:
+** 0 : main popup menu
+** 1 : main menubar file menu
+** 2 : main menubar options menu
+** 3 : main menubar windows menu
+** 4 : main menubar help menu
+** other values will return NULL.
+*/
+
+#define IPC_GET_EXTENDED_FILE_INFO 290 //pass a pointer to the following struct in wParam
+#define IPC_GET_EXTENDED_FILE_INFO_HOOKABLE 296
+/* (requires Winamp 2.9+)
+** to use, create an extendedFileInfoStruct, point the values filename and metadata to the
+** filename and metadata field you wish to query, and ret to a buffer, with retlen to the
+** length of that buffer, and then SendMessage(hwnd_winamp,WM_WA_IPC,&struct,IPC_GET_EXTENDED_FILE_INFO);
+** the results should be in the buffer pointed to by ret.
+** returns 1 if the decoder supports a getExtendedFileInfo method
+*/
+typedef struct {
+ const char *filename;
+ const char *metadata;
+ char *ret;
+ int retlen;
+} extendedFileInfoStruct;
+
+
+#define IPC_GET_BASIC_FILE_INFO 291 //pass a pointer to the following struct in wParam
+typedef struct {
+ const char *filename;
+
+ 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)
+
+ // filled in by winamp
+ int length;
+ char *title;
+ int titlelen;
+} basicFileInfoStruct;
+
+#define IPC_GET_BASIC_FILE_INFOW 1291 //pass a pointer to the following struct in wParam
+typedef struct {
+ const wchar_t *filename;
+
+ 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)
+
+ // filled in by winamp
+ int length;
+ wchar_t *title;
+ int titlelen;
+} basicFileInfoStructW;
+
+
+#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
+#define IPC_GET_EXTLISTW 1292 // wide char version of above
+
+#define IPC_INFOBOX 293
+typedef struct {
+ HWND parent;
+ char *filename;
+} infoBoxParam;
+
+#define IPC_SET_EXTENDED_FILE_INFO 294 //pass a pointer to the a extendedFileInfoStruct in wParam
+/* (requires Winamp 2.9+)
+** to use, create an extendedFileInfoStruct, point the values filename and metadata to the
+** filename and metadata field you wish to write in ret. (retlen is not used). and then
+** SendMessage(hwnd_winamp,WM_WA_IPC,&struct,IPC_SET_EXTENDED_FILE_INFO);
+** returns 1 if the metadata is supported
+** Call IPC_WRITE_EXTENDED_FILE_INFO once you're done setting all the metadata you want to update
+*/
+
+#define IPC_WRITE_EXTENDED_FILE_INFO 295
+/* (requires Winamp 2.9+)
+** writes all the metadata set thru IPC_SET_EXTENDED_FILE_INFO to the file
+** returns 1 if the file has been successfully updated, 0 if error
+*/
+
+#define IPC_FORMAT_TITLE 297
+typedef struct
+{
+ char *spec; // NULL=default winamp spec
+ void *p;
+
+ char *out;
+ int out_len;
+
+ char * (*TAGFUNC)(const char * tag, void * p); //return 0 if not found
+ void (*TAGFREEFUNC)(char * tag,void * p);
+} waFormatTitle;
+
+#define IPC_FORMAT_TITLE_EXTENDED 298 // similiar to IPC_FORMAT_TITLE, but falls back to Winamp's %tags% if your passed tag function doesn't handle it
+typedef struct
+{
+ const wchar_t *filename;
+ int useExtendedInfo; // set to 1 if you want the Title Formatter to query the input plugins for any tags that your tag function fails on
+ const wchar_t *spec; // NULL=default winamp spec
+ void *p;
+
+ wchar_t *out;
+ int out_len;
+
+ wchar_t * (*TAGFUNC)(const wchar_t * tag, void * p); //return 0 if not found, -1 for empty tag
+ void (*TAGFREEFUNC)(wchar_t *tag, void *p);
+} waFormatTitleExtended;
+
+#define IPC_GETUNCOMPRESSINTERFACE 331
+/* returns a function pointer to uncompress().
+** int (*uncompress)(unsigned char *dest, unsigned long *destLen, const unsigned char *source, unsigned long sourceLen);
+** right out of zlib, useful for decompressing zlibbed data.
+** if you pass the parm of 0x10100000, it will return a wa_inflate_struct * to an inflate API.
+*/
+
+typedef struct {
+ int (*inflateReset)(void *strm);
+ int (*inflateInit_)(void *strm,const char *version, int stream_size);
+ int (*inflate)(void *strm, int flush);
+ int (*inflateEnd)(void *strm);
+ unsigned long (*crc32)(unsigned long crc, const unsigned char *buf, unsigned int len);
+} wa_inflate_struct;
+
+
+#define IPC_ADD_PREFS_DLG 332
+#define IPC_REMOVE_PREFS_DLG 333
+/* (requires Winamp 2.9+)
+** to use, allocate a prefsDlgRec structure (either on the heap or some global
+** data, but NOT on the stack), initialze the members:
+** hInst to the DLL instance where the resource is located
+** dlgID to the ID of the dialog,
+** proc to the window procedure for the dialog
+** name to the name of the prefs page in the prefs.
+** where to 0 (eventually we may add more options)
+** then, SendMessage(hwnd_winamp,WM_WA_IPC,&prefsRec,IPC_ADD_PREFS_DLG);
+**
+** you can also IPC_REMOVE_PREFS_DLG with the address of the same prefsRec,
+** but you shouldn't really ever have to.
+**
+*/
+#define IPC_OPENPREFSTOPAGE 380 // pass an id of a builtin page, or a &prefsDlgRec of prefs page to open
+
+typedef struct _prefsDlgRec {
+ HINSTANCE hInst;
+ int dlgID;
+ void *proc;
+
+ char *name;
+ intptr_t where; // 0 for options, 1 for plugins, 2 for skins, 3 for bookmarks, 4 for prefs
+
+ intptr_t _id;
+ struct _prefsDlgRec *next;
+} prefsDlgRec;
+
+
+#define IPC_GETINIFILE 334 // returns a pointer to winamp.ini
+#define IPC_GETINIDIRECTORY 335 // returns a pointer to the directory to put config files in (if you dont want to use winamp.ini)
+#define IPC_GETPLUGINDIRECTORY 336
+#define IPC_GETM3UDIRECTORY 337 // returns a char pointer to the directory where winamp.m3u is stored in.
+#define IPC_GETM3UDIRECTORYW 338 // returns a wchar_t pointer to the directory where winamp.m3u is stored in.
+
+#define IPC_SPAWNBUTTONPOPUP 361 // param =
+// 0 = eject
+// 1 = previous
+// 2 = next
+// 3 = pause
+// 4 = play
+// 5 = stop
+
+#define IPC_OPENURLBOX 360 // pass a HWND to a parent, returns a HGLOBAL that needs to be freed with GlobalFree(), if successful
+#define IPC_OPENFILEBOX 362 // pass a HWND to a parent
+#define IPC_OPENDIRBOX 363 // pass a HWND to a parent
+
+// pass an HWND to a parent. call this if you take over the whole UI so that the dialogs are not appearing on the
+// bottom right of the screen since the main winamp window is at 3000x3000, call again with NULL to reset
+#define IPC_SETDIALOGBOXPARENT 364
+
+
+
+#define IPC_DRO_MIN 401 // reserved for DrO
+#define IPC_SET_JTF_COMPARATOR 409
+/* pass me an int (__cdecl *)(const char *, const char *) in wParam */
+#define IPC_SET_JTF_COMPARATOR_W 410
+/* pass me an int (__cdecl *)(const wchar_t *, const wchar_t *) in wParam ... maybe someday :) */
+#define IPC_SET_JTF_DRAWTEXT 416
+
+#define IPC_DRO_MAX 499
+
+
+// pass 0 for a copy of the skin HBITMAP
+// pass 1 for name of font to use for playlist editor likeness
+// pass 2 for font charset
+// pass 3 for font size
+#define IPC_GET_GENSKINBITMAP 503
+
+
+#define IPC_GET_EMBEDIF 505 // pass an embedWindowState
+// returns an HWND embedWindow(embedWindowState *); if the data is NULL, otherwise returns the HWND directly
+typedef struct
+{
+ HWND me; //hwnd of the window
+
+ int flags;
+
+ RECT r;
+
+ void *user_ptr; // for application use
+
+ intptr_t extra_data[64]; // for internal winamp use
+} embedWindowState;
+
+#define EMBED_FLAGS_NORESIZE 0x1 // set this bit in embedWindowState.flags to keep window from being resizable
+#define EMBED_FLAGS_NOTRANSPARENCY 0x2 // set this bit in embedWindowState.flags to make gen_ff turn transparency off for this wnd
+#define EMBED_FLAGS_NOWINDOWMENU 0x4 // set this bit to prevent gen_ff from automatically adding your window to the right-click menu
+#define EMBED_FLAGS_GUID 0x8 // call SET_EMBED_GUID(yourEmbedWindowStateStruct, GUID) to define a GUID for this window
+
+#define SET_EMBED_GUID(windowState, windowGUID) { windowState->flags |= EMBED_FLAGS_GUID; *((GUID *)&windowState->extra_data[4])=windowGUID; }
+#define GET_EMBED_GUID(windowState) (*((GUID *)&windowState->extra_data[4]))
+
+#define IPC_EMBED_ENUM 532
+typedef struct embedEnumStruct
+{
+ int (*enumProc)(embedWindowState *ws, struct embedEnumStruct *param); // return 1 to abort
+ int user_data; // or more :)
+} embedEnumStruct;
+ // pass
+
+#define IPC_EMBED_ISVALID 533
+
+#define IPC_CONVERTFILE 506
+/* (requires Winamp 2.92+)
+** Converts a given file to a different format (PCM, MP3, etc...)
+** To use, pass a pointer to a waFileConvertStruct struct
+** This struct can be either on the heap or some global
+** data, but NOT on the stack. At least, until the conversion is done.
+**
+** eg: SendMessage(hwnd_winamp,WM_WA_IPC,&myConvertStruct,IPC_CONVERTFILE);
+**
+** Return value:
+** 0: Can't start the conversion. Look at myConvertStruct->error for details.
+** 1: Conversion started. Status messages will be sent to the specified callbackhwnd.
+** Be sure to call IPC_CONVERTFILE_END when your callback window receives the
+** IPC_CB_CONVERT_DONE message.
+*/
+typedef struct
+{
+ char *sourcefile; // "c:\\source.mp3"
+ char *destfile; // "c:\\dest.pcm"
+ int destformat[8]; // like 'PCM ',srate,nch,bps.
+ //hack alert! you can set destformat[6]=mmioFOURCC('I','N','I',' '); and destformat[7]=(int)my_ini_file; (where my_ini_file is a char*)
+ HWND callbackhwnd; // window that will receive the IPC_CB_CONVERT notification messages
+
+ //filled in by winamp.exe
+ char *error; //if IPC_CONVERTFILE returns 0, the reason will be here
+
+ int bytes_done; //you can look at both of these values for speed statistics
+ int bytes_total;
+ int bytes_out;
+
+ int killswitch; // don't set it manually, use IPC_CONVERTFILE_END
+ intptr_t extra_data[64]; // for internal winamp use
+} convertFileStruct;
+
+#define IPC_CONVERTFILE_END 507
+/* (requires Winamp 2.92+)
+** Stop/ends a convert process started from IPC_CONVERTFILE
+** You need to call this when you receive the IPC_CB_CONVERTDONE message or when you
+** want to abort a conversion process
+**
+** eg: SendMessage(hwnd_winamp,WM_WA_IPC,&myConvertStruct,IPC_CONVERTFILE_END);
+**
+** No return value
+*/
+
+typedef struct {
+ HWND hwndParent;
+ int format;
+
+ //filled in by winamp.exe
+ HWND hwndConfig;
+ int extra_data[8];
+ //hack alert! you can set extra_data[6]=mmioFOURCC('I','N','I',' '); and extra_data[7]=(int)my_ini_file; (where my_ini_file is a char*)
+} convertConfigStruct;
+#define IPC_CONVERT_CONFIG 508
+#define IPC_CONVERT_CONFIG_END 509
+
+typedef struct
+{
+ void (*enumProc)(intptr_t user_data, const char *desc, int fourcc);
+ intptr_t user_data;
+} converterEnumFmtStruct;
+#define IPC_CONVERT_CONFIG_ENUMFMTS 510
+/* (requires Winamp 2.92+)
+*/
+
+typedef struct
+{
+ char cdletter;
+ char *playlist_file;
+ HWND callback_hwnd;
+
+ //filled in by winamp.exe
+ char *error;
+} burnCDStruct;
+#define IPC_BURN_CD 511
+/* (requires Winamp 5.0+)
+*/
+
+typedef struct
+{
+ convertFileStruct *cfs;
+ int priority;
+} convertSetPriority;
+#define IPC_CONVERT_SET_PRIORITY 512
+
+typedef struct
+{
+ unsigned int format; //fourcc value
+ char *item; // config item, eg "bitrate"
+ char *data; // buffer to recieve, or buffer that contains the data
+ int len; // length of the data buffer (only used when getting a config item)
+ char *configfile; // config file to read from
+} convertConfigItem;
+
+#define IPC_CONVERT_CONFIG_SET_ITEM 513 // returns TRUE if successful
+#define IPC_CONVERT_CONFIG_GET_ITEM 514 // returns TRUE if successful
+
+typedef struct
+{
+ const char *filename;
+ char *title; // 2048 bytes
+ int length;
+ int force_useformatting; // can set this to 1 if you want to force a url to use title formatting shit
+} waHookTitleStruct;
+// return TRUE if you hook this
+#define IPC_HOOK_TITLES 850
+
+typedef struct
+{
+ const wchar_t *filename;
+ wchar_t *title; // 2048 bytes
+ int length;
+ int force_useformatting; // can set this to 1 if you want to force a url to use title formatting shit
+} waHookTitleStructW;
+// return TRUE if you hook this
+#define IPC_HOOK_TITLESW 851
+
+#define IPC_GETSADATAFUNC 800
+// 0: returns a char *export_sa_get() that returns 150 bytes of data
+// 1: returns a export_sa_setreq(int want);
+
+#define IPC_GETVUDATAFUNC 801
+// 0: returns a int export_vu_get(int channel) that returns 0-255 (or -1 for bad channel)
+
+#define IPC_ISMAINWNDVISIBLE 900
+
+
+#define IPC_SETPLEDITCOLORS 920
+typedef struct
+{
+ int numElems;
+ int *elems;
+ HBITMAP bm; // set if you want to override
+} waSetPlColorsStruct;
+
+
+// the following IPC use waSpawnMenuParms as parameter
+#define IPC_SPAWNEQPRESETMENU 933
+#define IPC_SPAWNFILEMENU 934 //menubar
+#define IPC_SPAWNOPTIONSMENU 935 //menubar
+#define IPC_SPAWNWINDOWSMENU 936 //menubar
+#define IPC_SPAWNHELPMENU 937 //menubar
+#define IPC_SPAWNPLAYMENU 938 //menubar
+#define IPC_SPAWNPEFILEMENU 939 //menubar
+#define IPC_SPAWNPEPLAYLISTMENU 940 //menubar
+#define IPC_SPAWNPESORTMENU 941 //menubar
+#define IPC_SPAWNPEHELPMENU 942 //menubar
+#define IPC_SPAWNMLFILEMENU 943 //menubar
+#define IPC_SPAWNMLVIEWMENU 944 //menubar
+#define IPC_SPAWNMLHELPMENU 945 //menubar
+#define IPC_SPAWNPELISTOFPLAYLISTS 946
+
+typedef struct
+{
+ HWND wnd;
+ int xpos; // in screen coordinates
+ int ypos;
+} waSpawnMenuParms;
+
+// waSpawnMenuParms2 is used by the menubar submenus
+typedef struct
+{
+ HWND wnd;
+ int xpos; // in screen coordinates
+ int ypos;
+ int width;
+ int height;
+} waSpawnMenuParms2;
+
+
+// system tray sends this (you might want to simulate it)
+#define WM_WA_SYSTRAY WM_USER+1
+
+// input plugins send this when they are done playing back
+#define WM_WA_MPEG_EOF WM_USER+2
+
+
+
+//// video stuff
+
+#define IPC_IS_PLAYING_VIDEO 501 // returns >1 if playing, 0 if not, 1 if old version (so who knows):)
+#define IPC_GET_IVIDEOOUTPUT 500 // see below for IVideoOutput interface
+#define VIDEO_MAKETYPE(A,B,C,D) ((A) | ((B)<<8) | ((C)<<16) | ((D)<<24))
+#define VIDUSER_SET_INFOSTRING 0x1000
+#define VIDUSER_GET_VIDEOHWND 0x1001
+#define VIDUSER_SET_VFLIP 0x1002
+#define VIDUSER_SET_TRACKSELINTERFACE 0x1003 // give your ITrackSelector interface as param2
+#define VIDUSER_OPENVIDEORENDERER 0x1004
+#define VIDUSER_CLOSEVIDEORENDERER 0x1005
+#define VIDUSER_GETPOPUPMENU 0x1006
+
+typedef struct
+{
+ int w;
+ int h;
+ int vflip;
+ double aspectratio;
+ unsigned int fmt;
+} VideoOpenStruct;
+
+#ifndef NO_IVIDEO_DECLARE
+#ifdef __cplusplus
+
+class VideoOutput;
+class SubsItem;
+
+typedef struct {
+ unsigned char* baseAddr;
+ long rowBytes;
+} YV12_PLANE;
+
+typedef struct {
+ YV12_PLANE y;
+ YV12_PLANE u;
+ YV12_PLANE v;
+} YV12_PLANES;
+
+class IVideoOutput
+{
+ public:
+ virtual ~IVideoOutput() { }
+ virtual int open(int w, int h, int vflip, double aspectratio, unsigned int fmt)=0;
+ virtual void setcallback(LRESULT (*msgcallback)(void *token, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam), void *token) { }
+ virtual void close()=0;
+ virtual void draw(void *frame)=0;
+ virtual void drawSubtitle(SubsItem *item) { }
+ virtual void showStatusMsg(const char *text) { }
+ virtual int get_latency() { return 0; }
+ virtual void notifyBufferState(int bufferstate) { } /* 0-255*/
+
+ virtual INT_PTR extended(INT_PTR param1, INT_PTR param2, INT_PTR param3) { return 0; } // Dispatchable, eat this!
+};
+
+class ITrackSelector
+{
+ public:
+ virtual int getNumAudioTracks()=0;
+ virtual void enumAudioTrackName(int n, const char *buf, int size)=0;
+ virtual int getCurAudioTrack()=0;
+ virtual int getNumVideoTracks()=0;
+ virtual void enumVideoTrackName(int n, const char *buf, int size)=0;
+ virtual int getCurVideoTrack()=0;
+
+ virtual void setAudioTrack(int n)=0;
+ virtual void setVideoTrack(int n)=0;
+};
+
+#endif //cplusplus
+#endif//NO_IVIDEO_DECLARE
+
+// these messages are callbacks that you can grab by subclassing the winamp window
+
+// wParam =
+#define IPC_CB_WND_EQ 0 // use one of these for the param
+#define IPC_CB_WND_PE 1
+#define IPC_CB_WND_MB 2
+#define IPC_CB_WND_VIDEO 3
+#define IPC_CB_WND_MAIN 4
+
+#define IPC_CB_ONSHOWWND 600
+#define IPC_CB_ONHIDEWND 601
+
+#define IPC_CB_GETTOOLTIP 602
+
+#define IPC_CB_MISC 603
+ #define IPC_CB_MISC_TITLE 0
+ #define IPC_CB_MISC_VOLUME 1 // volume/pan
+ #define IPC_CB_MISC_STATUS 2
+ #define IPC_CB_MISC_EQ 3
+ #define IPC_CB_MISC_INFO 4
+ #define IPC_CB_MISC_VIDEOINFO 5
+
+#define IPC_CB_CONVERT_STATUS 604 // param value goes from 0 to 100 (percent)
+#define IPC_CB_CONVERT_DONE 605
+
+#define IPC_ADJUST_FFWINDOWSMENUPOS 606
+/* (requires Winamp 2.9+)
+** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_FFWINDOWSMENUPOS);
+** moves where winamp expects the freeform windows in the menubar windows main menu. Useful if you wish to insert a
+** menu item above extra freeform windows.
+*/
+
+#define IPC_ISDOUBLESIZE 608
+
+#define IPC_ADJUST_FFOPTIONSMENUPOS 609
+/* (requires Winamp 2.9+)
+** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_FFOPTIONSMENUPOS);
+** moves where winamp expects the freeform preferences item in the menubar windows main menu. Useful if you wish to insert a
+** menu item above preferences item.
+*/
+
+#define IPC_GETTIMEDISPLAYMODE 610 // returns 0 if displaying elapsed time or 1 if displaying remaining time
+
+#define IPC_SETVISWND 611 // param is hwnd, setting this allows you to receive ID_VIS_NEXT/PREVOUS/RANDOM/FS wm_commands
+#define ID_VIS_NEXT 40382
+#define ID_VIS_PREV 40383
+#define ID_VIS_RANDOM 40384
+#define ID_VIS_FS 40389
+#define ID_VIS_CFG 40390
+#define ID_VIS_MENU 40391
+
+#define IPC_GETVISWND 612 // returns the vis cmd handler hwnd
+#define IPC_ISVISRUNNING 613
+#define IPC_CB_VISRANDOM 628 // param is status of random
+
+#define IPC_SETIDEALVIDEOSIZE 614 // sent by winamp to winamp, trap it if you need it. width=HIWORD(param), height=LOWORD(param)
+
+#define IPC_GETSTOPONVIDEOCLOSE 615
+#define IPC_SETSTOPONVIDEOCLOSE 616
+
+typedef struct {
+ HWND hwnd;
+ int uMsg;
+ WPARAM wParam;
+ LPARAM lParam;
+} transAccelStruct;
+
+#define IPC_TRANSLATEACCELERATOR 617
+
+typedef struct {
+ int cmd;
+ int x;
+ int y;
+ int align;
+} windowCommand; // send this as param to an IPC_PLCMD, IPC_MBCMD, IPC_VIDCMD
+
+#define IPC_CB_ONTOGGLEAOT 618
+
+#define IPC_GETPREFSWND 619
+
+#define IPC_SET_PE_WIDTHHEIGHT 620 // data is a pointer to a POINT structure that holds width & height
+
+#define IPC_GETLANGUAGEPACKINSTANCE 621
+
+#define IPC_CB_PEINFOTEXT 622 // data is a string, ie: "04:21/45:02"
+
+#define IPC_CB_OUTPUTCHANGED 623 // output plugin was changed in config
+
+#define IPC_GETOUTPUTPLUGIN 625
+
+#define IPC_SETDRAWBORDERS 626
+#define IPC_DISABLESKINCURSORS 627
+#define IPC_CB_RESETFONT 629
+
+#define IPC_IS_FULLSCREEN 630 // returns 1 if video or vis is in fullscreen mode
+#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
+
+#define IPC_SHOW_NOTIFICATION 632
+
+#define IPC_GETSKININFO 633
+
+#define IPC_GET_MANUALPLADVANCE 634
+/* (requires Winamp 5.03+)
+** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_MANUALPLADVANCE);
+**
+** IPC_GET_MANUALPLADVANCE returns the status of the Manual Playlist Advance (1 if set)
+*/
+
+#define IPC_SET_MANUALPLADVANCE 635
+/* (requires Winamp 5.03+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_MANUALPLADVANCE);
+**
+** IPC_SET_MANUALPLADVANCE sets the status of the Manual Playlist Advance option (1 to turn it on)
+*/
+
+#define IPC_GET_NEXT_PLITEM 636
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_EOF_GET_NEXT_PLITEM);
+**
+** Sent to Winamp's main window when an item has just finished playback or the next button has been pressed and
+** requesting the new playlist item number to go to.
+** Mainly used by gen_jumpex. Subclass this message in your application to return the new item number.
+** -1 for normal winamp operation (default) or the new item number in the playlist to play.
+*/
+
+#define IPC_GET_PREVIOUS_PLITEM 637
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_EOF_GET_PREVIOUS_PLITEM);
+**
+** Sent to Winamp's main window when the previous button has been pressed and Winamp is requesting the new playlist item number to go to.
+** Mainly used by gen_jumpex. Subclass this message in your application to return the new item number.
+** -1 for normal winamp operation (default) or the new item number in the playlist to play.
+*/
+
+#define IPC_IS_WNDSHADE 638
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,wnd,IPC_IS_WNDSHADE);
+**
+** 'wnd' is window id as defined for IPC_GETWND, or -1 for main window
+** Returns 1 if wnd is set to winshade mode, or 0 if it is not
+*/
+
+#define IPC_SETRATING 639
+/* (requires Winamp 5.04+ with ML)
+** SendMessage(hwnd_winamp,WM_WA_IPC,rating,IPC_SETRATING);
+** 'rating' is an int value from 0 (no rating) to 5
+*/
+
+#define IPC_GETRATING 640
+/* (requires Winamp 5.04+ with ML)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETRATING);
+** returns the current item's rating
+*/
+
+#define IPC_GETNUMAUDIOTRACKS 641
+/* (requires Winamp 5.04+)
+** int n = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETNUMAUDIOTRACKS);
+** returns the number of audio tracks for the currently playing item
+*/
+
+#define IPC_GETNUMVIDEOTRACKS 642
+/* (requires Winamp 5.04+)
+** int n = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETNUMVIDEOTRACKS);
+** returns the number of video tracks for the currently playing item
+*/
+
+#define IPC_GETAUDIOTRACK 643
+/* (requires Winamp 5.04+)
+** int cur = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETAUDIOTRACK);
+** returns the id of the current audio track for the currently playing item
+*/
+
+#define IPC_GETVIDEOTRACK 644
+/* (requires Winamp 5.04+)
+** int cur = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVIDEOTRACK);
+** returns the id of the current video track for the currently playing item
+*/
+
+#define IPC_SETAUDIOTRACK 645
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,track,IPC_SETAUDIOTRACK);
+** switch the currently playing item to a new audio track
+*/
+
+#define IPC_SETVIDEOTRACK 646
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,track,IPC_SETVIDEOTRACK);
+** switch the currently playing item to a new video track
+*/
+
+#define IPC_PUSH_DISABLE_EXIT 647
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_PUSH_DISABLE_EXIT );
+** lets you disable or re-enable the UI exit functions (close button,
+** context menu, alt-f4).
+** call IPC_POP_DISABLE_EXIT when you are done doing whatever required
+** preventing exit
+*/
+
+#define IPC_POP_DISABLE_EXIT 648
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_POP_DISABLE_EXIT );
+** see IPC_PUSH_DISABLE_EXIT
+*/
+
+#define IPC_IS_EXIT_ENABLED 649
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_IS_EXIT_ENABLED);
+** returns 0 if exit is disabled, 1 otherwise
+*/
+
+#define IPC_IS_AOT 650
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_IS_AOT);
+** returns status of always on top flag. note: this may not match the actual
+** TOPMOST window flag while another fullscreen application is focused
+*/
+
+#define IPC_USES_RECYCLEBIN 651
+/*
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_USES_RECYCLEBIN);
+** returns 1 if deleted files should be sent to the recycle bin.
+** returns 0 if deleted files should be deleted permanently.
+**
+** You should check for this option if your plugin deletes files
+** so that your setting matches the winamp setting
+*/
+
+#define IPC_FLUSHAUDITS 652
+/*
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_FLUSHAUDITS);
+**
+** Will flush any pending audits in the global audits que
+**
+*/
+
+#define IPC_GETPLAYITEM_START 653
+#define IPC_GETPLAYITEM_END 654
+
+
+// >>>>>>>>>>> Next is 655
+
+#define IPC_PLCMD 1000
+
+#define PLCMD_ADD 0
+#define PLCMD_REM 1
+#define PLCMD_SEL 2
+#define PLCMD_MISC 3
+#define PLCMD_LIST 4
+
+//#define IPC_MBCMD 1001
+
+#define MBCMD_BACK 0
+#define MBCMD_FORWARD 1
+#define MBCMD_STOP 2
+#define MBCMD_RELOAD 3
+#define MBCMD_MISC 4
+
+#define IPC_VIDCMD 1002
+
+#define VIDCMD_FULLSCREEN 0
+#define VIDCMD_1X 1
+#define VIDCMD_2X 2
+#define VIDCMD_LIB 3
+#define VIDPOPUP_MISC 4
+
+//#define IPC_MBURL 1003 //sets the URL
+//#define IPC_MBGETCURURL 1004 //copies the current URL into wParam (have a 4096 buffer ready)
+//#define IPC_MBGETDESC 1005 //copies the current URL description into wParam (have a 4096 buffer ready)
+//#define IPC_MBCHECKLOCFILE 1006 //checks that the link file is up to date (otherwise updates it). wParam=parent HWND
+//#define IPC_MBREFRESH 1007 //refreshes the "now playing" view in the library
+//#define IPC_MBGETDEFURL 1008 //copies the default URL into wParam (have a 4096 buffer ready)
+
+#define IPC_STATS_LIBRARY_ITEMCNT 1300 // updates library count status
+
+// IPC 2000-3000 reserved for freeform messages, see gen_ff/ff_ipc.h
+#define IPC_FF_FIRST 2000
+#define IPC_FF_LAST 3000
+
+
+/*
+** General IPC messages in Winamp
+**
+** All notification messages appear in the lParam of the main window message proceedure.
+*/
+
+
+#define IPC_GETDROPTARGET 3001
+/* (requires Winamp 5.0+)
+** IDropTarget* IDrop = (IDropTarget*)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETDROPTARGET);
+**
+** You call this to retrieve a copy of the IDropTarget interface which Winamp created for
+** handling external drag and drop operations on to it's Windows. This is only really
+** useful if you're providing an alternate interface and want your Windows to provide the
+** same drag and drop support as Winamp normally provides the user. Check out MSDN or
+** your prefered search facility for more information about the IDropTarget interface and
+** what's needed to handle it in your own instance.
+*/
+
+#define IPC_PLAYLIST_MODIFIED 3002
+/* (requires Winamp 5.0+)
+** This is a notification message sent to the main Winamp window whenever the playlist is
+** modified in any way e.g. the addition/removal of a playlist entry.
+**
+** It is not a good idea to do large amounts of processing in this notification since it
+** will slow down Winamp as playlist entries are modified (especially when you're adding
+** in a large playlist).
+**
+** if(uMsg == WM_WA_IPC && lParam == IPC_PLAYLIST_MODIFIED){
+** // do what you need to do here
+** }
+*/
+
+#define IPC_PLAYING_FILE 3003
+/* (requires Winamp 5.0+)
+** This is a notification message sent to the main Winamp windoq when playback begins for
+** a file. This passes the full filepath in the wParam of the message received.
+**
+** if(uMsg == WM_WA_IPC && lParam == IPC_PLAYING_FILE){
+** // do what you need to do here, e.g.
+** process_file((char*)wParam);
+** }
+*/
+
+#define IPC_FILE_TAG_MAY_HAVE_UPDATED 3004 // sent to main wnd with the file as parm whenever a file tag might be updated
+/* (requires Winamp 5.0+)
+** This is a notification message sent to the main Winamp window when a file's tag
+** (e.g. id3) may have been updated. This appears to be sent when the InfoBox(..) function
+** of the associated input plugin returns a 1 (which is the file information dialog/editor
+** call normally).
+**
+** if(uMsg == WM_WA_IPC && lParam == IPC_FILE_TAG_MAY_HAVE_UPDATED){
+** // do what you need to do here, e.g.
+** update_info_on_file_update((char*)wParam);
+** }
+*/
+
+#define IPC_ALLOW_PLAYTRACKING 3007
+/* (requires Winamp 5.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,allow,IPC_ALLOW_PLAYTRACKING);
+** Send allow as nonzero to allow play tracking and zero to disable the mode.
+*/
+
+#define IPC_HOOK_OKTOQUIT 3010
+/* (requires Winamp 5.0+)
+** This is a notification message sent to the main Winamp window asking if it's okay to
+** close or not. Return zero to prevent Winamp from closing or return anything non-zero
+** to allow Winamp to close.
+**
+** The best implementation of this option is to let the message pass through to the
+** original window proceedure since another plugin may want to have a say in the matter
+** with regards to Winamp closing.
+**
+** if(uMsg == WM_WA_IPC && lParam == IPC_HOOK_OKTOQUIT){
+** // do what you need to do here, e.g.
+** if(no_shut_down()){
+** return 1;
+** }
+** }
+*/
+
+#define IPC_WRITECONFIG 3011
+/* (requires Winamp 5.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,write_type,IPC_WRITECONFIG);
+**
+** Send write_type as 2 to write all config settings and the current playlist.
+**
+** Send write_type as 1 to write the playlist and common settings.
+** This won't save the following ini settings::
+**
+** defext, titlefmt, proxy, visplugin_name, dspplugin_name, check_ft_startup,
+** visplugin_num, pe_fontsize, visplugin_priority, visplugin_autoexec, dspplugin_num,
+** sticon, splash, taskbar, dropaotfs, ascb_new, ttips, riol, minst, whichicon,
+** whichicon2, addtolist, snap, snaplen, parent, hilite, disvis, rofiob, shownumsinpl,
+** keeponscreen, eqdsize, usecursors, fixtitles, priority, shuffle_morph_rate,
+** useexttitles, bifont, inet_mode, ospb, embedwnd_freesize, no_visseh
+** (the above was valid for 5.1)
+**
+** Send write_type as 0 to write the common and less common settings and no playlist.
+*/
+
+#define IPC_UPDATE_URL 3012 // pass the URL (char *) in lparam, will be free()'d on done.
+
+// pass a string to be the name to register, and returns a value > 65536, which is a unique value you can use
+// for custom WM_WA_IPC messages.
+
+#define IPC_GET_RANDFUNC 3015 // returns a function to get a random number
+/* (requires Winamp 5.1+)
+** int (*randfunc)(void) = (int(*)(void))SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_GET_RANDFUNC);
+** if(randfunc && randfunc != 1){
+** randfunc();
+** }
+**
+** This will return a positive 32-bit number (essentially 31-bit).
+** The check for a returned value of 1 is because that's the default return value from
+** SendMessage(..) when it is not handled so is good to check for it in this situation.
+*/
+
+#define IPC_METADATA_CHANGED 3017
+/* (requires Winamp 5.1+)
+** int changed=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)(char*)field,IPC_METADATA_CHANGED);
+** a plugin can SendMessage this to winamp if internal metadata has changes.
+** wParam should be a char * of what field changed
+**
+** Currently used for internal actions (and very few at that) the intent of this api is
+** to allow a plugin to call it when metadata has changed in the current playlist entry
+** e.g.a new id3v2 tag was found in a stream
+**
+** The wparam value can either be NULL or a pointer to an ansi string for the metadata
+** which has changed. This can be thought of as an advanced version of IPC_UPDTITLE and
+** could be used to allow for update of the current title when a specific tag changed.
+**
+** Not recommended to be used since there is not the complete handling implemented in
+** Winamp for it at the moment.
+*/
+
+#define IPC_SKIN_CHANGED 3018
+/* (requires Winamp 5.1+)
+** This is a notification message sent to the main Winamp window by itself whenever
+** the skin in use is changed. There is no information sent by the wParam for this.
+**
+** if(message == WM_WA_IPC && lparam == IPC_SKIN_CHANGED){
+** // do what you need to do to handle skin changes, e.g. call WADlg_init(hwnd_winamp);
+** }
+*/
+
+#define IPC_REGISTER_LOWORD_COMMAND 3019
+/* (requires Winamp 5.1+)
+** WORD id = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_REGISTER_LOWORD_COMMAND);
+** This will assign you a unique id for making your own commands such as for extra menu
+** entries. The starting value returned by this message will potentially change as and
+** when the main resource file of Winamp is updated with extra data so assumptions cannot
+** be made on what will be returned and plugin loading order will affect things as well.
+*/
+
+#define IPC_GET_DISPATCH_OBJECT 3020 // gets winamp main IDispatch * (for embedded webpages)
+#define IPC_GET_UNIQUE_DISPATCH_ID 3021 // gives you a unique dispatch ID that won't conflict with anything in winamp's IDispatch *
+
+#define IPC_ADD_DISPATCH_OBJECT 3022 // add your own dispatch object into winamp's. This lets embedded webpages access your functions
+// pass a pointer to DispatchInfo (see below). Winamp makes a copy of all this data so you can safely delete it later
+typedef struct
+{
+ wchar_t *name; // filled in by plugin, make sure it's a unicode string!! (i.e. L"myObject" instead of "myObject).
+ struct IDispatch *dispatch; // filled in by plugin
+ DWORD id; // filled in by winamp on return
+} DispatchInfo;
+
+#define IPC_GET_PROXY_STRING 3023
+/* (requires Winamp 5.11+)
+** char* proxy_string=(char*)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_PROXY_STRING);
+** This will return the same string as is shown on the General Preferences page.
+*/
+
+#define IPC_USE_REGISTRY 3024
+/* (requires Winamp 5.11+)
+** int reg_enabled=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_USE_REGISTRY);
+** This will return 0 if you should leave your grubby hands off the registry (i.e. for
+** lockdown mode). This is useful if Winamp is run from a USB drive and you can't alter
+** system settings, etc.
+*/
+
+#define IPC_GET_API_SERVICE 3025
+/* (requires Winamp 5.12+)
+** api_service* api_service = (api_service)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_API_SERVICE);
+** This api will return Winamp's api_service pointer (which is what Winamp3 used, heh).
+** If this api is not supported in the Winamp version that is being used at the time then
+** the returned value from this api will be 1 which is a good version check.
+**
+** As of 5.12 there is support for .w5s plugins which reside in %WinampDir%\System and
+** are intended for common code that can be shared amongst other plugins e.g. jnetlib.w5s
+** which contains jnetlib in one instance instead of being duplicated multiple times in
+** all of the plugins which need internet access.
+**
+** Details on the .w5s specifications will come at some stage (possibly).
+*/
+
+#define WINAMP_OPTIONS_EQ 40036 // toggles the EQ window
+#define WINAMP_OPTIONS_PLEDIT 40040 // toggles the playlist window
+#define WINAMP_VOLUMEUP 40058 // turns the volume up a little
+#define WINAMP_VOLUMEDOWN 40059 // turns the volume down a little
+#define WINAMP_FFWD5S 40060 // fast forwards 5 seconds
+#define WINAMP_REW5S 40061 // rewinds 5 seconds
+
+// the following are the five main control buttons, with optionally shift
+// or control pressed
+// (for the exact functions of each, just try it out)
+#define WINAMP_BUTTON1 40044
+#define WINAMP_BUTTON2 40045
+#define WINAMP_BUTTON3 40046
+#define WINAMP_BUTTON4 40047
+#define WINAMP_BUTTON5 40048
+#define WINAMP_BUTTON1_SHIFT 40144
+#define WINAMP_BUTTON2_SHIFT 40145
+#define WINAMP_BUTTON3_SHIFT 40146
+#define WINAMP_BUTTON4_SHIFT 40147
+#define WINAMP_BUTTON5_SHIFT 40148
+#define WINAMP_BUTTON1_CTRL 40154
+#define WINAMP_BUTTON2_CTRL 40155
+#define WINAMP_BUTTON3_CTRL 40156
+#define WINAMP_BUTTON4_CTRL 40157
+#define WINAMP_BUTTON5_CTRL 40158
+
+#define WINAMP_FILE_PLAY 40029 // pops up the load file(s) box
+#define WINAMP_FILE_DIR 40187 // pops up the load directory box
+#define WINAMP_OPTIONS_PREFS 40012 // pops up the preferences
+#define WINAMP_OPTIONS_AOT 40019 // toggles always on top
+#define WINAMP_HELP_ABOUT 40041 // pops up the about box :)
+
+#define ID_MAIN_PLAY_AUDIOCD1 40323 // starts playing the audio CD in the first CD reader
+#define ID_MAIN_PLAY_AUDIOCD2 40323 // plays the 2nd
+#define ID_MAIN_PLAY_AUDIOCD3 40323 // plays the 3nd
+#define ID_MAIN_PLAY_AUDIOCD4 40323 // plays the 4nd
+
+// IDs 42000 to 45000 are reserved for gen_ff
+// IDs from 45000 to 57000 are reserved for library
+
+typedef struct {
+ const wchar_t *filename;
+ const wchar_t *metadata;
+ wchar_t *ret;
+ int retlen;
+} extendedFileInfoStructW;
+
+#define IPC_GET_EXTENDED_FILE_INFOW 3026
+/* (requires Winamp 5.13+)
+** Pass a pointer to the above struct in wParam
+*/
+#define IPC_GET_EXTENDED_FILE_INFOW_HOOKABLE 3027
+#define IPC_SET_EXTENDED_FILE_INFOW 3028
+/* (requires Winamp 5.13+)
+** Pass a pointer to the above struct in wParam
+*/
+
+#define IPC_PLAYLIST_GET_NEXT_SELECTED 3029
+/* (requires 5.2+)
+** int pl_item = SendMessage(hwnd_winamp,WM_WA_IPC,start,IPC_PLAYLIST_GET_NEXT_SELECTED);
+**
+** This works just like the ListView_GetNextItem(..) macro for ListView controls.
+** 'start' is the index of the playlist item that you want to begin the search after or
+** set this as -1 for the search to begin with the first item of the current playlist.
+**
+** This will return the index of the selected playlist according to the 'start' value or
+** it returns -1 if there is no selection or no more selected items according to 'start'.
+**
+** Quick example:
+**
+** int sel = -1;
+** // keep incrementing the start of the search so we get all of the selected entries
+** while((sel = SendMessage(hwnd_winamp,WM_WA_IPC,sel,IPC_PLAYLIST_GET_NEXT_SELECTED))!=-1){
+** // show the playlist file entry of the selected item(s) if there were any
+** MessageBox(hwnd_winamp,(char*)SendMessage(hwnd_winamp,WM_WA_IPC,sel,IPC_GETPLAYLISTFILE),0,0);
+** }
+*/
+
+#define IPC_PLAYLIST_GET_SELECTED_COUNT 3030
+/* (requires 5.2+)
+** int selcnt = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_PLAYLIST_GET_SELECTED_COUNT);
+** This will return the number of selected playlist entries.
+*/
+
+#define IPC_GET_PLAYING_FILENAME 3031 // returns wchar_t * of the currently playing filename
+
+#define IPC_REGISTER_WINAMP_IPCMESSAGE 65536
+/* (requires Winamp 5.0+)
+** DWORD id = SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)name,IPC_REGISTER_WINAMP_IPCMESSAGE);
+** The value 'id' returned is > 65536 and is incremented on subsequent calls for unique
+** 'name' values passed to it. By using the same 'name' in different plugins will allow a
+** common runtime api to be provided for the currently running instance of Winamp
+** e.g.
+** PostMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)my_param,registered_ipc);
+** Have a look at wa_hotkeys.h for an example on how this api is used in practice for a
+** custom WM_WA_IPC message.
+**
+** if(uMsg == WM_WA_IPC && lParam == id_from_register_winamp_ipcmessage){
+** // do things
+** }
+*/
+
+#endif//_WA_IPC_H_ \ No newline at end of file
diff --git a/Plugins/listeningto/players/player.cpp b/Plugins/listeningto/players/player.cpp
new file mode 100644
index 0000000..b444422
--- /dev/null
+++ b/Plugins/listeningto/players/player.cpp
@@ -0,0 +1,223 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "..\\commons.h"
+
+
+extern void HasNewListeningInfo();
+
+
+
+Player::Player() : name(_T("Player")), enabled(FALSE), needPoll(FALSE)
+{
+ ZeroMemory(&listening_info, sizeof(listening_info));
+ InitializeCriticalSection(&cs);
+}
+
+Player::~Player()
+{
+ FreeData();
+ DeleteCriticalSection(&cs);
+}
+
+void Player::NotifyInfoChanged()
+{
+ if (enabled)
+ HasNewListeningInfo();
+}
+
+BOOL Player::GetListeningInfo(LISTENINGTOINFO *lti)
+{
+ EnterCriticalSection(&cs);
+
+ BOOL ret;
+ if (listening_info.cbSize == 0)
+ {
+ ret = FALSE;
+ }
+ else
+ {
+ if (lti != NULL)
+ CopyListeningInfo(lti, &listening_info);
+ ret = TRUE;
+ }
+
+ LeaveCriticalSection(&cs);
+
+ return ret;
+}
+
+void Player::FreeData()
+{
+ EnterCriticalSection(&cs);
+
+ if (listening_info.cbSize != 0)
+ FreeListeningInfo(&listening_info);
+
+ LeaveCriticalSection(&cs);
+}
+
+LISTENINGTOINFO * Player::LockListeningInfo()
+{
+ EnterCriticalSection(&cs);
+
+ return &listening_info;
+}
+
+void Player::ReleaseListeningInfo()
+{
+ LeaveCriticalSection(&cs);
+}
+
+
+
+ExternalPlayer::ExternalPlayer()
+{
+ name = _T("ExternalPlayer");
+ needPoll = TRUE;
+
+ window_classes = NULL;
+ num_window_classes = 0;
+ found_window = FALSE;
+}
+
+ExternalPlayer::~ExternalPlayer()
+{
+}
+
+HWND ExternalPlayer::FindWindow()
+{
+ HWND hwnd = NULL;
+ for(int i = 0; i < num_window_classes; i++)
+ {
+ hwnd = ::FindWindow(window_classes[i], NULL);
+ if (hwnd != NULL)
+ break;
+ }
+ return hwnd;
+}
+
+BOOL ExternalPlayer::GetListeningInfo(LISTENINGTOINFO *lti)
+{
+ if (FindWindow() == NULL)
+ return FALSE;
+
+ return Player::GetListeningInfo(lti);
+}
+
+
+
+CodeInjectionPlayer::CodeInjectionPlayer()
+{
+ name = _T("CodeInjectionPlayer");
+ dll_name = NULL;
+ message_window_class = NULL;
+ next_request_time = 0;
+}
+
+CodeInjectionPlayer::~CodeInjectionPlayer()
+{
+}
+
+void CodeInjectionPlayer::InjectCode()
+{
+ if (!opts.enable_code_injection)
+ return;
+ else if (next_request_time > GetTickCount())
+ return;
+
+ // Window is opened?
+ HWND hwnd = FindWindow();
+ if (hwnd == NULL)
+ return;
+
+ // Msg Window is registered? (aka plugin is running?)
+ HWND msgHwnd = ::FindWindow(message_window_class, NULL);
+ if (msgHwnd != NULL)
+ return;
+
+
+ next_request_time = GetTickCount() + 30000;
+
+
+ // Get the dll path
+ char dll_path[1024] = {0};
+ if (!GetModuleFileNameA(hInst, dll_path, MAX_REGS(dll_path)))
+ return;
+
+ char *p = strrchr(dll_path, '\\');
+ if (p == NULL)
+ return;
+
+ p++;
+ *p = '\0';
+
+ size_t len = p - dll_path;
+
+ mir_snprintf(p, 1024 - len, "listeningto\\%s.dll", dll_name);
+
+ len = strlen(dll_path);
+
+ // File exists?
+ DWORD attribs = GetFileAttributesA(dll_path);
+ if (attribs == 0xFFFFFFFF || !(attribs & FILE_ATTRIBUTE_ARCHIVE))
+ return;
+
+ // Do the code injection
+ unsigned long pid;
+ GetWindowThreadProcessId(hwnd, &pid);
+ HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION
+ | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid);
+ if (hProcess == NULL)
+ return;
+
+ char *_dll = (char *) VirtualAllocEx(hProcess, NULL, len+1, MEM_COMMIT, PAGE_READWRITE );
+ if (_dll == NULL)
+ {
+ CloseHandle(hProcess);
+ return;
+ }
+ WriteProcessMemory(hProcess, _dll, dll_path, len+1, NULL);
+
+ HMODULE hKernel32 = GetModuleHandleA("kernel32");
+ HANDLE hLoadLibraryA = GetProcAddress(hKernel32, "LoadLibraryA");
+ DWORD threadId;
+ HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE) hLoadLibraryA,
+ _dll, 0, &threadId);
+ if (hThread == NULL)
+ {
+ VirtualFreeEx(hProcess, _dll, len+1, MEM_RELEASE);
+ CloseHandle(hProcess);
+ return;
+ }
+ WaitForSingleObject(hThread, INFINITE);
+ CloseHandle(hThread);
+ VirtualFreeEx(hProcess, _dll, len+1, MEM_RELEASE);
+ CloseHandle(hProcess);
+}
+
+BOOL CodeInjectionPlayer::GetListeningInfo(LISTENINGTOINFO *lti)
+{
+ if (enabled)
+ InjectCode();
+
+ return ExternalPlayer::GetListeningInfo(lti);
+}
+
diff --git a/Plugins/listeningto/players/player.h b/Plugins/listeningto/players/player.h
new file mode 100644
index 0000000..45396ad
--- /dev/null
+++ b/Plugins/listeningto/players/player.h
@@ -0,0 +1,81 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+class Player
+{
+protected:
+ LISTENINGTOINFO listening_info;
+ CRITICAL_SECTION cs;
+
+ void NotifyInfoChanged();
+
+public:
+ BOOL enabled;
+ BOOL needPoll;
+ TCHAR *name;
+
+ Player();
+ virtual ~Player();
+
+ virtual BOOL GetListeningInfo(LISTENINGTOINFO *lti);
+
+ virtual void FreeData();
+
+ // Helpers to write to this object's listening info
+ virtual LISTENINGTOINFO * LockListeningInfo();
+ virtual void ReleaseListeningInfo();
+
+ // Called everytime options change
+ virtual void EnableDisable() {}
+};
+
+
+class ExternalPlayer : public Player
+{
+protected:
+ TCHAR **window_classes;
+ int num_window_classes;
+ BOOL found_window;
+
+ virtual HWND FindWindow();
+
+public:
+ ExternalPlayer();
+ virtual ~ExternalPlayer();
+
+ virtual BOOL GetListeningInfo(LISTENINGTOINFO *lti);
+};
+
+
+class CodeInjectionPlayer : public ExternalPlayer
+{
+protected:
+ char *dll_name;
+ TCHAR *message_window_class;
+ DWORD next_request_time;
+
+ virtual void InjectCode();
+
+public:
+ CodeInjectionPlayer();
+ virtual ~CodeInjectionPlayer();
+
+ virtual BOOL GetListeningInfo(LISTENINGTOINFO *lti);
+};
diff --git a/Plugins/listeningto/players/wa_ipc.h b/Plugins/listeningto/players/wa_ipc.h
new file mode 100644
index 0000000..6076573
--- /dev/null
+++ b/Plugins/listeningto/players/wa_ipc.h
@@ -0,0 +1,1022 @@
+/*
+** Copyright (C) 2003 Nullsoft, Inc.
+**
+** This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held
+** liable for any damages arising from the use of this software.
+**
+** Permission is granted to anyone to use this software for any purpose, including commercial applications, and to
+** alter it and redistribute it freely, subject to the following restrictions:
+**
+** 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
+** If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+**
+** 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+**
+** 3. This notice may not be removed or altered from any source distribution.
+**
+*/
+
+#ifndef _WA_IPC_H_
+#define _WA_IPC_H_
+
+/*
+** This is the modern replacement for the classic 'frontend.h'. Most of these
+** updates are designed for in-process use, i.e. from a plugin.
+**
+*/
+
+/* message used to sent many messages to winamp's main window.
+** most all of the IPC_* messages involve sending the message in the form of:
+** result = SendMessage(hwnd_winamp,WM_WA_IPC,(parameter),IPC_*);
+*/
+#define WM_WA_IPC WM_USER
+/* but some of them use WM_COPYDATA. be afraid.
+*/
+
+#define IPC_GETVERSION 0
+/* int version = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVERSION);
+**
+** Version will be 0x20yx for winamp 2.yx. versions previous to Winamp 2.0
+** typically (but not always) use 0x1zyx for 1.zx versions. Weird, I know.
+*/
+
+#define IPC_GETREGISTEREDVERSION 770
+
+
+typedef struct {
+ char *filename;
+ char *title;
+ int length;
+} enqueueFileWithMetaStruct; // send this to a IPC_PLAYFILE in a non WM_COPYDATA,
+// and you get the nice desired result. if title is NULL, it is treated as a "thing",
+// otherwise it's assumed to be a file (for speed)
+
+#define IPC_PLAYFILE 100 // dont be fooled, this is really the same as enqueufile
+#define IPC_ENQUEUEFILE 100
+/* sent as a WM_COPYDATA, with IPC_PLAYFILE as the dwData, and the string to play
+** as the lpData. Just enqueues, does not clear the playlist or change the playback
+** state.
+*/
+
+
+#define IPC_DELETE 101
+#define IPC_DELETE_INT 1101 // don't use this, it's used internally by winamp when
+ // dealing with some lame explorer issues.
+/* SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_DELETE);
+** Use IPC_DELETE to clear Winamp's internal playlist.
+*/
+
+
+#define IPC_STARTPLAY 102 // starts playback. almost like hitting play in Winamp.
+#define IPC_STARTPLAY_INT 1102 // used internally, don't bother using it (won't be any fun)
+
+
+#define IPC_CHDIR 103
+/* sent as a WM_COPYDATA, with IPC_CHDIR as the dwData, and the directory to change to
+** as the lpData.
+*/
+
+
+#define IPC_ISPLAYING 104
+/* int res = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING);
+** If it returns 1, it is playing. if it returns 3, it is paused,
+** if it returns 0, it is not playing.
+*/
+
+
+#define IPC_GETOUTPUTTIME 105
+/* int res = SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETOUTPUTTIME);
+** returns the position in milliseconds of the current track (mode = 0),
+** or the track length, in seconds (mode = 1). Returns -1 if not playing or error.
+*/
+
+
+#define IPC_JUMPTOTIME 106
+/* (requires Winamp 1.60+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,ms,IPC_JUMPTOTIME);
+** IPC_JUMPTOTIME sets the position in milliseconds of the
+** current song (approximately).
+** Returns -1 if not playing, 1 on eof, or 0 if successful
+*/
+
+#define IPC_GETMODULENAME 109
+#define IPC_EX_ISRIGHTEXE 666
+/* usually shouldnt bother using these, but here goes:
+** send a WM_COPYDATA with IPC_GETMODULENAME, and an internal
+** flag gets set, which if you send a normal WM_WA_IPC message with
+** IPC_EX_ISRIGHTEXE, it returns whether or not that filename
+** matches. lame, I know.
+*/
+
+#define IPC_WRITEPLAYLIST 120
+/* (requires Winamp 1.666+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_WRITEPLAYLIST);
+**
+** IPC_WRITEPLAYLIST writes the current playlist to <winampdir>\\Winamp.m3u,
+** and returns the current playlist position.
+** Kinda obsoleted by some of the 2.x new stuff, but still good for when
+** using a front-end (instead of a plug-in)
+*/
+
+
+#define IPC_SETPLAYLISTPOS 121
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,position,IPC_SETPLAYLISTPOS)
+** IPC_SETPLAYLISTPOS sets the playlist position to 'position'. It
+** does not change playback or anything, it just sets position, and
+** updates the view if necessary
+*/
+
+
+#define IPC_SETVOLUME 122
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,volume,IPC_SETVOLUME);
+** IPC_SETVOLUME sets the volume of Winamp (from 0-255).
+*/
+
+
+#define IPC_SETPANNING 123
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,panning,IPC_SETPANNING);
+** IPC_SETPANNING sets the panning of Winamp (from 0 (left) to 255 (right)).
+*/
+
+
+#define IPC_GETLISTLENGTH 124
+/* (requires Winamp 2.0+)
+** int length = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTLENGTH);
+** IPC_GETLISTLENGTH returns the length of the current playlist, in
+** tracks.
+*/
+
+
+#define IPC_GETLISTPOS 125
+/* (requires Winamp 2.05+)
+** int pos=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS);
+** IPC_GETLISTPOS returns the playlist position. A lot like IPC_WRITEPLAYLIST
+** only faster since it doesn't have to write out the list. Heh, silly me.
+*/
+
+
+#define IPC_GETINFO 126
+/* (requires Winamp 2.05+)
+** int inf=SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETINFO);
+** IPC_GETINFO returns info about the current playing song. The value
+** it returns depends on the value of 'mode'.
+** Mode Meaning
+** ------------------
+** 0 Samplerate (i.e. 44100)
+** 1 Bitrate (i.e. 128)
+** 2 Channels (i.e. 2)
+** 3 (5+) Video LOWORD=w HIWORD=h
+** 4 (5+) > 65536, string (video description)
+*/
+
+
+#define IPC_GETEQDATA 127
+/* (requires Winamp 2.05+)
+** int data=SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA);
+** IPC_GETEQDATA queries the status of the EQ.
+** The value returned depends on what 'pos' is set to:
+** Value Meaning
+** ------------------
+** 0-9 The 10 bands of EQ data. 0-63 (+20db - -20db)
+** 10 The preamp value. 0-63 (+20db - -20db)
+** 11 Enabled. zero if disabled, nonzero if enabled.
+** 12 Autoload. zero if disabled, nonzero if enabled.
+*/
+
+
+#define IPC_SETEQDATA 128
+/* (requires Winamp 2.05+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA);
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SETEQDATA);
+** IPC_SETEQDATA sets the value of the last position retrieved
+** by IPC_GETEQDATA. This is pretty lame, and we should provide
+** an extended version that lets you do a MAKELPARAM(pos,value).
+** someday...
+
+ new (2.92+):
+ if the high byte is set to 0xDB, then the third byte specifies
+ which band, and the bottom word specifies the value.
+*/
+
+#define IPC_ADDBOOKMARK 129
+/* (requires Winamp 2.4+)
+** Sent as a WM_COPYDATA, using IPC_ADDBOOKMARK, adds the specified
+** file/url to the Winamp bookmark list.
+*/
+/*
+In winamp 5+, we use this as a normal WM_WA_IPC and the string:
+
+ "filename\0title\0"
+
+ to notify the library/bookmark editor that a bookmark
+was added. Note that using this message in this context does not
+actually add the bookmark.
+do not use :)
+*/
+
+
+#define IPC_INSTALLPLUGIN 130
+/* not implemented, but if it was you could do a WM_COPYDATA with
+** a path to a .wpz, and it would install it.
+*/
+
+
+#define IPC_RESTARTWINAMP 135
+/* (requires Winamp 2.2+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_RESTARTWINAMP);
+** IPC_RESTARTWINAMP will restart Winamp (isn't that obvious ? :)
+*/
+
+
+#define IPC_ISFULLSTOP 400
+/* (requires winamp 2.7+ I think)
+** ret=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISFULLSTOP);
+** useful for when you're an output plugin, and you want to see
+** if the stop/close is a full stop, or just between tracks.
+** returns nonzero if it's full, zero if it's just a new track.
+*/
+
+
+#define IPC_INETAVAILABLE 242
+/* (requires Winamp 2.05+)
+** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_INETAVAILABLE);
+** IPC_INETAVAILABLE will return 1 if the Internet connection is available for Winamp.
+*/
+
+
+#define IPC_UPDTITLE 243
+/* (requires Winamp 2.2+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_UPDTITLE);
+** IPC_UPDTITLE will ask Winamp to update the informations about the current title.
+*/
+
+
+#define IPC_REFRESHPLCACHE 247
+/* (requires Winamp 2.2+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_REFRESHPLCACHE);
+** IPC_REFRESHPLCACHE will flush the playlist cache buffer.
+** (send this if you want it to go refetch titles for tracks)
+*/
+
+
+#define IPC_GET_SHUFFLE 250
+/* (requires Winamp 2.4+)
+** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_SHUFFLE);
+**
+** IPC_GET_SHUFFLE returns the status of the Shuffle option (1 if set)
+*/
+
+
+#define IPC_GET_REPEAT 251
+/* (requires Winamp 2.4+)
+** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_REPEAT);
+**
+** IPC_GET_REPEAT returns the status of the Repeat option (1 if set)
+*/
+
+
+#define IPC_SET_SHUFFLE 252
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_SHUFFLE);
+**
+** IPC_SET_SHUFFLE sets the status of the Shuffle option (1 to turn it on)
+*/
+
+
+#define IPC_SET_REPEAT 253
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_REPEAT);
+**
+** IPC_SET_REPEAT sets the status of the Repeat option (1 to turn it on)
+*/
+
+
+#define IPC_ENABLEDISABLE_ALL_WINDOWS 259 // 0xdeadbeef to disable
+/* (requires Winamp 2.9+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,enable?0:0xdeadbeef,IPC_MBOPENREAL);
+** sending with 0xdeadbeef as the param disables all winamp windows,
+** any other values will enable all winamp windows.
+*/
+
+
+#define IPC_GETWND 260
+/* (requires Winamp 2.9+)
+** HWND h=SendMessage(hwnd_winamp,WM_WA_IPC,IPC_GETWND_xxx,IPC_GETWND);
+** returns the HWND of the window specified.
+*/
+ #define IPC_GETWND_EQ 0 // use one of these for the param
+ #define IPC_GETWND_PE 1
+ #define IPC_GETWND_MB 2
+ #define IPC_GETWND_VIDEO 3
+#define IPC_ISWNDVISIBLE 261 // same param as IPC_GETWND
+
+
+
+
+/************************************************************************
+***************** in-process only (WE LOVE PLUGINS)
+************************************************************************/
+
+
+#define IPC_SETSKIN 200
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"skinname",IPC_SETSKIN);
+** IPC_SETSKIN sets the current skin to "skinname". Note that skinname
+** can be the name of a skin, a skin .zip file, with or without path.
+** If path isn't specified, the default search path is the winamp skins
+** directory.
+*/
+
+
+#define IPC_GETSKIN 201
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)skinname_buffer,IPC_GETSKIN);
+** IPC_GETSKIN puts the directory where skin bitmaps can be found
+** into skinname_buffer.
+** skinname_buffer must be MAX_PATH characters in length.
+** When using a .zip'd skin file, it'll return a temporary directory
+** where the ZIP was decompressed.
+*/
+
+
+#define IPC_EXECPLUG 202
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"vis_file.dll",IPC_EXECPLUG);
+** IPC_EXECPLUG executes a visualization plug-in pointed to by WPARAM.
+** the format of this string can be:
+** "vis_whatever.dll"
+** "vis_whatever.dll,0" // (first mod, file in winamp plug-in dir)
+** "C:\\dir\\vis_whatever.dll,1"
+*/
+
+
+#define IPC_GETPLAYLISTFILE 211
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE);
+** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index].
+** returns a pointer to it. returns NULL on error.
+*/
+
+
+#define IPC_GETPLAYLISTTITLE 212
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTTITLE);
+**
+** IPC_GETPLAYLISTTITLE gets the title of the playlist entry [index].
+** returns a pointer to it. returns NULL on error.
+*/
+
+
+#define IPC_GETHTTPGETTER 240
+/* retrieves a function pointer to a HTTP retrieval function.
+** if this is unsupported, returns 1 or 0.
+** the function should be:
+** int (*httpRetrieveFile)(HWND hwnd, char *url, char *file, char *dlgtitle);
+** if you call this function, with a parent window, a URL, an output file, and a dialog title,
+** it will return 0 on successful download, 1 on error.
+*/
+
+
+#define IPC_MBOPEN 241
+/* (requires Winamp 2.05+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_MBOPEN);
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)url,IPC_MBOPEN);
+** IPC_MBOPEN will open a new URL in the minibrowser. if url is NULL, it will open the Minibrowser window.
+*/
+
+
+
+#define IPC_CHANGECURRENTFILE 245
+/* (requires Winamp 2.05+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)file,IPC_CHANGECURRENTFILE);
+** IPC_CHANGECURRENTFILE will set the current playlist item.
+*/
+
+
+#define IPC_GETMBURL 246
+/* (requires Winamp 2.2+)
+** char buffer[4096]; // Urls can be VERY long
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)buffer,IPC_GETMBURL);
+** IPC_GETMBURL will retrieve the current Minibrowser URL into buffer.
+** buffer must be at least 4096 bytes long.
+*/
+
+
+#define IPC_MBBLOCK 248
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_MBBLOCK);
+**
+** IPC_MBBLOCK will block the Minibrowser from updates if value is set to 1
+*/
+
+#define IPC_MBOPENREAL 249
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)url,IPC_MBOPENREAL);
+**
+** IPC_MBOPENREAL works the same as IPC_MBOPEN except that it will works even if
+** IPC_MBBLOCK has been set to 1
+*/
+
+#define IPC_ADJUST_OPTIONSMENUPOS 280
+/* (requires Winamp 2.9+)
+** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_OPTIONSMENUPOS);
+** moves where winamp expects the Options menu in the main menu. Useful if you wish to insert a
+** menu item above the options/skins/vis menus.
+*/
+
+#define IPC_GET_HMENU 281
+/* (requires Winamp 2.9+)
+** HMENU hMenu=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)0,IPC_GET_HMENU);
+** values for data:
+** 0 : main popup menu
+** 1 : main menubar file menu
+** 2 : main menubar options menu
+** 3 : main menubar windows menu
+** 4 : main menubar help menu
+** other values will return NULL.
+*/
+
+#define IPC_GET_EXTENDED_FILE_INFO 290 //pass a pointer to the following struct in wParam
+#define IPC_GET_EXTENDED_FILE_INFO_HOOKABLE 296
+/* (requires Winamp 2.9+)
+** to use, create an extendedFileInfoStruct, point the values filename and metadata to the
+** filename and metadata field you wish to query, and ret to a buffer, with retlen to the
+** length of that buffer, and then SendMessage(hwnd_winamp,WM_WA_IPC,&struct,IPC_GET_EXTENDED_FILE_INFO);
+** the results should be in the buffer pointed to by ret.
+** returns 1 if the decoder supports a getExtendedFileInfo method
+*/
+typedef struct {
+ char *filename;
+ char *metadata;
+ char *ret;
+ int retlen;
+} extendedFileInfoStruct;
+
+#define IPC_GET_BASIC_FILE_INFO 291 //pass a pointer to the following struct in wParam
+typedef struct {
+ char *filename;
+
+ 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)
+
+ // filled in by winamp
+ int length;
+ char *title;
+ int titlelen;
+} basicFileInfoStruct;
+
+#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
+
+#define IPC_INFOBOX 293
+typedef struct {
+ HWND parent;
+ char *filename;
+} infoBoxParam;
+
+#define IPC_SET_EXTENDED_FILE_INFO 294 //pass a pointer to the a extendedFileInfoStruct in wParam
+/* (requires Winamp 2.9+)
+** to use, create an extendedFileInfoStruct, point the values filename and metadata to the
+** filename and metadata field you wish to write in ret. (retlen is not used). and then
+** SendMessage(hwnd_winamp,WM_WA_IPC,&struct,IPC_SET_EXTENDED_FILE_INFO);
+** returns 1 if the metadata is supported
+** Call IPC_WRITE_EXTENDED_FILE_INFO once you're done setting all the metadata you want to update
+*/
+
+#define IPC_WRITE_EXTENDED_FILE_INFO 295
+/* (requires Winamp 2.9+)
+** writes all the metadata set thru IPC_SET_EXTENDED_FILE_INFO to the file
+** returns 1 if the file has been successfully updated, 0 if error
+*/
+
+#define IPC_FORMAT_TITLE 297
+typedef struct
+{
+ char *spec; // NULL=default winamp spec
+ void *p;
+
+ char *out;
+ int out_len;
+
+ char * (*TAGFUNC)(char * tag, void * p); //return 0 if not found
+ void (*TAGFREEFUNC)(char * tag,void * p);
+} waFormatTitle;
+
+#define IPC_GETUNCOMPRESSINTERFACE 331
+/* returns a function pointer to uncompress().
+** int (*uncompress)(unsigned char *dest, unsigned long *destLen, const unsigned char *source, unsigned long sourceLen);
+** right out of zlib, useful for decompressing zlibbed data.
+** if you pass the parm of 0x10100000, it will return a wa_inflate_struct * to an inflate API.
+*/
+
+typedef struct {
+ int (*inflateReset)(void *strm);
+ int (*inflateInit_)(void *strm,const char *version, int stream_size);
+ int (*inflate)(void *strm, int flush);
+ int (*inflateEnd)(void *strm);
+ unsigned long (*crc32)(unsigned long crc, const unsigned char *buf, unsigned int len);
+} wa_inflate_struct;
+
+
+#define IPC_ADD_PREFS_DLG 332
+#define IPC_REMOVE_PREFS_DLG 333
+/* (requires Winamp 2.9+)
+** to use, allocate a prefsDlgRec structure (either on the heap or some global
+** data, but NOT on the stack), initialze the members:
+** hInst to the DLL instance where the resource is located
+** dlgID to the ID of the dialog,
+** proc to the window procedure for the dialog
+** name to the name of the prefs page in the prefs.
+** where to 0 (eventually we may add more options)
+** then, SendMessage(hwnd_winamp,WM_WA_IPC,&prefsRec,IPC_ADD_PREFS_DLG);
+**
+** you can also IPC_REMOVE_PREFS_DLG with the address of the same prefsRec,
+** but you shouldn't really ever have to.
+**
+*/
+#define IPC_OPENPREFSTOPAGE 380 // pass an id of a builtin page, or a &prefsDlgRec of prefs page to open
+
+typedef struct _prefsDlgRec {
+ HINSTANCE hInst;
+ int dlgID;
+ void *proc;
+
+ char *name;
+ int where; // 0 for options, 1 for plugins, 2 for skins, 3 for bookmarks, 4 for prefs
+
+
+ int _id;
+ struct _prefsDlgRec *next;
+} prefsDlgRec;
+
+
+#define IPC_GETINIFILE 334 // returns a pointer to winamp.ini
+#define IPC_GETINIDIRECTORY 335 // returns a pointer to the directory to put config files in (if you dont want to use winamp.ini)
+
+#define IPC_SPAWNBUTTONPOPUP 361 // param =
+// 0 = eject
+// 1 = previous
+// 2 = next
+// 3 = pause
+// 4 = play
+// 5 = stop
+
+#define IPC_OPENURLBOX 360 // pass a HWND to a parent, returns a HGLOBAL that needs to be freed with GlobalFree(), if successful
+#define IPC_OPENFILEBOX 362 // pass a HWND to a parent
+#define IPC_OPENDIRBOX 363 // pass a HWND to a parent
+
+// pass an HWND to a parent. call this if you take over the whole UI so that the dialogs are not appearing on the
+// bottom right of the screen since the main winamp window is at 3000x3000, call again with NULL to reset
+#define IPC_SETDIALOGBOXPARENT 364
+
+
+
+// pass 0 for a copy of the skin HBITMAP
+// pass 1 for name of font to use for playlist editor likeness
+// pass 2 for font charset
+// pass 3 for font size
+#define IPC_GET_GENSKINBITMAP 503
+
+
+#define IPC_GET_EMBEDIF 505 // pass an embedWindowState
+// returns an HWND embedWindow(embedWindowState *); if the data is NULL, otherwise returns the HWND directly
+typedef struct
+{
+ HWND me; //hwnd of the window
+
+ int flags;
+
+ RECT r;
+
+ void *user_ptr; // for application use
+
+ int extra_data[64]; // for internal winamp use
+} embedWindowState;
+
+#define EMBED_FLAGS_NORESIZE 1 // set this bit in embedWindowState.flags to keep window from being resizable
+#define EMBED_FLAGS_NOTRANSPARENCY 2 // set this bit in embedWindowState.flags to make gen_ff turn transparency off for this wnd
+
+
+#define IPC_EMBED_ENUM 532
+typedef struct embedEnumStruct
+{
+ int (*enumProc)(embedWindowState *ws, struct embedEnumStruct *param); // return 1 to abort
+ int user_data; // or more :)
+} embedEnumStruct;
+ // pass
+
+#define IPC_EMBED_ISVALID 533
+
+#define IPC_CONVERTFILE 506
+/* (requires Winamp 2.92+)
+** Converts a given file to a different format (PCM, MP3, etc...)
+** To use, pass a pointer to a waFileConvertStruct struct
+** This struct can be either on the heap or some global
+** data, but NOT on the stack. At least, until the conversion is done.
+**
+** eg: SendMessage(hwnd_winamp,WM_WA_IPC,&myConvertStruct,IPC_CONVERTFILE);
+**
+** Return value:
+** 0: Can't start the conversion. Look at myConvertStruct->error for details.
+** 1: Conversion started. Status messages will be sent to the specified callbackhwnd.
+** Be sure to call IPC_CONVERTFILE_END when your callback window receives the
+** IPC_CB_CONVERT_DONE message.
+*/
+typedef struct
+{
+ char *sourcefile; // "c:\\source.mp3"
+ char *destfile; // "c:\\dest.pcm"
+ int destformat[8]; // like 'PCM ',srate,nch,bps
+ HWND callbackhwnd; // window that will receive the IPC_CB_CONVERT notification messages
+
+ //filled in by winamp.exe
+ char *error; //if IPC_CONVERTFILE returns 0, the reason will be here
+
+ int bytes_done; //you can look at both of these values for speed statistics
+ int bytes_total;
+ int bytes_out;
+
+ int killswitch; // don't set it manually, use IPC_CONVERTFILE_END
+ int extra_data[64]; // for internal winamp use
+} convertFileStruct;
+
+#define IPC_CONVERTFILE_END 507
+/* (requires Winamp 2.92+)
+** Stop/ends a convert process started from IPC_CONVERTFILE
+** You need to call this when you receive the IPC_CB_CONVERTDONE message or when you
+** want to abort a conversion process
+**
+** eg: SendMessage(hwnd_winamp,WM_WA_IPC,&myConvertStruct,IPC_CONVERTFILE_END);
+**
+** No return value
+*/
+
+typedef struct {
+ HWND hwndParent;
+ int format;
+
+ //filled in by winamp.exe
+ HWND hwndConfig;
+ int extra_data[8];
+} convertConfigStruct;
+#define IPC_CONVERT_CONFIG 508
+#define IPC_CONVERT_CONFIG_END 509
+
+typedef struct
+{
+ void (*enumProc)(int user_data, const char *desc, int fourcc);
+ int user_data;
+} converterEnumFmtStruct;
+#define IPC_CONVERT_CONFIG_ENUMFMTS 510
+/* (requires Winamp 2.92+)
+*/
+
+
+typedef struct
+{
+ char cdletter;
+ char *playlist_file;
+ HWND callback_hwnd;
+
+ //filled in by winamp.exe
+ char *error;
+} burnCDStruct;
+#define IPC_BURN_CD 511
+/* (requires Winamp 5.0+)
+*/
+
+typedef struct
+{
+ convertFileStruct *cfs;
+ int priority;
+} convertSetPriority;
+#define IPC_CONVERT_SET_PRIORITY 512
+
+typedef struct
+{
+ char *filename;
+ char *title; // 2048 bytes
+ int length;
+ int force_useformatting; // can set this to 1 if you want to force a url to use title formatting shit
+} waHookTitleStruct;
+// return TRUE if you hook this
+#define IPC_HOOK_TITLES 850
+
+#define IPC_GETSADATAFUNC 800
+// 0: returns a char *export_sa_get() that returns 150 bytes of data
+// 1: returns a export_sa_setreq(int want);
+
+#define IPC_ISMAINWNDVISIBLE 900
+
+
+#define IPC_SETPLEDITCOLORS 920
+typedef struct
+{
+ int numElems;
+ int *elems;
+ HBITMAP bm; // set if you want to override
+} waSetPlColorsStruct;
+
+
+// the following IPC use waSpawnMenuParms as parameter
+#define IPC_SPAWNEQPRESETMENU 933
+#define IPC_SPAWNFILEMENU 934 //menubar
+#define IPC_SPAWNOPTIONSMENU 935 //menubar
+#define IPC_SPAWNWINDOWSMENU 936 //menubar
+#define IPC_SPAWNHELPMENU 937 //menubar
+#define IPC_SPAWNPLAYMENU 938 //menubar
+#define IPC_SPAWNPEFILEMENU 939 //menubar
+#define IPC_SPAWNPEPLAYLISTMENU 940 //menubar
+#define IPC_SPAWNPESORTMENU 941 //menubar
+#define IPC_SPAWNPEHELPMENU 942 //menubar
+#define IPC_SPAWNMLFILEMENU 943 //menubar
+#define IPC_SPAWNMLVIEWMENU 944 //menubar
+#define IPC_SPAWNMLHELPMENU 945 //menubar
+#define IPC_SPAWNPELISTOFPLAYLISTS 946
+
+typedef struct
+{
+ HWND wnd;
+ int xpos; // in screen coordinates
+ int ypos;
+} waSpawnMenuParms;
+
+// waSpawnMenuParms2 is used by the menubar submenus
+typedef struct
+{
+ HWND wnd;
+ int xpos; // in screen coordinates
+ int ypos;
+ int width;
+ int height;
+} waSpawnMenuParms2;
+
+
+// system tray sends this (you might want to simulate it)
+#define WM_WA_SYSTRAY WM_USER+1
+
+// input plugins send this when they are done playing back
+#define WM_WA_MPEG_EOF WM_USER+2
+
+
+
+//// video stuff
+
+#define IPC_IS_PLAYING_VIDEO 501 // returns >1 if playing, 0 if not, 1 if old version (so who knows):)
+#define IPC_GET_IVIDEOOUTPUT 500 // see below for IVideoOutput interface
+#define VIDEO_MAKETYPE(A,B,C,D) ((A) | ((B)<<8) | ((C)<<16) | ((D)<<24))
+#define VIDUSER_SET_INFOSTRING 0x1000
+#define VIDUSER_GET_VIDEOHWND 0x1001
+#define VIDUSER_SET_VFLIP 0x1002
+
+#ifndef NO_IVIDEO_DECLARE
+#ifdef __cplusplus
+
+class VideoOutput;
+class SubsItem;
+
+typedef struct {
+ unsigned char* baseAddr;
+ long rowBytes;
+} YV12_PLANE;
+
+typedef struct {
+ YV12_PLANE y;
+ YV12_PLANE u;
+ YV12_PLANE v;
+} YV12_PLANES;
+
+class IVideoOutput
+{
+ public:
+ virtual ~IVideoOutput() { }
+ virtual int open(int w, int h, int vflip, double aspectratio, unsigned int fmt)=0;
+ virtual void setcallback(LRESULT (*msgcallback)(void *token, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam), void *token) { }
+ virtual void close()=0;
+ virtual void draw(void *frame)=0;
+ virtual void drawSubtitle(SubsItem *item) { }
+ virtual void showStatusMsg(const char *text) { }
+ virtual int get_latency() { return 0; }
+ virtual void notifyBufferState(int bufferstate) { } /* 0-255*/
+
+ virtual int extended(int param1, int param2, int param3) { return 0; } // Dispatchable, eat this!
+};
+#endif //cplusplus
+#endif//NO_IVIDEO_DECLARE
+
+// these messages are callbacks that you can grab by subclassing the winamp window
+
+// wParam =
+#define IPC_CB_WND_EQ 0 // use one of these for the param
+#define IPC_CB_WND_PE 1
+#define IPC_CB_WND_MB 2
+#define IPC_CB_WND_VIDEO 3
+#define IPC_CB_WND_MAIN 4
+
+#define IPC_CB_ONSHOWWND 600
+#define IPC_CB_ONHIDEWND 601
+
+#define IPC_CB_GETTOOLTIP 602
+
+#define IPC_CB_MISC 603
+ #define IPC_CB_MISC_TITLE 0
+ #define IPC_CB_MISC_VOLUME 1 // volume/pan
+ #define IPC_CB_MISC_STATUS 2
+ #define IPC_CB_MISC_EQ 3
+ #define IPC_CB_MISC_INFO 4
+ #define IPC_CB_MISC_VIDEOINFO 5
+
+#define IPC_CB_CONVERT_STATUS 604 // param value goes from 0 to 100 (percent)
+#define IPC_CB_CONVERT_DONE 605
+
+#define IPC_ADJUST_FFWINDOWSMENUPOS 606
+/* (requires Winamp 2.9+)
+** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_FFWINDOWSMENUPOS);
+** moves where winamp expects the freeform windows in the menubar windows main menu. Useful if you wish to insert a
+** menu item above extra freeform windows.
+*/
+
+#define IPC_ISDOUBLESIZE 608
+
+#define IPC_ADJUST_FFOPTIONSMENUPOS 609
+/* (requires Winamp 2.9+)
+** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_FFOPTIONSMENUPOS);
+** moves where winamp expects the freeform preferences item in the menubar windows main menu. Useful if you wish to insert a
+** menu item above preferences item.
+*/
+
+#define IPC_GETTIMEDISPLAYMODE 610 // returns 0 if displaying elapsed time or 1 if displaying remaining time
+
+#define IPC_SETVISWND 611 // param is hwnd, setting this allows you to receive ID_VIS_NEXT/PREVOUS/RANDOM/FS wm_commands
+#define ID_VIS_NEXT 40382
+#define ID_VIS_PREV 40383
+#define ID_VIS_RANDOM 40384
+#define ID_VIS_FS 40389
+#define ID_VIS_CFG 40390
+#define ID_VIS_MENU 40391
+
+#define IPC_GETVISWND 612 // returns the vis cmd handler hwnd
+#define IPC_ISVISRUNNING 613
+#define IPC_CB_VISRANDOM 628 // param is status of random
+
+#define IPC_SETIDEALVIDEOSIZE 614 // sent by winamp to winamp, trap it if you need it. width=HIWORD(param), height=LOWORD(param)
+
+#define IPC_GETSTOPONVIDEOCLOSE 615
+#define IPC_SETSTOPONVIDEOCLOSE 616
+
+typedef struct {
+ HWND hwnd;
+ int uMsg;
+ int wParam;
+ int lParam;
+} transAccelStruct;
+
+#define IPC_TRANSLATEACCELERATOR 617
+
+typedef struct {
+ int cmd;
+ int x;
+ int y;
+ int align;
+} windowCommand; // send this as param to an IPC_PLCMD, IPC_MBCMD, IPC_VIDCMD
+
+#define IPC_CB_ONTOGGLEAOT 618
+
+#define IPC_GETPREFSWND 619
+
+#define IPC_SET_PE_WIDTHHEIGHT 620 // data is a pointer to a POINT structure that holds width & height
+
+#define IPC_GETLANGUAGEPACKINSTANCE 621
+
+#define IPC_CB_PEINFOTEXT 622 // data is a string, ie: "04:21/45:02"
+
+#define IPC_CB_OUTPUTCHANGED 623 // output plugin was changed in config
+
+#define IPC_GETOUTPUTPLUGIN 625
+
+#define IPC_SETDRAWBORDERS 626
+#define IPC_DISABLESKINCURSORS 627
+#define IPC_CB_RESETFONT 629
+
+#define IPC_IS_FULLSCREEN 630 // returns 1 if video or vis is in fullscreen mode
+#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
+
+#define IPC_SHOW_NOTIFICATION 632
+
+#define IPC_GETSKININFO 633
+
+// >>>>>>>>>>> Next is 634
+
+#define IPC_PLCMD 1000
+
+#define PLCMD_ADD 0
+#define PLCMD_REM 1
+#define PLCMD_SEL 2
+#define PLCMD_MISC 3
+#define PLCMD_LIST 4
+
+#define IPC_MBCMD 1001
+
+#define MBCMD_BACK 0
+#define MBCMD_FORWARD 1
+#define MBCMD_STOP 2
+#define MBCMD_RELOAD 3
+#define MBCMD_MISC 4
+
+#define IPC_VIDCMD 1002
+
+#define VIDCMD_FULLSCREEN 0
+#define VIDCMD_1X 1
+#define VIDCMD_2X 2
+#define VIDCMD_LIB 3
+#define VIDPOPUP_MISC 4
+
+#define IPC_MBURL 1003 //sets the URL
+#define IPC_MBGETCURURL 1004 //copies the current URL into wParam (have a 4096 buffer ready)
+#define IPC_MBGETDESC 1005 //copies the current URL description into wParam (have a 4096 buffer ready)
+#define IPC_MBCHECKLOCFILE 1006 //checks that the link file is up to date (otherwise updates it). wParam=parent HWND
+#define IPC_MBREFRESH 1007 //refreshes the "now playing" view in the library
+#define IPC_MBGETDEFURL 1008 //copies the default URL into wParam (have a 4096 buffer ready)
+
+#define IPC_STATS_LIBRARY_ITEMCNT 1300 // updates library count status
+
+// IPC 2000-3000 reserved for freeform messages, see gen_ff/ff_ipc.h
+#define IPC_FF_FIRST 2000
+#define IPC_FF_LAST 3000
+
+#define IPC_GETDROPTARGET 3001
+
+#define IPC_PLAYLIST_MODIFIED 3002 // sent to main wnd whenever the playlist is modified
+
+#define IPC_PLAYING_FILE 3003 // sent to main wnd with the file as parm whenever a file is played
+#define IPC_FILE_TAG_MAY_HAVE_UPDATED 3004 // sent to main wnd with the file as parm whenever a file tag might be updated
+
+
+#define IPC_ALLOW_PLAYTRACKING 3007
+// send nonzero to allow, zero to disallow
+
+#define IPC_HOOK_OKTOQUIT 3010 // return 0 to abort a quit, nonzero if quit is OK
+
+#define IPC_WRITECONFIG 3011 // pass 2 to write all, 1 to write playlist + common, 0 to write common+less common
+
+// pass a string to be the name to register, and returns a value > 65536, which is a unique value you can use
+// for custom WM_WA_IPC messages.
+#define IPC_REGISTER_WINAMP_IPCMESSAGE 65536
+
+/**************************************************************************/
+
+/*
+** Finally there are some WM_COMMAND messages that you can use to send
+** Winamp misc commands.
+**
+** To send these, use:
+**
+** SendMessage(hwnd_winamp, WM_COMMAND,command_name,0);
+*/
+
+#define WINAMP_OPTIONS_EQ 40036 // toggles the EQ window
+#define WINAMP_OPTIONS_PLEDIT 40040 // toggles the playlist window
+#define WINAMP_VOLUMEUP 40058 // turns the volume up a little
+#define WINAMP_VOLUMEDOWN 40059 // turns the volume down a little
+#define WINAMP_FFWD5S 40060 // fast forwards 5 seconds
+#define WINAMP_REW5S 40061 // rewinds 5 seconds
+
+// the following are the five main control buttons, with optionally shift
+// or control pressed
+// (for the exact functions of each, just try it out)
+#define WINAMP_BUTTON1 40044
+#define WINAMP_BUTTON2 40045
+#define WINAMP_BUTTON3 40046
+#define WINAMP_BUTTON4 40047
+#define WINAMP_BUTTON5 40048
+#define WINAMP_BUTTON1_SHIFT 40144
+#define WINAMP_BUTTON2_SHIFT 40145
+#define WINAMP_BUTTON3_SHIFT 40146
+#define WINAMP_BUTTON4_SHIFT 40147
+#define WINAMP_BUTTON5_SHIFT 40148
+#define WINAMP_BUTTON1_CTRL 40154
+#define WINAMP_BUTTON2_CTRL 40155
+#define WINAMP_BUTTON3_CTRL 40156
+#define WINAMP_BUTTON4_CTRL 40157
+#define WINAMP_BUTTON5_CTRL 40158
+
+#define WINAMP_FILE_PLAY 40029 // pops up the load file(s) box
+#define WINAMP_FILE_DIR 40187 // pops up the load directory box
+#define WINAMP_OPTIONS_PREFS 40012 // pops up the preferences
+#define WINAMP_OPTIONS_AOT 40019 // toggles always on top
+#define WINAMP_HELP_ABOUT 40041 // pops up the about box :)
+
+#define ID_MAIN_PLAY_AUDIOCD1 40323 // starts playing the audio CD in the first CD reader
+#define ID_MAIN_PLAY_AUDIOCD2 40323 // plays the 2nd
+#define ID_MAIN_PLAY_AUDIOCD3 40323 // plays the 3nd
+#define ID_MAIN_PLAY_AUDIOCD4 40323 // plays the 4nd
+
+// IDs 42000 to 45000 are reserved for gen_ff
+// IDs from 45000 to 57000 are reserved for library
+
+#endif//_WA_IPC_H_
+
+/*
+** EOF.. Enjoy.
+*/ \ No newline at end of file
diff --git a/Plugins/listeningto/players/watrack.cpp b/Plugins/listeningto/players/watrack.cpp
new file mode 100644
index 0000000..bace34d
--- /dev/null
+++ b/Plugins/listeningto/players/watrack.cpp
@@ -0,0 +1,153 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "..\\commons.h"
+
+
+static WATrack *instance = NULL;
+
+int NewStatusCallback(WPARAM wParam, LPARAM lParam)
+{
+ if (!loaded)
+ return 0;
+ if (instance != NULL)
+ instance->NewStatus(wParam, lParam);
+ return 0;
+}
+
+
+WATrack::WATrack()
+{
+ name = _T("WATrack");
+ instance = this;
+ hNewStatusHook = NULL;
+}
+
+
+
+WATrack::~WATrack()
+{
+ if (hNewStatusHook != NULL)
+ {
+ UnhookEvent(hNewStatusHook);
+ hNewStatusHook = NULL;
+ }
+ instance = NULL;
+}
+
+
+void WATrack::EnableDisable()
+{
+ if (!ServiceExists(MS_WAT_GETMUSICINFO))
+ {
+ enabled = FALSE;
+ return;
+ }
+
+ if (hNewStatusHook == NULL)
+ hNewStatusHook = HookEvent(ME_WAT_NEWSTATUS, NewStatusCallback);
+}
+
+
+void WATrack::NewStatus(int event, int value)
+{
+ EnterCriticalSection(&cs);
+
+ if (event == WAT_EVENT_PLUGINSTATUS && value != 0)
+ {
+ FreeData();
+ }
+ else
+ {
+ GetData();
+ }
+
+ LeaveCriticalSection(&cs);
+
+ NotifyInfoChanged();
+}
+
+
+void WATrack::GetData()
+{
+#ifdef UNICODE
+
+ SONGINFO *si = NULL;
+
+ int playing = CallService(MS_WAT_GETMUSICINFO, WAT_INF_UNICODE, (LPARAM) &si);
+
+#else
+
+ SONGINFOA *si = NULL;
+
+ int playing = CallService(MS_WAT_GETMUSICINFO, WAT_INF_ANSI, (LPARAM) &si);
+
+#endif
+
+ FreeData();
+
+ // See if something is playing
+ if (playing != WAT_PLS_NORMAL
+ || si == NULL
+ || si->status != 1
+ || ( IsEmpty(si->artist) && IsEmpty(si->title) ) )
+ {
+ return;
+ }
+
+ // Copy new data
+
+ listening_info.ptszAlbum = DUP(si->album);
+ listening_info.ptszArtist = DUP(si->artist);
+ listening_info.ptszTitle = DUP(si->title);
+ listening_info.ptszYear = DUP(si->year);
+
+ if (si->track > 0)
+ {
+ listening_info.ptszTrack = (TCHAR*) mir_alloc(10 * sizeof(TCHAR));
+ _itot(si->track, listening_info.ptszTrack, 10);
+ }
+
+ listening_info.ptszGenre = DUP(si->genre);
+
+ if (si->total > 0)
+ {
+ listening_info.ptszLength = (TCHAR*) mir_alloc(10 * sizeof(TCHAR));
+
+ int s = si->total % 60;
+ int m = (si->total / 60) % 60;
+ int h = (si->total / 60) / 60;
+
+ if (h > 0)
+ mir_sntprintf(listening_info.ptszLength, 9, _T("%d:%02d:%02d"), h, m, s);
+ else
+ mir_sntprintf(listening_info.ptszLength, 9, _T("%d:%02d"), m, s);
+ }
+
+ if (si->width > 0)
+ listening_info.ptszType = mir_tstrdup(_T("Video"));
+ else
+ listening_info.ptszType = mir_tstrdup(_T("Music"));
+
+ listening_info.ptszPlayer = DUPD(si->player, name);
+
+ listening_info.cbSize = sizeof(listening_info);
+ listening_info.dwFlags = LTI_TCHAR;
+}
diff --git a/Plugins/listeningto/players/watrack.h b/Plugins/listeningto/players/watrack.h
new file mode 100644
index 0000000..2a7da3b
--- /dev/null
+++ b/Plugins/listeningto/players/watrack.h
@@ -0,0 +1,35 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+class WATrack : public Player
+{
+protected:
+ HANDLE hNewStatusHook;
+
+ void GetData();
+
+public:
+ WATrack();
+ virtual ~WATrack();
+
+ void NewStatus(int event, int value);
+
+ virtual void EnableDisable();
+};
diff --git a/Plugins/listeningto/players/winamp.cpp b/Plugins/listeningto/players/winamp.cpp
new file mode 100644
index 0000000..8579538
--- /dev/null
+++ b/Plugins/listeningto/players/winamp.cpp
@@ -0,0 +1,35 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "..\\commons.h"
+
+
+static TCHAR *wcs[] = {
+ _T("Winamp v1.x")
+};
+
+Winamp::Winamp()
+{
+ name = _T("Winamp");
+ window_classes = wcs;
+ num_window_classes = MAX_REGS(wcs);
+ message_window_class = MIRANDA_WINDOWCLASS _T(".Winamp");
+ dll_name = "gen_mlt";
+}
diff --git a/Plugins/listeningto/players/winamp.h b/Plugins/listeningto/players/winamp.h
new file mode 100644
index 0000000..69a9d04
--- /dev/null
+++ b/Plugins/listeningto/players/winamp.h
@@ -0,0 +1,25 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+class Winamp : public CodeInjectionPlayer
+{
+public:
+ Winamp();
+};
diff --git a/Plugins/listeningto/players/wmp.cpp b/Plugins/listeningto/players/wmp.cpp
new file mode 100644
index 0000000..a146976
--- /dev/null
+++ b/Plugins/listeningto/players/wmp.cpp
@@ -0,0 +1,204 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "..\\commons.h"
+
+
+
+#define WMP_WINDOWCLASS _T("MsnMsgrUIManager")
+
+static LRESULT CALLBACK ReceiverWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+
+static UINT hTimer = NULL;
+
+
+WindowsMediaPlayer *singleton = NULL;
+
+
+
+WindowsMediaPlayer::WindowsMediaPlayer()
+{
+ name = _T("WindowsMediaPlayer");
+ received[0] = L'\0';
+ singleton = this;
+
+ WNDCLASS wc = {0};
+ wc.lpfnWndProc = ReceiverWndProc;
+ wc.hInstance = hInst;
+ wc.lpszClassName = WMP_WINDOWCLASS;
+
+ RegisterClass(&wc);
+
+ hWnd = CreateWindow(WMP_WINDOWCLASS, _T("Miranda ListeningTo WMP receiver"),
+ 0, 0, 0, 0, 0, NULL, NULL, hInst, NULL);
+}
+
+
+
+WindowsMediaPlayer::~WindowsMediaPlayer()
+{
+ if (hTimer != NULL)
+ {
+ KillTimer(NULL, hTimer);
+ hTimer = NULL;
+ }
+
+ DestroyWindow(hWnd);
+ hWnd = NULL;
+
+ UnregisterClass(WMP_WINDOWCLASS, hInst);
+ singleton = NULL;
+}
+
+
+
+void WindowsMediaPlayer::ProcessReceived()
+{
+ EnterCriticalSection(&cs);
+
+ FreeData();
+
+ // Do the processing
+ // MSNMusicString = L"\\0Music\\0%d\\0%s\\0%s\\0%s\\0%s\\0%s\\0\\0"
+ // MSNMusicString, msn->msncommand, strMSNFormat, msn->title, msn->artist, msn->album, msn->wmcontentid);
+
+ WCHAR *p1 = wcsstr(received, L"\\0");
+
+ if (received[0] == L'\0' || p1 == NULL)
+ {
+ LeaveCriticalSection(&cs);
+ NotifyInfoChanged();
+ return;
+ }
+
+ // Process string
+ WCHAR *parts[8] = {0};
+ int pCount = 0;
+ WCHAR *p = received;
+ do {
+ *p1 = L'\0';
+ parts[pCount] = p;
+ pCount ++;
+ p = p1 + 2;
+ p1 = wcsstr(p, L"\\0");
+ } while( p1 != NULL && pCount < 7 );
+ if (p1 != NULL)
+ *p1 = L'\0';
+ parts[pCount] = p;
+
+ // Fill cache
+ if (pCount > 4 && !IsEmpty(parts[1]) && (!IsEmpty(parts[4]) || !IsEmpty(parts[5])))
+ {
+ listening_info.cbSize = sizeof(listening_info);
+ listening_info.dwFlags = LTI_TCHAR;
+
+ listening_info.ptszType = U2T(parts[1]);
+ listening_info.ptszTitle = U2T(parts[4]);
+ listening_info.ptszArtist = U2T(parts[5]);
+ listening_info.ptszAlbum = U2T(parts[6]);
+
+ listening_info.ptszPlayer = mir_tstrdup(name);
+ }
+
+ // Put back the '\\'s
+ for(int i = 1; i <= pCount; i++)
+ *(parts[i] - 2) = L'\\';
+ if (p1 != NULL)
+ *p1 = L'\\';
+
+ LeaveCriticalSection(&cs);
+
+ NotifyInfoChanged();
+}
+
+
+
+static VOID CALLBACK SendTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ KillTimer(NULL, hTimer);
+ hTimer = NULL;
+
+ if (!loaded)
+ return;
+
+ if (singleton != NULL)
+ singleton->ProcessReceived();
+}
+
+
+void WindowsMediaPlayer::NewData(const WCHAR *data, size_t len)
+{
+ EnterCriticalSection(&cs);
+
+ len = min(len, 1023);
+ if (wcsncmp(received, data, len) != 0)
+ {
+ wcsncpy(received, data, len);
+ received[len] = L'\0';
+
+/*#ifdef UNICODE
+ m_log(_T("ReceiverWndProc"), _T("WMP : New data: [%d] %s"), len, received);
+#else
+ m_log(_T("ReceiverWndProc"), _T("WMP : New data: [%d] %S"), len, received);
+#endif
+*/
+ if (hTimer)
+ KillTimer(NULL, hTimer);
+ hTimer = SetTimer(NULL, NULL, 300, SendTimerProc); // Do the processing after we return true
+ }
+/* else
+ {
+ m_log(_T("NewData"), _T("END: Text is the same as last time"));
+ }
+*/
+ LeaveCriticalSection(&cs);
+}
+
+
+
+static LRESULT CALLBACK ReceiverWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_COPYDATA :
+ {
+ if (!loaded)
+ return FALSE;
+
+ if (singleton == NULL || !singleton->enabled)
+ return FALSE;
+
+ COPYDATASTRUCT* pData = (PCOPYDATASTRUCT) lParam;
+ if (pData->dwData != 0x547 || pData->cbData == 0 || pData->lpData == NULL)
+ return FALSE;
+
+ if (singleton != NULL)
+ singleton->NewData((WCHAR *) pData->lpData, pData->cbData / 2);
+
+ return TRUE;
+ }
+ case WM_DESTROY :
+ PostQuitMessage(0);
+ break;
+ }
+
+ return DefWindowProc(hWnd, message, wParam, lParam);
+} \ No newline at end of file
diff --git a/Plugins/listeningto/players/wmp.h b/Plugins/listeningto/players/wmp.h
new file mode 100644
index 0000000..a7cdc87
--- /dev/null
+++ b/Plugins/listeningto/players/wmp.h
@@ -0,0 +1,33 @@
+/*
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+class WindowsMediaPlayer : public Player
+{
+protected:
+ HWND hWnd;
+ WCHAR received[1024];
+
+public:
+ WindowsMediaPlayer();
+ virtual ~WindowsMediaPlayer();
+
+ void ProcessReceived();
+ void NewData(const WCHAR *data, size_t len);
+};
diff --git a/Plugins/listeningto/res/listening_to.ico b/Plugins/listeningto/res/listening_to.ico
new file mode 100644
index 0000000..d359ec1
--- /dev/null
+++ b/Plugins/listeningto/res/listening_to.ico
Binary files differ
diff --git a/Plugins/listeningto/res/ttb_disabled.bmp b/Plugins/listeningto/res/ttb_disabled.bmp
new file mode 100644
index 0000000..df1a9ab
--- /dev/null
+++ b/Plugins/listeningto/res/ttb_disabled.bmp
Binary files differ
diff --git a/Plugins/listeningto/res/ttb_enabled.bmp b/Plugins/listeningto/res/ttb_enabled.bmp
new file mode 100644
index 0000000..98467fb
--- /dev/null
+++ b/Plugins/listeningto/res/ttb_enabled.bmp
Binary files differ
diff --git a/Plugins/listeningto/resource.h b/Plugins/listeningto/resource.h
new file mode 100644
index 0000000..91972b8
--- /dev/null
+++ b/Plugins/listeningto/resource.h
@@ -0,0 +1,93 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDD_OPTIONS 119
+#define IDD_PLAYERS 120
+#define IDD_FORMAT 121
+#define IDB_TTB_UP_DISABLED 122
+#define IDB_TTB_UP_ENABLED 123
+#define IDI_LISTENINGTO 124
+#define IDC_DELAY 1001
+#define IDC_WINCOLORS 1002
+#define IDC_DEFAULTCOLORS 1003
+#define IDC_BGCOLOR 1004
+#define IDC_TEXTCOLOR 1005
+#define IDC_PREV 1006
+#define IDC_DELAYFROMPU 1007
+#define IDC_DELAYCUSTOM 1008
+#define IDC_DELAYPERMANENT 1009
+#define IDC_VARS2_L 1016
+#define IDC_VARS_L 1017
+#define IDC_LISTENING_L 1018
+#define IDC_ADV_ICON 1019
+#define IDC_ENABLE_SEND 1020
+#define IDC_WATRACK 1021
+#define IDC_RIGHT_ACTION 1022
+#define IDC_LEFT_ACTION 1023
+#define IDC_PROTOCOLS 1041
+#define IDC_MESSAGE_L 1055
+#define IDC_LISTENINGTO_G 1056
+#define IDC_XSTATUS_MESSAGE 1057
+#define IDC_TEMPLATE 1058
+#define IDC_UNKNOWN 1059
+#define IDC_SHOW_ADV_ICON 1060
+#define IDC_NOTHING 1060
+#define IDC_CODE_INJECTION 1061
+#define IDC_ENABLE_MENU 1062
+#define IDC_FORMAT_G 1063
+#define IDC_TEMPLATE_L 1064
+#define IDC_UNKNOWN_L 1065
+#define IDC_PROTOCOLS_G 1066
+#define IDC_NOTHING_L 1066
+#define IDC_PROTOCOLS_L 1067
+#define IDC_TRACK_CHANGE 1068
+#define IDC_OVERRIDE_CONTACTS_TEMPLATE 1069
+#define IDC_ONLY_NOT_OFFLINE 1070
+#define IDC_TYPE_L 1075
+#define IDC_PLAYER_L 1076
+#define IDC_LENGTH_L 1077
+#define IDC_GENRE_L 1078
+#define IDC_YEAR_L 1079
+#define IDC_TRACK_L 1080
+#define IDC_TITLE_L 1081
+#define IDC_ALBUM_L 1082
+#define IDC_ARTIST_L 1083
+#define IDC_WINAMP 1085
+#define IDC_ITUNES 1086
+#define IDC_POLL_TIMER 1087
+#define IDC_WMP 1088
+#define IDC_PLAYERS_L 1089
+#define IDC_POLL_TIMER_L 1090
+#define IDC_POLL_TIMER_S_L 1091
+#define IDC_OTHER 1092
+#define IDC_CONTACTS_G 1093
+#define IDC_FOOBAR 1093
+#define IDC_LISTENING_G 1094
+#define IDC_XSTATUS_G 1095
+#define IDC_XSTATUS_L 1096
+#define IDC_SET_XSTATUS 1097
+#define IDC_CHECK_XSTATUS 1098
+#define IDC_IGNORE_XSTATUS 1099
+#define IDC_XSTATUS_NAME 1100
+#define IDC_CHECK_XSTATUS_MUSIC 1100
+#define IDC_NAME_L 1101
+#define IDC_ENABLE_MUSIC 1102
+#define IDC_ENABLE_RADIO 1103
+#define IDC_ENABLE_VIDEO 1104
+#define IDC_ENABLE_OTHERS 1105
+#define IDC_POLL_TIMER_SPIN 1625
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_3D_CONTROLS 1
+#define _APS_NEXT_RESOURCE_VALUE 124
+#define _APS_NEXT_COMMAND_VALUE 40004
+#define _APS_NEXT_CONTROL_VALUE 1103
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Plugins/listeningto/resource.rc b/Plugins/listeningto/resource.rc
new file mode 100644
index 0000000..f45d179
--- /dev/null
+++ b/Plugins/listeningto/resource.rc
@@ -0,0 +1,243 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "resource.h"
+#include "winresrc.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPTIONS DIALOGEX 0, 0, 288, 220
+STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX " Listening to information ",IDC_LISTENING_G,3,12,282,58
+ CONTROL "Enable sending listening information to contacts:",
+ IDC_ENABLE_SEND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,
+ 26,262,11
+ CONTROL "Music",IDC_ENABLE_MUSIC,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,26,40,52,11
+ CONTROL "Radio",IDC_ENABLE_RADIO,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,92,40,52,11
+ CONTROL "Video",IDC_ENABLE_VIDEO,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,158,40,52,11
+ CONTROL "Others",IDC_ENABLE_OTHERS,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,224,40,52,11
+ LTEXT "You also have to enable it per protocol in the main menu",
+ IDC_STATIC,12,55,262,13
+ GROUPBOX " XStatus ",IDC_XSTATUS_G,3,74,282,88
+ LTEXT "For protocols that don't support listening to but support XStatus:",
+ IDC_XSTATUS_L,12,88,263,11
+ CONTROL "Set XStatus to Music and show listening info",
+ IDC_SET_XSTATUS,"Button",BS_AUTORADIOBUTTON,19,101,257,
+ 12
+ CONTROL "If other XStatus is not set, set XStatus to Music and show listening info",
+ IDC_CHECK_XSTATUS,"Button",BS_AUTORADIOBUTTON,19,115,257,
+ 12
+ CONTROL "If XStatus is Music, show listening info",
+ IDC_CHECK_XSTATUS_MUSIC,"Button",BS_AUTORADIOBUTTON,19,
+ 129,257,12
+ CONTROL "Do nothing",IDC_IGNORE_XSTATUS,"Button",
+ BS_AUTORADIOBUTTON,19,143,257,12
+ GROUPBOX " Contacts ",IDC_CONTACTS_G,3,166,282,49
+ CONTROL "Apply template for info from contacts (overrides contacts template)",
+ IDC_OVERRIDE_CONTACTS_TEMPLATE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,12,180,262,11
+ CONTROL "Show advanced icon in slot",IDC_SHOW_ADV_ICON,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,12,193,104,13
+ COMBOBOX IDC_ADV_ICON,122,193,46,15,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+END
+
+IDD_PLAYERS DIALOGEX 0, 0, 288, 224
+STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg"
+BEGIN
+ CONTROL "Get info from WATrack plugin",IDC_WATRACK,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,3,12,282,11
+ LTEXT "Get info from these players:",IDC_PLAYERS_L,3,30,282,11
+ CONTROL "Winamp (*)",IDC_WINAMP,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,20,44,265,11
+ CONTROL "Windows Media Player",IDC_WMP,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,20,59,265,11
+ CONTROL "iTunes",IDC_ITUNES,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,20,74,265,11
+ CONTROL "foobar2000 (need to install the plugin manually)",
+ IDC_FOOBAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,89,
+ 265,11
+ CONTROL "Other players",IDC_OTHER,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,20,104,265,11
+ LTEXT "Ask for new info every",IDC_POLL_TIMER_L,3,126,87,12
+ EDITTEXT IDC_POLL_TIMER,97,125,34,13,ES_AUTOHSCROLL
+ CONTROL "",IDC_POLL_TIMER_SPIN,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS |
+ UDS_HOTTRACK,125,123,11,12
+ LTEXT "seconds",IDC_POLL_TIMER_S_L,138,126,82,12
+ CONTROL "Allow auto-loading plugins into players (affect players with *)",
+ IDC_CODE_INJECTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 3,142,282,11
+END
+
+IDD_FORMAT DIALOGEX 0, 0, 288, 221
+STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX " Listening to ",IDC_LISTENINGTO_G,3,8,282,125
+ LTEXT "Template:",IDC_TEMPLATE_L,11,22,55,10
+ EDITTEXT IDC_TEMPLATE,72,20,202,13,ES_AUTOHSCROLL
+ LTEXT "Variables:",IDC_VARS_L,11,39,129,8
+ LTEXT "%artist% - Artist name",IDC_ARTIST_L,11,51,129,8
+ LTEXT "%album% - Album name",IDC_ALBUM_L,148,51,129,8
+ LTEXT "%title% - Song title",IDC_TITLE_L,11,63,129,8
+ LTEXT "%track% - Track number",IDC_TRACK_L,148,63,129,8
+ LTEXT "%year% - Song year",IDC_YEAR_L,11,75,129,8
+ LTEXT "%genre% - Song genre",IDC_GENRE_L,148,75,129,8
+ LTEXT "%length% - Song length",IDC_LENGTH_L,11,87,129,8
+ LTEXT "%player% - Player name",IDC_PLAYER_L,148,87,129,8
+ LTEXT "%type% - Media type (Music, Radio, Video, etc)",
+ IDC_TYPE_L,11,99,265,8
+ LTEXT "When variable not found, use:",IDC_UNKNOWN_L,11,117,108,
+ 10
+ EDITTEXT IDC_UNKNOWN,122,114,152,13,ES_AUTOHSCROLL
+ GROUPBOX " XStatus ",IDC_XSTATUS_G,3,137,282,79
+ LTEXT "Title:",IDC_NAME_L,11,152,55,10
+ EDITTEXT IDC_XSTATUS_NAME,72,150,202,13,ES_AUTOHSCROLL
+ LTEXT "Message:",IDC_MESSAGE_L,11,167,55,10
+ EDITTEXT IDC_XSTATUS_MESSAGE,72,165,202,13,ES_AUTOHSCROLL
+ LTEXT "Other Variables:",IDC_VARS2_L,11,183,58,8
+ LTEXT "%listening% - Listening to info (as set above)",
+ IDC_LISTENING_L,72,183,201,8
+ LTEXT "When nothing is playing, replace %listening% with:",
+ IDC_NOTHING_L,11,199,171,10
+ EDITTEXT IDC_NOTHING,183,197,91,13,ES_AUTOHSCROLL
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_OPTIONS, DIALOG
+ BEGIN
+ LEFTMARGIN, 3
+ RIGHTMARGIN, 285
+ TOPMARGIN, 12
+ BOTTOMMARGIN, 217
+ END
+
+ IDD_PLAYERS, DIALOG
+ BEGIN
+ LEFTMARGIN, 3
+ RIGHTMARGIN, 285
+ TOPMARGIN, 12
+ BOTTOMMARGIN, 221
+ END
+
+ IDD_FORMAT, DIALOG
+ BEGIN
+ LEFTMARGIN, 3
+ RIGHTMARGIN, 285
+ TOPMARGIN, 8
+ BOTTOMMARGIN, 218
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_TTB_UP_DISABLED BITMAP DISCARDABLE "res\\ttb_disabled.bmp"
+IDB_TTB_UP_ENABLED BITMAP DISCARDABLE "res\\ttb_enabled.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_LISTENINGTO ICON DISCARDABLE "res\\listening_to.ico"
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (Canada) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENC)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_CAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""resource.h""\r\n"
+ "#include ""winresrc.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (Canada) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Plugins/listeningto/sdk/m_cluiframes.h b/Plugins/listeningto/sdk/m_cluiframes.h
new file mode 100644
index 0000000..bf6d565
--- /dev/null
+++ b/Plugins/listeningto/sdk/m_cluiframes.h
@@ -0,0 +1,338 @@
+/*
+Miranda ICQ: the free icq client for MS Windows
+Copyright (C) 2000-2 Richard Hughes, Roland Rabien & Tristan Van de Vreede
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/************************************************************************/
+/* Extra Image Column Support +0.5.0.0 */
+/************************************************************************/
+/*
+ HINT: Common usage of Extra icons by modules
+ Usage sequence is next:
+ The Plugin have to be subscribed to ME_CLIST_EXTRA_LIST_REBUILD and
+ ME_CLIST_EXTRA_IMAGE_APPLY notifications.
+
+ During .._REBUILD Notification handle plugin should register required
+ icons in CList internal list via MS_CLIST_EXTRA_ADD_ICON servise
+ and should to keep returned icon indexes.
+
+ Note: _REBUILD notification means that list was rebuilded and
+ all previously registered icon indexes became invalid and can not be used.
+
+ Note: After calling _ADD_ICON services the icon handle you provided is not
+ need for extra images porpouses and have to be released by you in order
+ to reduce GDI resources consumptions.
+
+ Note: Don't forget that icon handle loaded by LoadIcon GDI function is
+ shared and will be kept in memory till plugin unloading. So it is not
+ better way to load icon. Please use appropriate Iconlib services.
+
+ Note: The icon can be registered in Clist at any time.
+
+ During .._ME_CLIST_EXTRA_IMAGE_APPLY the plugin has to call
+ MS_CLIST_EXTRA_SET_ICON passing appropriate icon index for contact. This
+ service can be called any time in order to change current extra image.
+
+ ATTENTION: Currently Module support only 254 registered extra icons. The returned
+ value 0xFF internally means 'No extra icon' so thry t register only realy required
+ icons. The best solution - register not registered/invalidated icon just before
+ setting of extra image.
+
+ ATTENTION: Due to different module may use same extra icons slot - they will be conflicted.
+ Please provide ability to end-user to change extra image slot to be used to show
+ your plugin information.
+
+*/
+
+//Extra columns type.
+//column arranged in this way
+//
+// [statusicon] ContactName [WEB][ADV1][ADV2][SMS][EMAIL][PROTO][CLIENT]
+//
+#define EXTRA_ICON_EMAIL 1
+#define EXTRA_ICON_PROTO 2
+#define EXTRA_ICON_SMS 3
+#define EXTRA_ICON_ADV1 4
+#define EXTRA_ICON_ADV2 5
+#define EXTRA_ICON_WEB 6
+#define EXTRA_ICON_CLIENT 7
+#define EXTRA_ICON_VISMODE 8
+#define EXTRA_ICON_ADV3 9
+#define EXTRA_ICON_ADV4 10
+
+#define EXTRA_ICON_COUNT 10
+
+typedef struct
+{
+ int cbSize; //must be sizeof(IconExtraColumn)
+ int ColumnType;
+ HANDLE hImage; //return value from MS_CLIST_EXTRA_ADD_ICON
+}IconExtraColumn,*pIconExtraColumn;
+
+//Set icon for contact at needed column
+//wparam=hContact
+//lparam=pIconExtraColumn
+//return 0 on success,-1 on failure
+//
+//See above for supported columns
+#define MS_CLIST_EXTRA_SET_ICON "CListFrames/SetIconForExraColumn"
+
+//Adding icon to extra image list.
+//Call this in ME_CLIST_EXTRA_LIST_REBUILD event
+//
+//wparam=hIcon
+//lparam=0
+//return hImage on success,-1 on failure
+#define MS_CLIST_EXTRA_ADD_ICON "CListFrames/AddIconToExtraImageList"
+
+#define ME_CLIST_EXTRA_LIST_REBUILD "CListFrames/OnExtraListRebuild"
+
+//called with wparam=hContact
+#define ME_CLIST_EXTRA_IMAGE_APPLY "CListFrames/OnExtraImageApply"
+
+//End of extra images header. TODO move it to separate m_extraimages.h file
+//Cause it has not any relationship to cluiframes engine
+
+
+/************************************************************************/
+/* CLUI Frames Support */
+/************************************************************************/
+
+// NOTE: Clui frames engine is in to be reconsructed..
+
+// Constants used bellow
+typedef struct tagCLISTFrame {
+ DWORD cbSize;
+ HWND hWnd ;
+ HICON hIcon;
+ int align; //al flags below
+ union _tagMinSize{
+ int height;
+ int minSize; //the actual meaning depends from type of frame
+ };
+ int Flags; //F_flags below
+ union {
+ char *name; //frame window name indentifier (DO NOT TRANSLATE)
+ wchar_t *wname;
+ LPTSTR tname;
+ };
+ union {
+ char *TBname; //titlebar & menu caption
+ wchar_t *TBwname;
+ LPTSTR TBtname;
+ };
+} CLISTFrame;
+
+#define F_VISIBLE 1 //Frame visible
+#define F_SHOWTB 2 //Show TitleBar
+#define F_UNCOLLAPSED 4 //UnCollapse frame
+#define F_LOCKED 8 //Lock Frame
+#define F_NOBORDER 16 //Dont apply WS_BORDER style for window
+#define F_SHOWTBTIP 32 //Show titlebar tooltip
+#define F_CANBEVERTICAL 64 //frames can be vertical
+#define F_CANNOTBEHORIZONTAL 128 //frames can NOT be horizontal F_CANBEVERTICAL have to be set
+#define F_NO_SUBCONTAINER 1024 //Support skining no subcontainer needed
+#define F_UNICODE 32768 //Use unicode text
+#ifdef _UNICODE
+# define F_TCHAR F_UNICODE
+#else
+# define F_TCHAR 0
+#endif
+
+// frame alignment
+#define alTop 0x00000001
+#define alBottom 0x00000002
+#define alClient 0x00000004 //only one alClient frame
+
+// since 0.7.0.20
+#define alLeft 0x00000011 // frame is vertical
+#define alRight 0x00000012
+
+#define alVertFrameMask 0x00000010
+
+#define FU_TBREDRAW 1 //redraw titlebar
+#define FU_FMREDRAW 2 //redraw Frame
+#define FU_FMPOS 4 //update Frame position
+
+#define FO_FLAGS 0x0001 //return set of F_VISIBLE,F_SHOWTB,F_UNCOLLAPSED,F_LOCKED,F_NOBORDER,F_SHOWTBTIP
+#define FO_NAME 0x0002 //Change name
+#define FO_TBNAME 0x0003 //Change TB caption
+#define FO_TBSTYLE 0x0004 //Change TB style
+#define FO_TBEXSTYLE 0x0005 //Change TB exstyle
+#define FO_ICON 0x0006 //Change icon
+#define FO_HEIGHT 0x0007 //Change height
+#define FO_ALIGN 0x0008 //Change align
+#define FO_TBTIPNAME 0x0009 //Change TB tooltip
+#define FO_FLOATING 0x000a //Change floating mode
+
+#define FO_UNICODETEXT 0x8000 // flag for FO_NAME,FO_TBNAME, FO_TBTIPNAME set/get lPAram as unicode wchar_t
+#ifdef _UNICODE
+ #define FO_TCHAR FO_UNICODETEXT
+#else
+ #define FO_TCHAR 0x0000
+#endif
+
+
+//////////////////////////////////////////////////////////////////////////
+//want show tooltip for statusbar
+//wparam=(char *)protocolname
+//lparam=0
+#define ME_CLIST_FRAMES_SB_SHOW_TOOLTIP "CListFrames/StatusBarShowToolTip"
+
+//////////////////////////////////////////////////////////////////////////
+//want hide tooltip for statusbar
+//wparam=lparam=0
+#define ME_CLIST_FRAMES_SB_HIDE_TOOLTIP "CListFrames/StatusBarHideToolTip"
+
+//////////////////////////////////////////////////////////////////////////
+//adds a frame window
+//wParam=(CLISTFrame*)
+//lParam=0
+//returns an integer, the frame id.
+#define MS_CLIST_FRAMES_ADDFRAME "CListFrames/AddFrame"
+
+//////////////////////////////////////////////////////////////////////////
+// remove frame. It destroy your window
+//
+#define MS_CLIST_FRAMES_REMOVEFRAME "CListFrames/RemoveFrame"
+
+//////////////////////////////////////////////////////////////////////////
+//shows all frames
+//wParam=lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_SHOWALLFRAMES "CListFrames/ShowALLFrames"
+
+//////////////////////////////////////////////////////////////////////////
+//shows the titlebars of all frames
+//wParam=lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_SHOWALLFRAMESTB "CListFrames/ShowALLFramesTB"
+
+//////////////////////////////////////////////////////////////////////////
+//hides the titlebars of all frames
+//wParam=lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_HIDEALLFRAMESTB "CListFrames/HideALLFramesTB"
+
+//////////////////////////////////////////////////////////////////////////
+//shows the frame if it is hidden,
+//hides the frame if it is shown
+//wParam=FrameId
+//lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_SHFRAME "CListFrames/SHFrame"
+
+//////////////////////////////////////////////////////////////////////////
+//shows the frame titlebar if it is hidden,
+//hides the frame titlebar if it is shown
+//wParam=FrameId
+//lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_SHFRAMETITLEBAR "CListFrame/SHFrameTitleBar"
+
+//////////////////////////////////////////////////////////////////////////
+//locks the frame if it is unlocked,
+//unlock the frame if it is locked
+//wParam=FrameId
+//lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_ULFRAME "CListFrame/ULFrame"
+
+//////////////////////////////////////////////////////////////////////////
+//collapses the frame if it is uncollapsed,
+//uncollapses the frame if it is collapsed
+//wParam=FrameId
+//lParam=0
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_UCOLLFRAME "CListFrame/UCOLLFrame"
+
+//////////////////////////////////////////////////////////////////////////
+//trigger border flags
+//wparam=frameid
+//lparam=0
+#define MS_CLIST_FRAMES_SETUNBORDER "CListFrame/SetUnBorder"
+
+//////////////////////////////////////////////////////////////////////////
+//redraws the frame
+//wParam=FrameId, -1 for all frames
+//lparam=FU_flags
+//returns a pointer to option, -1 on failure
+#define MS_CLIST_FRAMES_UPDATEFRAME "CListFrame/UpdateFrame"
+
+//////////////////////////////////////////////////////////////////////////
+//gets the frame options
+//(HIWORD)wParam=FrameId
+//(LOWORD)wParam=FO_flag
+//lParam=0
+//returns a pointer to option, -1 on failure
+#define MS_CLIST_FRAMES_GETFRAMEOPTIONS "CListFrame/GetFrameOptions"
+
+//sets the frame options
+//(HIWORLD)wParam=FrameId
+//(LOWORD)wParam=FO_flag
+//lParam=value
+//returns 0 on success, -1 on failure
+#define MS_CLIST_FRAMES_SETFRAMEOPTIONS "CListFrame/SetFrameOptions"
+
+//////////////////////////////////////////////////////////////////////////
+//Frames related menu stuff
+//////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////
+//add a new item to the context frame menu
+//wParam=0
+//lParam=(LPARAM)(CLISTMENUITEM*)&mi
+//returns a handle to the new item
+//popupposition=frameid
+//contactowner=advanced parameter
+#define MS_CLIST_ADDCONTEXTFRAMEMENUITEM "CList/AddContextFrameMenuItem"
+
+//////////////////////////////////////////////////////////////////////////
+//remove a item from context frame menu
+//wParam=hMenuItem returned by MS_CLIST_ADDCONTACTMENUITEM
+//lParam=0
+//returns 0 on success, nonzero on failure
+#define MS_CLIST_REMOVECONTEXTFRAMEMENUITEM "CList/RemoveContextFrameMenuItem"
+
+//////////////////////////////////////////////////////////////////////////
+//builds the context menu for a frame
+//wparam=frameid
+//lParam=0
+//returns a HMENU on success, or NULL on failure
+#define MS_CLIST_MENUBUILDFRAMECONTEXT "CList/BuildContextFrameMenu"
+
+//////////////////////////////////////////////////////////////////////////
+// the frame menu is about to be built
+// wparam=frameid
+// lparam=
+// -1 for build from titlebar,
+// use
+// MS_CLIST_ADDCONTEXTFRAMEMENUITEM
+// MS_CLIST_REMOVECONTEXTFRAMEMENUITEM
+//
+// >0 for build in main menu,
+// must be popupname=lparam to place your items in right popup of main menu.
+// use
+// MS_CLIST_ADDMAINMENUITEM
+// MS_CLIST_REMOVEMAINMENUITEM
+//
+#define ME_CLIST_PREBUILDFRAMEMENU "CList/PreBuildFrameMenu"
+
+//////////////////////////////////////////////////////////////////////////
+//needed by cluiframes module to add frames menu to main menu.
+//it just calls NotifyEventHooks(hPreBuildFrameMenuEvent,wParam,lParam);
+#define MS_CLIST_FRAMEMENUNOTIFY "CList/ContextFrameMenuNotify"
diff --git a/Plugins/listeningto/sdk/m_metacontacts.h b/Plugins/listeningto/sdk/m_metacontacts.h
new file mode 100644
index 0000000..1da12b9
--- /dev/null
+++ b/Plugins/listeningto/sdk/m_metacontacts.h
@@ -0,0 +1,162 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright © 2004 Universite Louis PASTEUR, STRASBOURG.
+Copyright © 2004 Scott Ellis (www.scottellis.com.au mail@scottellis.com.au)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_METACONTACTS_H__
+#define M_METACONTACTS_H__ 1
+
+//get the handle for a contact's parent metacontact
+//wParam=(HANDLE)hSubContact
+//lParam=0
+//returns a handle to the parent metacontact, or null if this contact is not a subcontact
+#define MS_MC_GETMETACONTACT "MetaContacts/GetMeta"
+
+//gets the handle for the default contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a handle to the default contact, or null on failure
+#define MS_MC_GETDEFAULTCONTACT "MetaContacts/GetDefault"
+
+//gets the contact number for the default contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a DWORD contact number, or -1 on failure
+#define MS_MC_GETDEFAULTCONTACTNUM "MetaContacts/GetDefaultNum"
+
+//gets the handle for the 'most online' contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a handle to the 'most online' contact
+#define MS_MC_GETMOSTONLINECONTACT "MetaContacts/GetMostOnline"
+
+//gets the number of subcontacts for a metacontact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a DWORD representing the number of subcontacts for the given metacontact
+#define MS_MC_GETNUMCONTACTS "MetaContacts/GetNumContacts"
+
+//gets the handle of a subcontact, using the subcontact's number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns a handle to the specified subcontact
+#define MS_MC_GETSUBCONTACT "MetaContacts/GetSubContact"
+
+//sets the default contact, using the subcontact's contact number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns 0 on success
+#define MS_MC_SETDEFAULTCONTACTNUM "MetaContacts/SetDefault"
+
+//sets the default contact, using the subcontact's handle
+//wParam=(HANDLE)hMetaContact
+//lParam=(HANDLE)hSubcontact
+//returns 0 on success
+#define MS_MC_SETDEFAULTCONTACT "MetaContacts/SetDefaultByHandle"
+
+//forces the metacontact to send using a specific subcontact, using the subcontact's contact number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns 0 on success
+#define MS_MC_FORCESENDCONTACTNUM "MetaContacts/ForceSendContact"
+
+//forces the metacontact to send using a specific subcontact, using the subcontact's handle
+//wParam=(HANDLE)hMetaContact
+//lParam=(HANDLE)hSubcontact
+//returns 0 on success (will fail if 'force default' is in effect)
+#define MS_MC_FORCESENDCONTACT "MetaContacts/ForceSendContactByHandle"
+
+//'unforces' the metacontact to send using a specific subcontact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns 0 on success (will fail if 'force default' is in effect)
+#define MS_MC_UNFORCESENDCONTACT "MetaContacts/UnforceSendContact"
+
+//'forces' or 'unforces' (i.e. toggles) the metacontact to send using it's default contact
+// overrides (and clears) 'force send' above, and will even force use of offline contacts
+// will send ME_MC_FORCESEND or ME_MC_UNFORCESEND event
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns 1(true) or 0(false) representing new state of 'force default'
+#define MS_MC_FORCEDEFAULT "MetaContacts/ForceSendDefault"
+
+// method to get state of 'force' for a metacontact
+// wParam=(HANDLE)hMetaContact
+// lParam= (DWORD)&contact_number or NULL
+//
+// if lparam supplied, the contact_number of the contatct 'in force' will be copied to the address it points to,
+// or if none is in force, the value (DWORD)-1 will be copied
+// (v0.8.0.8+ returns 1 if 'force default' is true with *lParam == default contact number, else returns 0 with *lParam as above)
+#define MS_MC_GETFORCESTATE "MetaContacts/GetForceState"
+
+// fired when a metacontact's default contact changes (fired upon creation of metacontact also, when default is initially set)
+// wParam=(HANDLE)hMetaContact
+// lParam=(HANDLE)hDefaultContact
+#define ME_MC_DEFAULTTCHANGED "MetaContacts/DefaultChanged"
+
+// fired when a metacontact's subcontacts change (fired upon creation of metacontact, when contacts are added or removed, and when
+// contacts are reordered) - a signal to re-read metacontact data
+// wParam=(HANDLE)hMetaContact
+// lParam=0
+#define ME_MC_SUBCONTACTSCHANGED "MetaContacts/SubcontactsChanged"
+
+// fired when a metacontact is forced to send using a specific subcontact
+// wParam=(HANDLE)hMetaContact
+// lParam=(HANDLE)hForceContact
+#define ME_MC_FORCESEND "MetaContacts/ForceSend"
+
+// fired when a metacontact is 'unforced' to send using a specific subcontact
+// wParam=(HANDLE)hMetaContact
+// lParam=0
+#define ME_MC_UNFORCESEND "MetaContacts/UnforceSend"
+
+// method to get protocol name - used to be sure you're dealing with a "real" metacontacts plugin :)
+// wParam=lParam=0
+#define MS_MC_GETPROTOCOLNAME "MetaContacts/GetProtoName"
+
+
+// added 0.9.5.0 (22/3/05)
+// wParam=(HANDLE)hContact
+// lParam=0
+// convert a given contact into a metacontact
+#define MS_MC_CONVERTTOMETA "MetaContacts/ConvertToMetacontact"
+
+// added 0.9.5.0 (22/3/05)
+// wParam=(HANDLE)hContact
+// lParam=(HANDLE)hMeta
+// add an existing contact to a metacontact
+#define MS_MC_ADDTOMETA "MetaContacts/AddToMetacontact"
+
+// added 0.9.5.0 (22/3/05)
+// wParam=0
+// lParam=(HANDLE)hContact
+// remove a contact from a metacontact
+#define MS_MC_REMOVEFROMMETA "MetaContacts/RemoveFromMetacontact"
+
+
+// added 0.9.13.2 (6/10/05)
+// wParam=(BOOL)disable
+// lParam=0
+// enable/disable the 'hidden group hack' - for clists that support subcontact hiding using 'IsSubcontact' setting
+// should be called once in the clist 'onmodulesloaded' event handler (which, since it's loaded after the db, will be called
+// before the metacontact onmodulesloaded handler where the subcontact hiding is usually done)
+#define MS_MC_DISABLEHIDDENGROUP "MetaContacts/DisableHiddenGroup"
+
+#endif
diff --git a/Plugins/listeningto/sdk/m_music.h b/Plugins/listeningto/sdk/m_music.h
new file mode 100644
index 0000000..4f10475
--- /dev/null
+++ b/Plugins/listeningto/sdk/m_music.h
@@ -0,0 +1,345 @@
+#ifndef M_MUSIC
+#define M_MUSIC
+
+#define MIID_WATRACK {0xfc6c81f4, 0x837e, 0x4430, {0x96, 0x01, 0xa0, 0xaa, 0x43, 0x17, 0x7a, 0xe3}}
+
+typedef struct tSongInfoA {
+ CHAR *artist;
+ CHAR *title;
+ CHAR *album;
+ CHAR *genre;
+ CHAR *comment;
+ CHAR *year;
+ CHAR *mfile; // media file
+ int kbps;
+ int khz;
+ int channels;
+ int track;
+ int total; // music length
+ int time; // elapsed time
+ CHAR *wndtext; // window title
+ CHAR *player; // player name
+ int plyver; // player version
+ HANDLE icon; // player icon
+ int fsize; // media file size
+ int vbr;
+ int status; // player status: 0 - stopped; 1 - playing; 2 - paused
+ HWND plwnd; // player window
+ // video part
+ int codec;
+ int width;
+ int height;
+ int fps;
+ __int64 date;
+ CHAR *txtver;
+ CHAR *lyric;
+ CHAR *cover;
+ int volume;
+ CHAR *url;
+} SONGINFOA, *LPSONGINFOA;
+
+typedef struct tSongInfo {
+ WCHAR *artist;
+ WCHAR *title;
+ WCHAR *album;
+ WCHAR *genre;
+ WCHAR *comment;
+ WCHAR *year;
+ WCHAR *mfile; // media file
+ int kbps;
+ int khz;
+ int channels;
+ int track;
+ int total; // music length
+ int time; // elapsed time
+ WCHAR *wndtext; // window title
+ WCHAR *player; // player name
+ int plyver; // player version
+ HANDLE icon; // player icon
+ int fsize; // media file size
+ int vbr;
+ int status; // player status: 0 - stopped; 1 - playing; 2 - paused
+ HWND plwnd; // player window
+ // video part
+ int codec;
+ int width;
+ int height;
+ int fps;
+ __int64 date;
+ WCHAR txtver;
+ // not implemented yet
+ WCHAR *lyric;
+ WCHAR *cover;
+ int volume;
+ WCHAR *url;
+} SONGINFO, *LPSONGINFO;
+
+#if defined(_UNICODE)
+ #define WAT_INF_TCHAR WAT_INF_UNICODE
+ #define SongInfoT tSongInfo
+#else
+ #define WAT_INF_TCHAR WAT_INF_ANSI
+ #define SongInfoT tSongInfoA
+#endif
+
+ // result codes
+#define WAT_RES_UNKNOWN -2
+#define WAT_RES_NOTFOUND -1
+#define WAT_RES_ERROR WAT_RES_NOTFOUND
+#define WAT_RES_OK 0
+#define WAT_RES_ENABLED WAT_RES_OK
+#define WAT_RES_DISABLED 1
+ // internal
+#define WAT_RES_NEWFILE 3
+
+#define WAT_PLS_NORMAL WAT_RES_OK
+#define WAT_PLS_NOMUSIC WAT_RES_DISABLED
+#define WAT_PLS_NOTFOUND WAT_RES_NOTFOUND
+
+#define WAT_INF_UNICODE 0
+#define WAT_INF_ANSI 1
+#define WAT_INF_UTF8 2
+#define WAT_INF_CHANGES 0x100
+
+/*
+ wParam : WAT_INF_* constant
+ lParam : pointer to LPSONGINGO (Unicode) or LPSONGINFOA (ANSI/UTF8)
+ Affects: Fill structure by currently played music info
+ returns: WAT_PLS_* constant
+ note: pointer will be point to global SONGINFO structure of plugin
+ warning: Non-Unicode data filled only by request
+ if lParam=0 only internal SongInfo structure will be filled
+ Example:
+ LPSONGINFO p;
+ PluginLink->CallService(MS_WAT_GETMUSICINFO,0,(DWORD)&p);
+*/
+
+#define MS_WAT_GETMUSICINFO "WATrack/GetMusicInfo"
+
+/*
+ wParam:0
+ lParam : pointer to pSongInfo (Unicode)
+ Affects: Fill structure by info from file named in SongInfo.mfile
+ returns: 0, if success
+ note: fields, which values can't be obtained, leaves old values.
+ you must free given strings by miranda mmi.free
+*/
+#define MS_WAT_GETFILEINFO "WATrack/GetFileInfo"
+
+/*
+ Get user's Music Info
+*/
+#define MS_WAT_GETCONTACTINFO = "WATrack/GetContactInfo"
+
+#define WAT_CTRL_PREV 1
+#define WAT_CTRL_PLAY 2
+#define WAT_CTRL_PAUSE 3
+#define WAT_CTRL_STOP 4
+#define WAT_CTRL_NEXT 5
+#define WAT_CTRL_VOLDN 6
+#define WAT_CTRL_VOLUP 7
+#define WAT_CTRL_SEEK 8 // lParam is new position (sec)
+/*
+ wParam: button code (WAT_CTRL_* const)
+ lParam: 0, or value (see WAT_CTRL_* const comments)
+ Affects: emulate player button pressing
+ returns: 0 if unsuccesful
+*/
+#define MS_WAT_PRESSBUTTON "WATrack/PressButton"
+
+// ------------ Plugin/player status ------------
+
+/*
+ wParam: 1 - switch off plugin
+ 0 - switch on plugin
+ -1 - switch plugin status
+ other - get plugin status
+ lParam: 0
+ Affects: Switch plugin status to enabled or disabled
+ returns: old plugin status, 0, if was enabled
+*/
+
+#define MS_WAT_PLUGINSTATUS "WATrack/PluginStatus"
+
+#define ME_WAT_MODULELOADED "WATrack/ModuleLoaded"
+
+#define WAT_EVENT_PLAYERSTATUS 1 // 0-normal; 1-no music (possibly stopped); 2-not found
+#define WAT_EVENT_NEWTRACK 2
+#define WAT_EVENT_PLUGINSTATUS 3 // 0-enabled; 1-dis.temporary; 2-dis.permanent
+#define WAT_EVENT_NEWPLAYER 4 //
+#define WAT_EVENT_NEWTEMPLATE 5 // TM_* constant
+
+/*
+ Plugin or player status changed:
+ wParam: type of event (see above)
+ lParam: value
+*/
+#define ME_WAT_NEWSTATUS "WATrack/NewStatus"
+
+// ---------- Popup module ------------
+
+/*
+ wParam: not used
+ lParam: not used
+ Affects: Show popup or Info window with current music information
+ note: Only Info window will be showed if Popup plugin disabled
+*/
+
+#define MS_WAT_SHOWMUSICINFO "WATrack/ShowMusicInfo"
+
+// --------- Statistic (report) module -------------
+
+/*
+ wParam: pointer to log file name or NULL
+ lParam: pointer to report file name or NULL
+ Affects: Create report from log and run it (if option is set)
+ returns: 0 if unsuccesful
+ note: if wParam or lParam is a NULL then file names from options are used
+*/
+#define MS_WAT_MAKEREPORT "WATrack/MakeReport"
+
+/*
+ wParam, lParam - not used
+ Affects: pack statistic file
+*/
+#define MS_WAT_PACKLOG = "WATrack/PackLog"
+
+/*
+ wParam: not used
+ lParam: pointer to SongInfo
+*/
+#define MS_WAT_ADDTOLOG = "WATrack/AddToLog"
+
+// ----------- Formats and players -----------
+
+// media file status
+
+#define WAT_MES_STOPPED 0
+#define WAT_MES_PLAYING 1
+#define WAT_MES_PAUSED 2
+#define WAT_MES_UNKNOWN -1
+
+#define WAT_ACT_REGISTER 1
+#define WAT_ACT_UNREGISTER 2
+#define WAT_ACT_DISABLE 3
+#define WAT_ACT_ENABLE 4
+#define WAT_ACT_GETSTATUS 5 // not found/enabled/disabled
+#define WAT_ACT_SETACTIVE 6
+#define WAT_ACT_REPLACE 0x10000 // can be combined with WAT_REGISTERFORMAT
+
+ // flags
+#define WAT_OPT_DISABLED 0x0001 // format registered but disabled
+#define WAT_OPT_ONLYONE 0x0002 // format can't be overwriten
+#define WAT_OPT_PLAYERINFO 0x0004 // song info from player
+#define WAT_OPT_WINAMPAPI 0x0008 // Winamp API support
+#define WAT_OPT_CHECKTIME 0x0010 // check file time for changes
+#define WAT_OPT_VIDEO 0x0020 // only for format registering used
+#define WAT_OPT_LAST 0x0040 // (internal)
+#define WAT_OPT_FIRS 0x0080 // (internal)
+#define WAT_OPT_TEMPLATE 0x0100 // (internal)
+#define WAT_OPT_IMPLANTANT 0x0200 // use process implantation
+#define WAT_OPT_HASURL 0x0400 // (player registration) URL field present
+#define WAT_OPT_CHANGES 0x0800 // obtain only chaged values
+ // (volume, status, window text, elapsed time)
+#define WAT_OPT_MULTITHREAD 0x8000 // Use multithread scan
+#define WAT_OPT_KEEPOLD 0x4000 // Keep Old opened file
+
+
+typedef BOOL (__cdecl *LPREADFORMATPROC)(LPSONGINFO Info);
+
+typedef struct tMusicFormat {
+ LPREADFORMATPROC proc;
+ CHAR ext[8];
+ int flags;
+} MUSICFORMAT, *LPMUSICFORMAT;
+
+/*
+ wParam: action
+ lParam: pointer to MUSICFORMAT if wParam = WAT_ACT_REGISTER,
+ else - pointer to extension string (ANSI)
+ returns: see result codes
+*/
+
+#define MS_WAT_FORMAT "WATrack/Format"
+
+/*
+ wParam - pointer to SONGINFO structure (plwind field must be initialized)
+ lParam - flags
+*/
+
+#define MS_WAT_WINAMPINFO "WATrack/WinampInfo"
+
+/*
+ wParam: window
+ lParam: LoWord - command; HiWord - value
+*/
+
+#define MS_WAT_WINAMPCOMMAND "WATrack/WinampCommand"
+
+typedef WCHAR (__cdecl *LPNAMEPROC)();
+typedef HWND (__cdecl *LPCHECKPROC)(int flags);
+typedef int (__cdecl *LPINFOPROC)(LPSONGINFO Info, int flags);
+typedef int (__cdecl *LPCOMMANDPROC)(int command, int value);
+
+typedef struct tPlayerCell {
+ CHAR *Desc;
+ int flags;
+ HICON Icon; // can be 0. for registration only
+ LPCHECKPROC Check; // check player
+ LPNAMEPROC GetName; // can be NULL. get media filename
+ LPINFOPROC GetInfo; // can be NULL. get info from player
+ LPCOMMANDPROC Command; // can be NULL. send command to player
+ CHAR *URL; // only if WAT_OPT_HASURL flag present
+} PLAYERCELL, *LPPLAYERCELL;
+
+/*
+ wParam: action
+ lParam: pointer to PLAYERCELL if wParam = WAT_ACT_REGISTER,
+ else - pointer to player description string (ANSI)
+ returns: player window handle or value>0 if found
+*/
+
+#define MS_WAT_PLAYER "WATrack/Player"
+
+// --------- Templates ----------
+
+//templates
+#define TM_MESSAGE 0 // privat message
+#define TM_CHANNEL 1 // chat
+#define TM_STAT_TITLE 2 // xstatus title
+#define TM_STAT_TEXT 3 // [x]status text
+#define TM_POPTITLE 4 // popup title
+#define TM_POPTEXT 5 // popup text
+#define TM_EXPORT 6 // other app
+#define TM_FRAMEINFO 7 // frame
+
+#define TM_SETTEXT 0x100 // only for service
+#define TM_GETTEXT 0 // only for service
+
+/*
+ wParam: not used
+ lParam: Unicode template
+ returns: New Unicode (replaced) string
+*/
+#define MS_WAT_REPLACETEXT "WATrack/ReplaceText"
+
+/*
+ event types for History
+ Blob structure for EVENTTYPE_WAT_ANSWER:
+ Uniciode artist#0title#0album#0answer
+*/
+#define EVENTTYPE_WAT_REQUEST 9601
+#define EVENTTYPE_WAT_ANSWER 9602
+#define EVENTTYPE_WAT_ERROR 9603
+#define EVENTTYPE_WAT_MESSAGE 9604
+
+/*
+ wParam: Template type (TM_* constants).
+ lParam: Template string for template setup, or not used
+ returns: pointer to statically allocated string (DON'T free!)
+ note: Template set if wParam with TM_SETTEXT combined. If used for
+ Protocol-dependent templates, used only for default templates.
+*/
+#define MS_WAT_TEMPLATE = "WATrack/Templates"
+
+#endif
diff --git a/Plugins/listeningto/sdk/m_proto_listeningto.h b/Plugins/listeningto/sdk/m_proto_listeningto.h
new file mode 100644
index 0000000..66d3b77
--- /dev/null
+++ b/Plugins/listeningto/sdk/m_proto_listeningto.h
@@ -0,0 +1,143 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+//this module was created in v0.6.0.0
+
+#ifndef M_PROTO_LISTENINGTO_H__
+#define M_PROTO_LISTENINGTO_H__ 1
+
+
+// Protocol Services /////////////////////////////////////////////////////////////////
+
+// This is the services a protocol have to support to support listening info
+
+typedef struct {
+ int cbSize;
+
+ union {
+ char* pszType; // Media type: Music, Video, etc...
+ TCHAR* ptszType;
+ };
+ union {
+ char* pszArtist; // Artist name
+ TCHAR* ptszArtist;
+ };
+ union {
+ char* pszAlbum; // Album name
+ TCHAR* ptszAlbum;
+ };
+ union {
+ char* pszTitle; // Song name
+ TCHAR* ptszTitle;
+ };
+ union {
+ char* pszTrack; // Track number
+ TCHAR* ptszTrack;
+ };
+ union {
+ char* pszYear; // Song year
+ TCHAR* ptszYear;
+ };
+ union {
+ char* pszGenre; // Song genre
+ TCHAR* ptszGenre;
+ };
+ union {
+ char* pszLength; // Song length
+ TCHAR* ptszLength;
+ };
+ union {
+ char* pszPlayer; // Player name
+ TCHAR* ptszPlayer;
+ };
+
+ DWORD dwFlags;
+
+} LISTENINGTOINFO;
+
+#define LTI_UNICODE 1
+
+#ifdef UNICODE
+ #define LTI_TCHAR LTI_UNICODE
+#else
+ #define LTI_TCHAR 0
+#endif
+
+// Set the listening info for the protocol.
+// Pass NULL to remove it.
+// wParam = NULL
+// lParam = LISTENINGTOINFO *
+#define PS_SET_LISTENINGTO "/SetListeningTo"
+
+// Get the listening info for the protocol
+// wParam = NULL
+// lParam = LISTENINGTOINFO *
+// The strings inside the struct need to be free using miranda free.
+#define PS_GET_LISTENINGTO "/GetListeningTo"
+
+// Also the protocol have to save a string with the text the other user is (probabily)
+// seeing under the main db key: <protocol>/ListeningTo
+
+// For a contact, the protocol should store the listening info as an string inside
+// the contact db key: <protocol>/ListeningTo
+
+
+// ListeningTo configuration plugin //////////////////////////////////////////////////
+
+// One plugin can be used to set some options relative to the listening to information.
+// But protocols should not assume this plugin exists. If it does not exist, protocols
+// have to decide what default to use.
+// This plugin have to support the following services:
+
+// Get the text format the user wants him / his contacts to see. Some strings represents
+// the text information:
+// %artist%, %album%, %title%, %track%, %year%, %genre%, %length%, %player%, %type%
+// This service is optional
+// wParam = TCHAR* - default text for this protocol
+// lParam = 0
+// Returns a TCHAR* containg the user setting. This need to be free using miranda free.
+#define MS_LISTENINGTO_GETTEXTFORMAT "ListeningTo/GetTextFormat"
+
+// Get the text the user wants him / his contacts to see, parsed with the info sent to
+// this service. Uses the same variables as the above service to the default text.
+// wParam = TCHAR* - default text for this protocol
+// lParam = LISTENINGTOINFO *
+// Returns a TCHAR* containg the parsed text. This need to be free using miranda free.
+#define MS_LISTENINGTO_GETPARSEDTEXT "ListeningTo/GetParsedText"
+
+// Get if the contact options about how to show the music info should be overriten or
+// not.
+// wParam = NULL
+// lParam = hContact
+// Returns a BOOL
+#define MS_LISTENINGTO_OVERRIDECONTACTOPTION "ListeningTo/OverrideContactOption"
+
+// Get the text to show if some info of the contact is empty.
+// wParam = NULL
+// lParam = NULL
+// Returns a TCHAR *. Don't free
+#define MS_LISTENINGTO_GETUNKNOWNTEXT "ListeningTo/GetUnknownText"
+
+
+#endif // M_PROTO_LISTENINGTO_H__
+
diff --git a/Plugins/listeningto/sdk/m_toptoolbar.h b/Plugins/listeningto/sdk/m_toptoolbar.h
new file mode 100644
index 0000000..6b1a018
--- /dev/null
+++ b/Plugins/listeningto/sdk/m_toptoolbar.h
@@ -0,0 +1,107 @@
+
+#ifndef M_TOPTOOLBAR_H
+#define M_TOPTOOLBAR_H
+
+//button flags
+#define TTBBF_DISABLED 1
+#define TTBBF_VISIBLE 2
+#define TTBBF_PUSHED 4
+#define TTBBF_SHOWTOOLTIP 8
+#define TTBBF_DRAWBORDER 16//draw border for bitmap,bitmap must be WxH 16x12
+#define TTBBF_ISSEPARATOR 32
+
+//for internal launch buttons
+#define TTBBF_ISLBUTTON 64
+
+typedef struct {
+ int cbSize;
+ HBITMAP hbBitmapUp;
+ HBITMAP hbBitmapDown;
+ char *pszServiceUp;
+ char *pszServiceDown;
+ DWORD dwFlags;
+ LPARAM lParamUp;
+ WPARAM wParamUp;
+ LPARAM lParamDown;
+ WPARAM wParamDown;
+ char *name;
+
+} TTBButton, * lpTTBButton;
+
+//=== EVENTS ===
+/*
+toptoolbar/moduleloaded event
+wParam = lParam = 0
+Called when the toolbar services are available
+
+!!!Warning you may work with TTB services only in this event or later.
+
+*/
+#define ME_TTB_MODULELOADED "TopToolBar/ModuleLoaded"
+
+
+
+//=== SERVICES ===
+/*
+toptoolbar/addbutton service
+wparam = (TTBButton*)lpTTBButton
+lparam = 0
+returns: hTTBButton - handle of added button on success, -1 on failure.
+*/
+#define MS_TTB_ADDBUTTON "TopToolBar/AddButton"
+
+/*
+toptoolbar/removebutton service
+wparam = (HANDLE)hTTButton
+lparam = 0
+returns: 0 on success, -1 on failure.
+*/
+#define MS_TTB_REMOVEBUTTON "TopToolBar/RemoveButton"
+
+/*
+toptoolbar/setstate service
+wparam = (HANDLE)hTTButton
+lparam = (LPARAM) state
+returns: 0 on success, -1 on failure.
+*/
+#define TTBST_PUSHED 1
+#define TTBST_RELEASED 2
+
+#define MS_TTB_SETBUTTONSTATE "TopToolBar/SetState"
+
+/*
+toptoolbar/getstate service
+wparam = (HANDLE)hTTButton
+lparam = 0
+returns: state on success, -1 on failure.
+*/
+#define MS_TTB_GETBUTTONSTATE "TopToolBar/GetState"
+
+/*
+toptoolbar/getoptions service
+(HIWORD)wparam = (HANDLE)hTTButton
+(LOWORD)wparam = TTBO_FLAG
+lparam = 0,or lparam=lpTTBButton if flag=TTBO_ALLDATA
+returns: value on success, -1 on failure.
+*/
+#define TTBO_FLAGS 0 //get/set all flags
+#define TTBO_POS 1 //position
+#define TTBO_WIDTH 2 //not impemented
+#define TTBO_HEIGHT 3 //not impemented
+#define TTBO_TIPNAME 4 //tool tip name
+#define TTBO_ALLDATA 5 //change all data via lparam=lpTTBButton
+
+
+#define MS_TTB_GETBUTTONOPTIONS "TopToolBar/GetOptions"
+
+/*
+toptoolbar/setoptions service
+(HIWORD)wparam = (HANDLE)hTTButton
+(LOWORD)wparam = TTBO_FLAG
+lparam = value
+returns: 1 on success, -1 on failure.
+*/
+#define MS_TTB_SETBUTTONOPTIONS "TopToolBar/SetOptions"
+
+
+#endif \ No newline at end of file
diff --git a/Plugins/listeningto/sdk/m_updater.h b/Plugins/listeningto/sdk/m_updater.h
new file mode 100644
index 0000000..371b743
--- /dev/null
+++ b/Plugins/listeningto/sdk/m_updater.h
@@ -0,0 +1,146 @@
+#ifndef _M_UPDATER_H
+#define _M_UPDATER_H
+
+// NOTES:
+// - For langpack updates, include a string of the following format in the langpack text file:
+// ";FLID: <file listing name> <version>"
+// version must be four numbers seperated by '.', in the range 0-255 inclusive
+// - Updater will disable plugins that are downloaded but were not active prior to the update (this is so that, if an archive contains e.g. ansi and
+// unicode versions, the correct plugin will be the only one active after the new version is installed)...so if you add a support plugin, you may need
+// to install an ini file to make the plugin activate when miranda restarts after the update
+// - Updater will replace all dlls that have the same internal shortName as a downloaded update dll (this is so that msn1.dll and msn2.dll, for example,
+// will both be updated) - so if you have a unicode and a non-unicode version of a plugin in your archive, you should make the internal names different (which will break automatic
+// updates from the file listing if there is only one file listing entry for both versions, unless you use the 'MS_UPDATE_REGISTER' service below)
+// - Updater will install all files in the root of the archive into the plugins folder, except for langpack files that contain the FLID string which go into the root folder (same
+// folder as miranda32.exe)...all folders in the archive will also be copied to miranda's root folder, and their contents transferred into the new folders. The only exception is a
+// special folder called 'root_files' - if there is a folder by that name in the archive, it's contents will also be copied into miranda's root folder - this is intended to be used
+// to install additional dlls etc that a plugin may require)
+
+// if you set Update.szUpdateURL to the following value when registering, as well as setting your beta site and version data,
+// Updater will ignore szVersionURL and pbVersionPrefix, and attempt to find the file listing URL's from the backend XML data.
+// for this to work, the plugin name in pluginInfo.shortName must match the file listing exactly (except for case)
+#define UPDATER_AUTOREGISTER "UpdaterAUTOREGISTER"
+// Updater will also use the backend xml data if you provide URL's that reference the miranda file listing for updates (so you can use that method
+// if e.g. your plugin shortName does not match the file listing) - it will grab the file listing id from the end of these URLs
+
+typedef struct Update_tag {
+ int cbSize;
+ char *szComponentName; // component name as it will appear in the UI (will be translated before displaying)
+
+ char *szVersionURL; // URL where the current version can be found (NULL to disable)
+ BYTE *pbVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ // (note that this URL could point at a binary file - dunno why, but it could :)
+ int cpbVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szUpdateURL; // URL where dll/zip is located
+ // set to UPDATER_AUTOREGISTER if you want Updater to find the file listing URLs (ensure plugin shortName matches file listing!)
+
+ char *szBetaVersionURL; // URL where the beta version can be found (NULL to disable betas)
+ BYTE *pbBetaVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ int cpbBetaVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szBetaUpdateURL; // URL where dll/zip is located
+
+ BYTE *pbVersion; // bytes of current version, used for comparison with those in VersionURL
+ int cpbVersion; // number of bytes pointed to by pbVersion
+
+ char *szBetaChangelogURL; // url for displaying changelog for beta versions
+} Update;
+
+// register a comonent with Updater
+//
+// wparam = 0
+// lparam = (LPARAM)&Update
+#define MS_UPDATE_REGISTER "Update/Register"
+
+// utility functions to create a version string from a DWORD or from pluginInfo
+// point buf at a buffer at least 16 chars wide - but note the version string returned may be shorter
+//
+__inline static char *CreateVersionString(DWORD version, char *buf) {
+ mir_snprintf(buf, 16, "%d.%d.%d.%d", (version >> 24) & 0xFF, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);
+ return buf;
+}
+
+__inline static char *CreateVersionStringPlugin(PLUGININFO *pluginInfo, char *buf) {
+ return CreateVersionString(pluginInfo->version, buf);
+}
+
+
+// register the 'easy' way - use this method if you have no beta URL and the plugin is on the miranda file listing
+// NOTE: the plugin version string on the file listing must be the string version of the version in pluginInfo (i.e. 0.0.0.1,
+// four numbers between 0 and 255 inclusivem, so no letters, brackets, etc.)
+//
+// wParam = (int)fileID - this is the file ID from the file listing (i.e. the number at the end of the download link)
+// lParam = (PLUGININFO*)&pluginInfo
+#define MS_UPDATE_REGISTERFL "Update/RegisterFL"
+
+// this function can be used to 'unregister' components - useful for plugins that register non-plugin/langpack components and
+// may need to change those components on the fly
+// lParam = (char *)szComponentName
+#define MS_UPDATE_UNREGISTER "Update/Unregister"
+
+// this event is fired when the startup process is complete, but NOT if a restart is imminent
+// it is designed for status managment plugins to use as a trigger for beggining their own startup process
+// wParam = lParam = 0 (unused)
+// (added in version 0.1.6.0)
+#define ME_UPDATE_STARTUPDONE "Update/StartupDone"
+
+// this service can be used to enable/disable Updater's global status control
+// it can be called from the StartupDone event handler
+// wParam = (BOOL)enable
+// lParam = 0
+// (added in version 0.1.6.0)
+#define MS_UPDATE_ENABLESTATUSCONTROL "Update/EnableStatusControl"
+
+// An description of usage of the above service and event:
+// Say you are a status control plugin that normally sets protocol or global statuses in your ModulesLoaded event handler.
+// In order to make yourself 'Updater compatible', you would move the status control code from ModulesLoaded to another function,
+// say DoStartup. Then, in ModulesLoaded you would check for the existence of the MS_UPDATE_ENABLESTATUSCONTROL service.
+// If it does not exist, call DoStartup. If it does exist, hook the ME_UPDATE_STARTUPDONE event and call DoStartup from there. You may
+// also wish to call MS_UPDATE_ENABLESTATUSCONTROL with wParam == FALSE at this time, to disable Updater's own status control feature.
+
+// this service can be used to determine whether updates are possible for a component with the given name
+// wParam = 0
+// lParam = (char *)szComponentName
+// returns TRUE if updates are supported, FALSE otherwise
+#define MS_UPDATE_ISUPDATESUPPORTED "Update/IsUpdateSupported"
+
+#endif
+
+
+/////////////// Usage Example ///////////////
+
+#ifdef EXAMPLE_CODE
+
+// you need to #include "m_updater.h" and HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded) in your Load function...
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam) {
+
+ Update update = {0}; // for c you'd use memset or ZeroMemory...
+ char szVersion[16];
+
+ update.cbSize = sizeof(Update);
+
+ update.szComponentName = pluginInfo.shortName;
+ update.pbVersion = (BYTE *)CreateVersionString(&pluginInfo, szVersion);
+ update.cpbVersion = strlen((char *)update.pbVersion);
+
+ // these are the three lines that matter - the archive, the page containing the version string, and the text (or data)
+ // before the version that we use to locate it on the page
+ // (note that if the update URL and the version URL point to standard file listing entries, the backend xml
+ // data will be used to check for updates rather than the actual web page - this is not true for beta urls)
+ update.szUpdateURL = "http://scottellis.com.au:81/test/updater.zip";
+ update.szVersionURL = "http://scottellis.com.au:81/test/updater_test.html";
+ update.pbVersionPrefix = (BYTE *)"Updater version ";
+
+ update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix);
+
+ // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+
+ // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing...
+ // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo);
+
+ return 0;
+}
+
+#endif
diff --git a/Plugins/listeningto/sdk/m_variables.h b/Plugins/listeningto/sdk/m_variables.h
new file mode 100644
index 0000000..3f13c96
--- /dev/null
+++ b/Plugins/listeningto/sdk/m_variables.h
@@ -0,0 +1,718 @@
+/*
+ Variables Plugin for Miranda-IM (www.miranda-im.org)
+ Copyright 2003-2006 P. Boon
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __M_VARS
+#define __M_VARS
+
+#if !defined(_TCHAR_DEFINED)
+#include <tchar.h>
+#endif
+
+#ifndef VARIABLES_NOHELPER
+#include <m_button.h>
+#endif
+
+// --------------------------------------------------------------------------
+// Memory management
+// --------------------------------------------------------------------------
+
+// Release memory that was allocated by the Variables plugin, e.g. returned
+// strings.
+
+#define MS_VARS_FREEMEMORY "Vars/FreeMemory"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(void *)pntr
+// Pointer to memory that was allocated by the Variables plugin (e.g. a
+// returned string) (can be NULL).
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Does return 0 on success, nozero otherwise.
+
+// Note: Do only use this service to free memory that was *explicitliy*
+// stated that it should be free with this service.
+
+
+
+#define MS_VARS_GET_MMI "Vars/GetMMI"
+
+// Get Variable's RTL/CRT function poiners to malloc(), free() and
+// realloc().
+
+// Parameters:
+// ------------------------
+// wParam = 0
+// lParam = (LPARAM) &MM_INTERFACE
+// Pointer to a memory manager interface struct (see m_system.h).
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nozero otherwise
+
+// Note: Works exactly the same as the MS_SYSTEM_GET_MMI service
+// service of m_system.h.
+
+// Helper function for easy using:
+#ifndef VARIABLES_NOHELPER
+__inline static void variables_free(void *pntr) {
+
+ CallService(MS_VARS_FREEMEMORY, (WPARAM)pntr, 0);
+}
+#endif
+
+
+
+// --------------------------------------------------------------------------
+// String formatting
+// --------------------------------------------------------------------------
+
+#define MS_VARS_FORMATSTRING "Vars/FormatString"
+
+// This service can be used to parse tokens in a text. The tokens will be
+// replaced by their resolved values. A token can either be a field or a
+// function. A field takes no arguments and is represented between
+// %-characters, e.g. "%winampsong%". A function can take any number of
+// arguments and is represented by a ? or !-character followed by the name
+// of the function and a list of arguments, e.g. "?add(1,2)".
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(FORMATINFO *)&fi
+// See below.
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Returns a pointer to the resolved string or NULL in case of an error.
+
+// Note: The returned pointer needs to be freed using MS_VARS_FREEMEMORY.
+
+typedef struct {
+ int cbSize; // Set this to sizeof(FORMATINFO).
+ int flags; // Flags to use (see FIF_* below).
+ union {
+ char *szFormat; // Text in which the tokens will be replaced (can't be
+ // NULL).
+ WCHAR *wszFormat;
+ TCHAR *tszFormat;
+ };
+ union {
+ char *szExtraText; // Extra, context-specific string (can be NULL) ->
+ // The field "extratext" will be replaced by this
+ // string. (Previously szSource).
+ WCHAR *wszExtraText;
+ TCHAR *tszExtraText;
+ };
+ HANDLE hContact; // Handle to contact (can be NULL) -> The field "subject"
+ // represents this contact.
+ int pCount; // (output) Number of succesful parsed tokens, needs to be set
+ // to 0 before the call
+ int eCount; // (output) Number of failed tokens, needs to be set to 0
+ // before the call
+ union {
+ char **szaTemporaryVars; // Temporary variables valid only in the duration of the format call
+ TCHAR **tszaTemporaryVars; // By pos: [i] is var name, [i + 1] is var value
+ WCHAR **wszaTemporaryVars;
+ };
+ int cbTemporaryVarsSize; // Number of elements in szaTemporaryVars array
+
+} FORMATINFO;
+
+#define FORMATINFOV2_SIZE 28
+
+// Possible flags:
+#define FIF_UNICODE 0x01 // Expects and returns unicode text (WCHAR*).
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define FIF_TCHAR FIF_UNICODE // Strings in structure are TCHAR*.
+#else
+#define FIF_TCHAR 0
+#endif
+
+// Helper functions for easy using:
+
+// Helper #1: variables_parse
+// ------------------------
+// The returned string needs to be freed using MS_VARS_FREEMEMORY.
+
+#ifndef VARIABLES_NOHELPER
+__inline static TCHAR *variables_parse(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact) {
+
+ FORMATINFO fi;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags = FIF_TCHAR;
+
+ return (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+}
+#endif
+
+__inline static TCHAR *variables_parse_ex(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact,
+ TCHAR **tszaTemporaryVars, int cbTemporaryVarsSize) {
+
+ FORMATINFO fi;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags = FIF_TCHAR;
+ fi.tszaTemporaryVars = tszaTemporaryVars;
+ fi.cbTemporaryVarsSize = cbTemporaryVarsSize;
+
+ return (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+}
+// Helper #2: variables_parsedup
+// ------------------------
+// Returns a _strdup()'ed copy of the unparsed string when Variables is not
+// installed, returns a strdup()'ed copy of the parsed result otherwise.
+
+// Note: The returned pointer needs to be released using your own free().
+
+#ifndef VARIABLES_NOHELPER
+__inline static TCHAR *variables_parsedup(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact) {
+
+ if (ServiceExists(MS_VARS_FORMATSTRING)) {
+ FORMATINFO fi;
+ TCHAR *tszParsed, *tszResult;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags |= FIF_TCHAR;
+ tszParsed = (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+ if (tszParsed) {
+ tszResult = _tcsdup(tszParsed);
+ CallService(MS_VARS_FREEMEMORY, (WPARAM)tszParsed, 0);
+ return tszResult;
+ }
+ }
+ return tszFormat?_tcsdup(tszFormat):tszFormat;
+}
+
+__inline static TCHAR *variables_parsedup_ex(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact,
+ TCHAR **tszaTemporaryVars, int cbTemporaryVarsSize) {
+
+ if (ServiceExists(MS_VARS_FORMATSTRING)) {
+ FORMATINFO fi;
+ TCHAR *tszParsed, *tszResult;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags |= FIF_TCHAR;
+ fi.tszaTemporaryVars = tszaTemporaryVars;
+ fi.cbTemporaryVarsSize = cbTemporaryVarsSize;
+ tszParsed = (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+ if (tszParsed) {
+ tszResult = _tcsdup(tszParsed);
+ CallService(MS_VARS_FREEMEMORY, (WPARAM)tszParsed, 0);
+ return tszResult;
+ }
+ }
+ return tszFormat?_tcsdup(tszFormat):tszFormat;
+}
+#endif
+
+
+
+// --------------------------------------------------------------------------
+// Register tokens
+// --------------------------------------------------------------------------
+
+// Plugins can define tokens which will be parsed by the Variables plugin.
+
+#define MS_VARS_REGISTERTOKEN "Vars/RegisterToken"
+
+// With this service you can define your own token. The newly added tokens
+// using this service are taken into account on every call to
+// MS_VARS_FORMATSTRING.
+
+// Parameters:
+// ------------------------
+// wParam = 0
+// lParam = (LPARAM)(TOKENREGISTER*)&tr
+// See below.
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nonzero otherwise. Existing tokens will be
+// 'overwritten' if registered twice.
+
+// Needed for szService and parseFunction:
+typedef struct {
+ int cbSize; // You need to check if this is >=sizeof(ARGUMENTSINFO)
+ // (already filled in).
+ FORMATINFO *fi; // Arguments passed to MS_VARS_FORMATSTRING.
+ unsigned int argc; // Number of elements in the argv array.
+ union {
+ char **argv; // Argv[0] will be the token name, the following elements
+ // are the additional arguments.
+ WCHAR **wargv; // If the registered token was registered as a unicode
+ // token, wargv should be accessed.
+ TCHAR **targv;
+ };
+ int flags; // (output) You can set flags here (initially 0), use the
+ // AIF_* flags (see below).
+} ARGUMENTSINFO;
+
+// Available flags for ARGUMENTSINFO:
+// Set the flags of the ARGUMENTSINFO struct to any of these to influence
+// further parsing.
+#define AIF_DONTPARSE 0x01 // Don't parse the result of this function,
+ // usually the result of a token is parsed
+ // again, if the `?` is used as a function
+ // character.
+#define AIF_FALSE 0x02 // The function returned logical false.
+
+// Definition of parse/cleanup functions:
+typedef char* (*VARPARSEFUNCA)(ARGUMENTSINFO *ai);
+typedef WCHAR* (*VARPARSEFUNCW)(ARGUMENTSINFO *ai);
+typedef void (*VARCLEANUPFUNCA)(char *szReturn);
+typedef void (*VARCLEANUPFUNCW)(WCHAR *wszReturn);
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define VARPARSEFUNC VARPARSEFUNCW
+#define VARCLEANUPFUNC VARCLEANUPFUNCW
+#else
+#define VARPARSEFUNC VARPARSEFUNCA
+#define VARCLEANUPFUNC VARCLEANUPFUNCA
+#endif
+
+typedef struct {
+ int cbSize; // Set this to sizeof(TOKENREGISTER).
+ union {
+ char *szTokenString; // Name of the new token to be created, without %,
+ // ?, ! etc. signs (can't be NULL).
+ WCHAR *wszTokenString;
+ TCHAR *tszTokenString;
+ };
+ union {
+ char *szService; // Name of a service that is used to request the
+ // token's value, if no service is used, a function
+ // and TRF_PARSEFUNC must be used.
+ VARPARSEFUNCA parseFunction; // See above, use with TRF_PARSEFUNC.
+ VARPARSEFUNCW parseFunctionW;
+ VARPARSEFUNC parseFunctionT;
+ };
+ union {
+ char *szCleanupService; // Name of a service to be called when the
+ // memory allocated in szService can be freed
+ // (only used when flag VRF_CLEANUP is set,
+ // else set this to NULL).
+ VARCLEANUPFUNCA cleanupFunction; // See above, use with TRF_CLEANUPFUNC.
+ VARCLEANUPFUNCW cleanupFunctionW;
+ VARCLEANUPFUNC cleanupFunctionT;
+ };
+ char *szHelpText; // Help info shown in help dialog (can be NULL). Has to
+ // be in the following format:
+ // "subject\targuments\tdescription"
+ // (Example: "math\t(x, y ,...)\tx + y + ..."), or:
+ // "subject\tdescription"
+ // (Example: "miranda\tPath to the Miranda-IM
+ // executable").
+ // Note: subject and description are translated by
+ // Variables.
+ int memType; // Describes which method Varibale's plugin needs to use to
+ // free the returned buffer, use one of the VR_MEM_* values
+ // (see below). Only valid if the flag VRF_FREEMEM is set,
+ // use TR_MEM_OWNER otherwise).
+ int flags; // Flags to use (see below), one of TRF_* (see below).
+} TOKENREGISTER;
+
+// Available Memory Storage Types:
+// These values describe which method Variables Plugin will use to free the
+// buffer returned by the parse function or service
+#define TR_MEM_VARIABLES 1 // Memory is allocated using the functions
+ // retrieved by MS_VARS_GET_MMI.
+#define TR_MEM_MIRANDA 2 // Memory is allocated using Miranda's Memory
+ // Manager Interface (using the functions
+ // returned by MS_SYSTEM_GET_MMI), if
+ // VRF_FREEMEM is set, the memory will be
+ // freed by Variables.
+#define TR_MEM_OWNER 3 // Memory is owned by the calling plugin
+ // (can't be freed by Variables Plugin
+ // automatically). This should be used if
+ // VRF_FREEMEM is not specified in the flags.
+
+// Available Flags for TOKENREGISTER:
+#define TRF_FREEMEM 0x01 // Variables Plugin will automatically free the
+ // pointer returned by the parse function or
+ // service (which method it will us is
+ // specified in memType -> see above).
+#define TRF_CLEANUP 0x02 // Call cleanup service or function, notifying
+ // that the returned buffer can be freed.
+ // Normally you should use either TRF_FREEMEM
+ // or TRF_CLEANUP.
+#define TRF_PARSEFUNC 0x40 // parseFunction will be used instead of a
+ // service.
+#define TRF_CLEANUPFUNC 0x80 // cleanupFunction will be used instead of a
+ // service.
+#define TRF_USEFUNCS TRF_PARSEFUNC|TRF_CLEANUPFUNC
+#define TRF_UNPARSEDARGS 0x04 // Provide the arguments for the parse
+ // function in their raw (unparsed) form.
+ // By default, arguments are parsed before
+ // presenting them to the parse function.
+#define TRF_FIELD 0x08 // The token can be used as a %field%.
+#define TRF_FUNCTION 0x10 // The token can be used as a ?function().
+ // Normally you should use either TRF_FIELD or
+ // TRF_FUNCTION.
+#define TRF_UNICODE 0x20 // Strings in structure are unicode (WCHAR*).
+ // In this case, the strings pointing to the
+ // arguments in the ARGUMENTS struct are
+ // unicode also. The returned buffer is
+ // expected to be unicode also, and the
+ // unicode parse and cleanup functions are
+ // called.
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define TRF_TCHAR TRF_UNICODE // Strings in structure are TCHAR*.
+#else
+#define TRF_TCHAR 0
+#endif
+
+// Deprecated:
+#define TRF_CALLSVC TRF_CLEANUP
+
+// Callback Service (szService) / parseFunction:
+// ------------------------
+// Service that is called automatically by the Variable's Plugin to resolve a
+// registered variable.
+
+// Parameters:
+// wParam = 0
+// lParam = (LPARAM)(ARGUMENTSINFO *)&ai
+// see above
+
+// Return Value:
+// Needs to return the pointer to a dynamically allocacated string or NULL.
+// A return value of NULL is regarded as an error (eCount will be increaded).
+// Flags in the ARGUMENTSINFO struct can be set (see above).
+
+// Callback Service (szCallbackService) / cleanupFunction:
+// ------------------------
+// This service is called when the memory that was allocated by the parse
+// function or service can be freed. Note: It will only be called when the
+// flag VRF_CLEANUP of TOKENREGISTER is set.
+
+// Parameters:
+// wParam = 0
+// lParam = (LPARAM)(char *)&res
+// Result from parse function or service (pointer to a string).
+
+// Return Value:
+// Should return 0 on success.
+
+
+
+// --------------------------------------------------------------------------
+// Show the help dialog
+// --------------------------------------------------------------------------
+
+// Plugins can invoke Variables' help dialog which can be used for easy input
+// by users.
+
+#define MS_VARS_SHOWHELPEX "Vars/ShowHelpEx"
+
+// This service can be used to open the help dialog of Variables. This dialog
+// provides easy input for the user and/or information about the available
+// tokens.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(HWND)hwndParent
+// lParam = (LPARAM)(VARHELPINFO)&vhi
+// See below.
+
+// Return Value:
+// ------------------------
+// Returns 0 on succes, any other value on error.
+
+typedef struct {
+ int cbSize; // Set to sizeof(VARHELPINFO).
+ FORMATINFO *fi; // Used for both input and output. If this pointer is not
+ // NULL, the information is used as the initial values for
+ // the dialog.
+ HWND hwndCtrl; // Used for both input and output. The window text of this
+ // window will be read and used as the initial input of the
+ // input dialog. If the user presses the OK button the window
+ // text of this window will be set to the text of the input
+ // field and a EN_CHANGE message via WM_COMMAND is send to
+ // this window. (Can be NULL).
+ char *szSubjectDesc; // The description of the %subject% token will be set
+ // to this text, if not NULL. This is translated
+ // automatically.
+ char *szExtraTextDesc; // The description of the %extratext% token will be
+ // set to this text, if not NULL. This is translated
+ // automatically.
+ int flags; // Flags, see below.
+} VARHELPINFO;
+
+
+// Flags for VARHELPINFO
+#define VHF_TOKENS 0x00000001 // Create a dialog with the list of
+ // tokens
+#define VHF_INPUT 0x00000002 // Create a dialog with an input
+ // field (this contains the list of
+ // tokens as well).
+#define VHF_SUBJECT 0x00000004 // Create a dialog to select a
+ // contact for the %subject% token.
+#define VHF_EXTRATEXT 0x00000008 // Create a dialog to enter a text
+ // for the %extratext% token.
+#define VHF_HELP 0x00000010 // Create a dialog with help info.
+#define VHF_HIDESUBJECTTOKEN 0x00000020 // Hide the %subject% token in the
+ // list of tokens.
+#define VHF_HIDEEXTRATEXTTOKEN 0x00000040 // Hide the %extratext% token in
+ // the list of tokens.
+#define VHF_DONTFILLSTRUCT 0x00000080 // Don't fill the struct with the
+ // new information if OK is pressed
+#define VHF_FULLFILLSTRUCT 0x00000100 // Fill all members of the struct
+ // when OK is pressed. By default
+ // only szFormat is set. With this
+ // flag on, hContact and
+ // szExtraText are also set.
+#define VHF_SETLASTSUBJECT 0x00000200 // Set the last contact that was
+ // used in the %subject% dialog in
+ // case fi.hContact is NULL.
+
+// Predefined flags
+#define VHF_FULLDLG VHF_INPUT|VHF_SUBJECT|VHF_EXTRATEXT|VHF_HELP
+#define VHF_SIMPLEDLG VHF_INPUT|VHF_HELP
+#define VHF_NOINPUTDLG VHF_TOKENS|VHF_HELP
+
+// If the service fills information in the struct for szFormat or szExtraText,
+// these members must be free'd using the free function of Variables.
+// If wParam==NULL, the dialog is created modeless. Only one dialog can be
+// shown at the time.
+// If both hwndCtrl and fi are NULL, the user input will not be retrievable.
+// In this case, the dialog is created with only a "Close" button, instead of
+// the "OK" and "Cancel" buttons.
+// In case of modeless dialog and fi != NULL, please make sure this pointer
+// stays valid while the dialog is open.
+
+// Helper function for easy use in standard case:
+#ifndef VARIABLES_NOHELPER
+__inline static int variables_showhelp(HWND hwndDlg, UINT uIDEdit, int flags, char *szSubjectDesc, char *szExtraDesc) {
+
+ VARHELPINFO vhi;
+
+ ZeroMemory(&vhi, sizeof(VARHELPINFO));
+ vhi.cbSize = sizeof(VARHELPINFO);
+ if (flags == 0) {
+ flags = VHF_SIMPLEDLG;
+ }
+ vhi.flags = flags;
+ vhi.hwndCtrl = GetDlgItem(hwndDlg, uIDEdit);
+ vhi.szSubjectDesc = szSubjectDesc;
+ vhi.szExtraTextDesc = szExtraDesc;
+
+ return CallService(MS_VARS_SHOWHELPEX, (WPARAM)hwndDlg, (LPARAM)&vhi);
+}
+#endif
+
+
+#define MS_VARS_GETSKINITEM "Vars/GetSkinItem"
+
+// This service can be used to get the icon you can use for example on the
+// Variables help button in your options screen. You can also get the tooltip
+// text to use with such a button. If icon library is available the icon will
+// be retrieved from icon library manager, otherwise the default is returned.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)0
+// lParam = (LPARAM)VSI_* (see below)
+
+// Return Value:
+// ------------------------
+// Depends on the information to retrieve (see below).
+
+// VSI_ constants
+#define VSI_HELPICON 1 // Can be used on the button accessing the
+ // Variables help dialog. Returns (HICON)hIcon on
+ // success or NULL on failure;
+#define VSI_HELPTIPTEXT 2 // Returns the tooltip text you can use for the
+ // help button. Returns (char *)szTipText, a
+ // static, translated buffer containing the help
+ // text or NULL on error.
+
+// Helper to set the icon on a button accessing the help dialog.
+// Preferably a 16x14 MButtonClass control, but it works on a standard
+// button control as well. If no icon is availble (because of old version of
+// Variables) the string "V" is shown on the button. If Variables is not
+// available, the button will be hidden.
+#ifndef VARIABLES_NOHELPER
+__inline static int variables_skin_helpbutton(HWND hwndDlg, UINT uIDButton) {
+
+ int res;
+ HICON hIcon;
+ TCHAR tszClass[32];
+
+ hIcon = NULL;
+ res = 0;
+ if (ServiceExists(MS_VARS_GETSKINITEM)) {
+ hIcon = (HICON)CallService(MS_VARS_GETSKINITEM, 0, (LPARAM)VSI_HELPICON);
+ }
+ GetClassName(GetDlgItem(hwndDlg, uIDButton), tszClass, sizeof(tszClass));
+ if (!_tcscmp(tszClass, _T("Button"))) {
+ if (hIcon != NULL) {
+ SetWindowLong(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE, GetWindowLong(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE)|BS_ICON);
+ SendMessage(GetDlgItem(hwndDlg, uIDButton), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hIcon);
+ }
+ else {
+ SetWindowLong(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE, GetWindowLong(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE)&~BS_ICON);
+ SetDlgItemText(hwndDlg, uIDButton, _T("V"));
+ }
+ }
+ else if (!_tcscmp(tszClass, MIRANDABUTTONCLASS)) {
+ if (hIcon != NULL) {
+ char *szTipInfo;
+
+ SendMessage(GetDlgItem(hwndDlg, uIDButton), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hIcon);
+ if (ServiceExists(MS_VARS_GETSKINITEM)) {
+ szTipInfo = (char *)CallService(MS_VARS_GETSKINITEM, 0, (LPARAM)VSI_HELPTIPTEXT);
+ }
+ if (szTipInfo == NULL) {
+ szTipInfo = Translate("Open String Formatting Help");
+ }
+ SendMessage(GetDlgItem(hwndDlg, uIDButton), BUTTONADDTOOLTIP, (WPARAM)szTipInfo, 0);
+ SendDlgItemMessage(hwndDlg, uIDButton, BUTTONSETASFLATBTN, 0, 0);
+ }
+ else {
+ SetDlgItemText(hwndDlg, uIDButton, _T("V"));
+ }
+ }
+ else {
+ res = -1;
+ }
+ ShowWindow(GetDlgItem(hwndDlg, uIDButton), ServiceExists(MS_VARS_FORMATSTRING));
+
+ return res;
+}
+#endif
+
+
+#define MS_VARS_SHOWHELP "Vars/ShowHelp"
+
+// WARNING: This service is obsolete, please use MS_VARS_SHOWHELPEX
+
+// Shows a help dialog where all possible tokens are displayed. The tokens
+// are explained on the dialog, too. The user can edit the initial string and
+// insert as many tokens as he likes.
+
+// Parameters:
+// ------------------------
+// wParam = (HWND)hwndEdit
+// Handle to an edit control in which the modified string
+// should be inserted (When the user clicks OK in the dialog the edited
+// string will be set to hwndEdit) (can be NULL).
+// lParam = (char *)pszInitialString
+// String that the user is provided with initially when
+// the dialog gets opened (If this is NULL then the current text in the
+// hwndEdit edit control will be used) (can be NULL).
+
+// Return Value:
+// ------------------------
+// Returns the handle to the help dialog (HWND).
+
+// Note: Only one help dialog can be opened at a time. When the dialog gets
+// closed an EN_CHANGE of the edit controll will be triggered because the
+// contents were updated. (Only when user selected OK).
+
+// Example:
+// CallService(MS_VARS_SHOWHELP, (WPARAM)hwndEdit, (LPARAM)"some initial text");
+
+// --------------------------------------------------------------------------
+// Retrieve a contact's HANDLE given a string
+// --------------------------------------------------------------------------
+
+#define MS_VARS_GETCONTACTFROMSTRING "Vars/GetContactFromString"
+
+// Searching for contacts in the database. You can find contacts in db by
+// searching for their name, e.g first name.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(CONTACTSINFO *)&ci
+// See below.
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Returns number of contacts found matching the given string representation.
+// The hContacts array of CONTACTSINFO struct contains these hContacts after
+// the call.
+
+// Note: The hContacts array needs to be freed after use using
+// MS_VARS_FREEMEMORY.
+
+typedef struct {
+ int cbSize; // Set this to sizeof(CONTACTSINFO).
+ union {
+ char *szContact; // String to search for, e.g. last name (can't be NULL).
+ WCHAR *wszContact;
+ TCHAR *tszContact;
+ };
+ HANDLE *hContacts; // (output) Array of contacts found.
+ DWORD flags; // Contact details that will be matched with the search
+ // string (flags can be combined).
+} CONTACTSINFO;
+
+// Possible flags:
+#define CI_PROTOID 0x00000001 // The contact in the string is encoded
+ // in the format <PROTOID:UNIQUEID>, e.g.
+ // <ICQ:12345678>.
+#define CI_NICK 0x00000002 // Search nick names.
+#define CI_LISTNAME 0x00000004 // Search custom names shown in contact
+ // list.
+#define CI_FIRSTNAME 0x00000008 // Search contact's first names (contact
+ // details).
+#define CI_LASTNAME 0x00000010 // Search contact's last names (contact
+ // details).
+#define CI_EMAIL 0x00000020 // Search contact's email adresses
+ // (contact details).
+#define CI_UNIQUEID 0x00000040 // Search unique ids of the contac, e.g.
+ // UIN.
+#define CI_CNFINFO 0x40000000 // Searches one of the CNF_* flags (set
+ // flags to CI_CNFINFO|CNF_X), only one
+ // CNF_ type possible
+#define CI_UNICODE 0x80000000 // tszContact is a unicode string
+ // (WCHAR*).
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define CI_TCHAR CI_UNICODE // Strings in structure are TCHAR*.
+#else
+#define CI_TCHAR 0
+#endif
+
+
+
+#endif //__M_VARS