├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── assets ├── screenshot-music-presence.png └── screenshot-windows-media-control.png ├── foobar2000 ├── ATLHelpers │ ├── ATLHelpers.h │ ├── AutoComplete.cpp │ ├── AutoComplete.h │ ├── BumpableElem.h │ ├── CDialogResizeHelper.cpp │ ├── CDialogResizeHelper.h │ ├── GDIUtils.h │ ├── Include │ │ ├── MS-PL.txt │ │ ├── atlapp.h │ │ ├── atlcrack.h │ │ ├── atlctrls.h │ │ ├── atlctrlw.h │ │ ├── atlctrlx.h │ │ ├── atlddx.h │ │ ├── atldlgs.h │ │ ├── atldwm.h │ │ ├── atlfind.h │ │ ├── atlframe.h │ │ ├── atlgdi.h │ │ ├── atlmisc.h │ │ ├── atlprint.h │ │ ├── atlres.h │ │ ├── atlribbon.h │ │ ├── atlscrl.h │ │ ├── atlsplit.h │ │ ├── atltheme.h │ │ ├── atluser.h │ │ └── atlwinx.h │ ├── WTL-PP.h │ ├── WindowPositionUtils.h │ ├── foobar2000_ATL_helpers.vcxproj │ ├── inplace_edit.cpp │ ├── inplace_edit.h │ ├── inplace_edit_v2.cpp │ ├── inplace_edit_v2.h │ ├── misc.cpp │ ├── misc.h │ ├── stdafx.cpp │ └── stdafx.h ├── SDK │ ├── abort_callback.cpp │ ├── abort_callback.h │ ├── advconfig.cpp │ ├── advconfig.h │ ├── advconfig_impl.h │ ├── advconfig_impl_legacy.h │ ├── album_art.cpp │ ├── album_art.h │ ├── album_art_helpers.h │ ├── app_close_blocker.cpp │ ├── app_close_blocker.h │ ├── archive.h │ ├── audioEncoder.h │ ├── audio_chunk.cpp │ ├── audio_chunk.h │ ├── audio_chunk_channel_config.cpp │ ├── audio_chunk_impl.h │ ├── audio_postprocessor.h │ ├── autoplaylist.h │ ├── callback_merit.h │ ├── cfg_var.cpp │ ├── cfg_var.h │ ├── cfg_var_legacy.cpp │ ├── cfg_var_legacy.h │ ├── chapterizer.cpp │ ├── chapterizer.h │ ├── commandline.cpp │ ├── commandline.h │ ├── commonObjects-Apple.h │ ├── commonObjects-Apple.mm │ ├── commonObjects.cpp │ ├── commonObjects.h │ ├── completion_notify.cpp │ ├── completion_notify.h │ ├── component.h │ ├── component_client.h │ ├── components_menu.h │ ├── componentversion.cpp │ ├── componentversion.h │ ├── configCache.h │ ├── configStore.cpp │ ├── configStore.h │ ├── config_io_callback.cpp │ ├── config_io_callback.h │ ├── config_object.cpp │ ├── config_object.h │ ├── config_object_impl.h │ ├── console.cpp │ ├── console.h │ ├── console_manager.h │ ├── contextmenu.h │ ├── contextmenu_manager.h │ ├── coreDarkMode.h │ ├── core_api.h │ ├── coreversion.h │ ├── decode_postprocessor.h │ ├── dsp-frontend.h │ ├── dsp.cpp │ ├── dsp.h │ ├── dsp_manager.cpp │ ├── dsp_manager.h │ ├── event_logger.h │ ├── exception_io.h │ ├── exceptions.h │ ├── file.h │ ├── fileDialog.h │ ├── file_cached_impl.cpp │ ├── file_format_sanitizer.h │ ├── file_info.cpp │ ├── file_info.h │ ├── file_info_const_impl.cpp │ ├── file_info_const_impl.h │ ├── file_info_filter.h │ ├── file_info_filter_impl.h │ ├── file_info_impl.cpp │ ├── file_info_impl.h │ ├── file_info_merge.cpp │ ├── file_lock_manager.h │ ├── file_operation_callback.cpp │ ├── file_operation_callback.h │ ├── filesystem.cpp │ ├── filesystem.h │ ├── filesystem_helper.cpp │ ├── filesystem_helper.h │ ├── filesystem_transacted.h │ ├── foobar2000-all.h │ ├── foobar2000-lite.h │ ├── foobar2000-pfc.h │ ├── foobar2000-sdk-pch.h │ ├── foobar2000-versions.h │ ├── foobar2000-winver.h │ ├── foobar2000.h │ ├── foobar2000_SDK.vcxproj │ ├── foobar2000_SDK.xcodeproj │ │ └── project.pbxproj │ ├── foosort.cpp │ ├── foosort.h │ ├── foosortstring.h │ ├── forward_types.h │ ├── fsItem.cpp │ ├── fsitem.h │ ├── genrand.h │ ├── guids.cpp │ ├── hasher_md5.cpp │ ├── hasher_md5.h │ ├── http_client.h │ ├── icon_remap.h │ ├── image.cpp │ ├── image.h │ ├── imageLoaderLite.h │ ├── imageViewer.h │ ├── info_lookup_handler.h │ ├── initquit.h │ ├── input.cpp │ ├── input.h │ ├── input_file_type.cpp │ ├── input_file_type.h │ ├── input_impl.h │ ├── keyValueIO.h │ ├── keyValueIOimpl.h │ ├── library_callbacks.h │ ├── library_index.h │ ├── library_manager.h │ ├── link_resolver.cpp │ ├── link_resolver.h │ ├── main_thread_callback.cpp │ ├── main_thread_callback.h │ ├── mainmenu.cpp │ ├── mem_block_container.cpp │ ├── mem_block_container.h │ ├── menu.h │ ├── menu_common.h │ ├── menu_helpers.cpp │ ├── menu_helpers.h │ ├── menu_item.cpp │ ├── menu_manager.cpp │ ├── messageBox.h │ ├── message_loop.h │ ├── metadb.cpp │ ├── metadb.h │ ├── metadb_callbacks.h │ ├── metadb_display_field_provider.h │ ├── metadb_handle.cpp │ ├── metadb_handle.h │ ├── metadb_handle_list.cpp │ ├── metadb_index.h │ ├── metadb_info_container_impl.h │ ├── modeless_dialog.h │ ├── noInfo.h │ ├── ole_interaction.h │ ├── output.cpp │ ├── output.h │ ├── packet_decoder.cpp │ ├── packet_decoder.h │ ├── play_callback.h │ ├── playable_location.cpp │ ├── playable_location.h │ ├── playback_control.cpp │ ├── playback_control.h │ ├── playback_stream_capture.h │ ├── playlist.cpp │ ├── playlist.h │ ├── playlistColumnProvider.h │ ├── playlist_loader.cpp │ ├── playlist_loader.h │ ├── popup_message.cpp │ ├── popup_message.h │ ├── powerManager.h │ ├── preferences_page.cpp │ ├── preferences_page.h │ ├── progress_meter.h │ ├── replaygain.cpp │ ├── replaygain.h │ ├── replaygain_info.cpp │ ├── replaygain_scanner.h │ ├── resampler.h │ ├── search_tools.h │ ├── service.cpp │ ├── service.h │ ├── service_by_guid.h │ ├── service_compat.h │ ├── service_impl.h │ ├── shortcut_actions.h │ ├── stdafx.cpp │ ├── system_time_keeper.h │ ├── tag_processor.cpp │ ├── tag_processor.h │ ├── tag_processor_id3v2.cpp │ ├── threadPool.h │ ├── threaded_process.cpp │ ├── threaded_process.h │ ├── threadsLite.h │ ├── timer.h │ ├── titleformat.cpp │ ├── titleformat.h │ ├── titleformat_object.h │ ├── toolbarDropDown.h │ ├── track_property.cpp │ ├── track_property.h │ ├── tracks.h │ ├── ui.cpp │ ├── ui.h │ ├── ui_edit_context.h │ ├── ui_element.cpp │ ├── ui_element.h │ ├── ui_element_typable_window_manager.h │ ├── unpack.h │ ├── utility.cpp │ └── vis.h ├── foo_input_validator │ ├── foo_input_validator.dll │ └── readme.txt ├── foo_mediacontrol │ ├── PCH.cpp │ ├── foo_mediacontrol.rc │ ├── foo_mediacontrol.sln │ ├── foo_mediacontrol.vcxproj │ ├── initquit.cpp │ ├── input_listener.cpp │ ├── input_listener.h │ ├── main.cpp │ ├── media_controls.cpp │ ├── media_controls.h │ ├── message_listener.cpp │ ├── message_listener.h │ ├── playback_listener.cpp │ ├── playback_listener.h │ ├── preferences.cpp │ ├── preferences.h │ ├── resource.h │ ├── stdafx.h │ ├── track_data.cpp │ ├── track_data.h │ └── util.h ├── foobar2000_component_client │ ├── component_client.cpp │ ├── foobar2000_component_client.vcxproj │ └── foobar2000_component_client.xcodeproj │ │ └── project.pbxproj ├── helpers-mac │ ├── CFObject.h │ ├── NSAttributedString+ppaddons.h │ ├── NSAttributedString+ppaddons.m │ ├── NSButton+checked.h │ ├── NSButton+checked.m │ ├── NSComboBox+fb2k.h │ ├── NSComboBox+fb2k.mm │ ├── NSEvent+ppstuff.h │ ├── NSEvent+ppstuff.m │ ├── NSMenu+ppaddons.h │ ├── NSMenu+ppaddons.m │ ├── NSTextField+grayed.h │ ├── NSTextField+grayed.m │ ├── NSView+embed.h │ ├── NSView+embed.m │ ├── NSView+ppsubviews.h │ ├── NSView+ppsubviews.m │ ├── fb2k-platform.h │ ├── fb2k-platform.mm │ ├── fooDecibelFormatter.h │ ├── fooDecibelFormatter.m │ ├── fooPreferencesCommon.h │ ├── fooTimeFormatter.h │ ├── fooTimeFormatter.mm │ ├── fooWindowWithCancel.h │ ├── fooWindowWithCancel.m │ └── foobar2000-mac-helpers.h ├── helpers │ ├── AutoComplete.cpp │ ├── AutoComplete.h │ ├── BumpableElem.h │ ├── CDialogResizeHelper.h │ ├── CListControlFb2kColors.h │ ├── CModelessDialogMessages.h │ ├── COM_utils.h │ ├── CPropVariant.h │ ├── CSingleThreadWrapper.h │ ├── CTableEditHelper-Legacy.cpp │ ├── CTableEditHelper-Legacy.h │ ├── CallForwarder.h │ ├── CmdThread.h │ ├── DarkMode.cpp │ ├── DarkMode.h │ ├── ProcessUtils.h │ ├── ProfileCache.h │ ├── StdAfx.cpp │ ├── StdAfx.h │ ├── ThreadUtils.cpp │ ├── ThreadUtils.h │ ├── VisUtils.cpp │ ├── VisUtils.h │ ├── VolumeMap.cpp │ ├── VolumeMap.h │ ├── WindowPositionUtils.cpp │ ├── WindowPositionUtils.h │ ├── advconfig_impl.h │ ├── advconfig_runtime.h │ ├── albumArtCache.h │ ├── album_art_helpers.cpp │ ├── album_art_helpers.h │ ├── atl-misc.h │ ├── audio_render_float.h │ ├── bitreader_helper.h │ ├── callInMainThreadHelper.h │ ├── callback_merit.h │ ├── cfg_dsp_chain_config.h │ ├── cfg_guidlist.cpp │ ├── cfg_guidlist.h │ ├── cfg_obj.h │ ├── cfg_objList.h │ ├── cfg_var_import.cpp │ ├── cfg_var_import.h │ ├── create_directory_helper.cpp │ ├── create_directory_helper.h │ ├── cue_creator.cpp │ ├── cue_creator.h │ ├── cue_parser.cpp │ ├── cue_parser.h │ ├── cue_parser_embedding.cpp │ ├── cuesheet_index_list.cpp │ ├── cuesheet_index_list.h │ ├── dialog_resize_helper.cpp │ ├── dialog_resize_helper.h │ ├── dropdown_helper.cpp │ ├── dropdown_helper.h │ ├── dsp_dialog.h │ ├── duration_counter.h │ ├── dynamic_bitrate_helper.cpp │ ├── dynamic_bitrate_helper.h │ ├── fb2kWorkerTool.h │ ├── fb2k_threads.h │ ├── fb2k_wfx.h │ ├── fileReadAhead.h │ ├── file_cached.h │ ├── file_info_const_impl.h │ ├── file_list_helper.cpp │ ├── file_list_helper.h │ ├── file_move_helper.cpp │ ├── file_move_helper.h │ ├── file_streamstub.h │ ├── file_win32_wrapper.cpp │ ├── file_win32_wrapper.h │ ├── filetimetools.cpp │ ├── filetimetools.h │ ├── foobar2000+atl.h │ ├── foobar2000-lite+atl.h │ ├── foobar2000_SDK_helpers.xcodeproj │ │ └── project.pbxproj │ ├── foobar2000_sdk_helpers.vcxproj │ ├── fullFileBuffer.h │ ├── helpers.h │ ├── icon_remapping_wildcard.h │ ├── image_load_save.cpp │ ├── image_load_save.h │ ├── inplace_edit.cpp │ ├── inplace_edit.h │ ├── input_fix_seeking.h │ ├── input_helper_cue.cpp │ ├── input_helper_cue.h │ ├── input_helpers.cpp │ ├── input_helpers.h │ ├── input_logging.h │ ├── input_stream_info_reader.h │ ├── meta_table_builder.h │ ├── metadb_handle_array.h │ ├── metadb_handle_set.h │ ├── metadb_info_container_impl.h │ ├── metadb_io_callback_v2_data.h │ ├── metadb_io_hintlist.h │ ├── mp3_utils.cpp │ ├── mp3_utils.h │ ├── notifyList.h │ ├── packet_decoder_aac_common.cpp │ ├── packet_decoder_aac_common.h │ ├── packet_decoder_mp3_common.cpp │ ├── packet_decoder_mp3_common.h │ ├── playlist_position_reference_tracker.h │ ├── readWriteLock.h │ ├── reader_pretend_nonseekable.h │ ├── readers.cpp │ ├── readers.h │ ├── readers_lite.h │ ├── rethrow.h │ ├── seekabilizer.cpp │ ├── seekabilizer.h │ ├── stream_buffer_helper.cpp │ ├── stream_buffer_helper.h │ ├── tag_write_callback_impl.h │ ├── text_file_loader.cpp │ ├── text_file_loader.h │ ├── text_file_loader_v2.cpp │ ├── text_file_loader_v2.h │ ├── track_property_callback_impl.cpp │ ├── track_property_callback_impl.h │ ├── ui_element_helpers.cpp │ ├── ui_element_helpers.h │ ├── win-MulDiv.h │ ├── win-systemtime.cpp │ ├── win-systemtime.h │ ├── win32_dialog.cpp │ ├── win32_dialog.h │ ├── win32_misc.cpp │ ├── win32_misc.h │ ├── window_placement_helper.cpp │ ├── window_placement_helper.h │ ├── winmm-types.h │ ├── writer_wav.cpp │ └── writer_wav.h └── shared │ ├── Utility.cpp │ ├── audio_math.cpp │ ├── audio_math.h │ ├── crash_info.cpp │ ├── fb2kdebug.h │ ├── filedialogs.cpp │ ├── filedialogs.h │ ├── filedialogs_vista.cpp │ ├── font_description.cpp │ ├── minidump.cpp │ ├── modal_dialog.cpp │ ├── shared-ARM64.lib │ ├── shared-ARM64EC.lib │ ├── shared-Win32.lib │ ├── shared-apple.h │ ├── shared-apple.mm │ ├── shared-nix.cpp │ ├── shared-nix.h │ ├── shared-x64.lib │ ├── shared.h │ ├── shared.vcxproj │ ├── shared.xcodeproj │ └── project.pbxproj │ ├── stdafx.cpp │ ├── systray.cpp │ ├── text_drawing.cpp │ ├── utf8.cpp │ ├── utf8api.cpp │ └── win32_misc.h ├── libPPUI ├── AutoComplete.cpp ├── AutoComplete.h ├── CButtonLite.h ├── CDialogResizeHelper.cpp ├── CDialogResizeHelper.h ├── CDialogResizeHelperCompat.h ├── CEditWithButtons.cpp ├── CEditWithButtons.h ├── CEnumString.h ├── CFlashWindow.h ├── CHeaderCtrlEx.h ├── CIconOverlayWindow.h ├── CListAccessible.cpp ├── CListAccessible.h ├── CListControl-Cell.h ├── CListControl-Cells-Compat.h ├── CListControl-Cells.cpp ├── CListControl-Cells.h ├── CListControl-Subst.cpp ├── CListControl-Subst.h ├── CListControl.cpp ├── CListControl.h ├── CListControlComplete.h ├── CListControlHeaderImpl.cpp ├── CListControlHeaderImpl.h ├── CListControlOwnerData.h ├── CListControlSimple.h ├── CListControlTruncationTooltipImpl.cpp ├── CListControlTruncationTooltipImpl.h ├── CListControlUserOptions.h ├── CListControlWithSelection.cpp ├── CListControlWithSelection.h ├── CListControl_EditImpl.h ├── CListViewCtrlEx.h ├── CMiddleDragImpl.cpp ├── CMiddleDragImpl.h ├── CMiddleDragLite.h ├── CMiddleDragOverlay.h ├── CPopupTooltipMessage.h ├── CPowerRequest.cpp ├── CPowerRequest.h ├── CPropVariant.h ├── CWindowCreateAndDelete.h ├── Controls.cpp ├── Controls.h ├── DarkMode-CHyperLink.h ├── DarkMode.cpp ├── DarkMode.h ├── DarkModeEx.h ├── EditBoxFix.cpp ├── EditBoxFixes.h ├── GDIUtils.cpp ├── GDIUtils.h ├── HyperLinkCtrl.h ├── IDataObjectUtils.cpp ├── IDataObjectUtils.h ├── ImageEncoder.cpp ├── ImageEncoder.h ├── ImplementOnFinalMessage.h ├── InPlaceCombo.cpp ├── InPlaceEdit.cpp ├── InPlaceEdit.h ├── InPlaceEditTable.cpp ├── InPlaceEditTable.h ├── PaintUtils.cpp ├── PaintUtils.h ├── ReStyleWnd.h ├── SmartStrStr.h ├── TreeMultiSel.h ├── TypeFind.cpp ├── TypeFind.h ├── clipboard.cpp ├── clipboard.h ├── commandline_parser.cpp ├── commandline_parser.h ├── gdi-types-portable.h ├── gdiplus-helpers-webp.h ├── gdiplus_helpers.cpp ├── gdiplus_helpers.h ├── gesture.h ├── hookWindowMessages.h ├── libPPUI-license.txt ├── libPPUI-readme.txt ├── libPPUI.vcxproj ├── link-CommonControls6.h ├── listview_helper.cpp ├── listview_helper.h ├── pp-COM-macros.h ├── stdafx.cpp ├── stdafx.h ├── targetver.h ├── win32_op.cpp ├── win32_op.h ├── win32_utility.cpp ├── win32_utility.h ├── windowLifetime.h ├── wtl-pp.cpp └── wtl-pp.h ├── pfc ├── CFObject.h ├── SmartStrStr-table.h ├── SmartStrStr-twoCharMappings.h ├── SmartStrStr.cpp ├── SmartStrStr.h ├── alloc.h ├── array.h ├── audio_math.cpp ├── audio_sample.cpp ├── audio_sample.h ├── autoref.h ├── avltree.h ├── base64.cpp ├── base64.h ├── bigmem.cpp ├── bigmem.h ├── binary_search.h ├── bit_array.cpp ├── bit_array.h ├── bit_array_impl.h ├── bit_array_impl_part2.h ├── bsearch.cpp ├── bsearch.h ├── bsearch_inline.h ├── byte_order.h ├── chain_list_v2.h ├── charDownConvert.cpp ├── charDownConvert.h ├── cmd_thread.h ├── com_ptr_t.h ├── cpuid.cpp ├── cpuid.h ├── crashWithMessage.cpp ├── debug.h ├── event.h ├── event_std.h ├── filehandle.cpp ├── filehandle.h ├── filetimetools.cpp ├── filetimetools.h ├── fixed_map.h ├── fpu.h ├── guid.cpp ├── guid.h ├── instance_tracker_legacy.h ├── int_types.h ├── iterators.h ├── killswitch.h ├── list.h ├── lockless.h ├── map.h ├── mem_block.h ├── memalign.h ├── nix-objects.cpp ├── nix-objects.h ├── notifyList.h ├── obj-c.mm ├── once.h ├── order_helper.h ├── other.cpp ├── other.h ├── pathUtils.cpp ├── pathUtils.h ├── pfc-fb2k-hooks.cpp ├── pfc-fb2k-hooks.h ├── pfc-license.txt ├── pfc-lite.h ├── pfc-readme.txt ├── pfc.h ├── pfc.vcxproj ├── pfc.xcodeproj │ └── project.pbxproj ├── platform-objects.h ├── pocket_char_ops.h ├── pool.h ├── pp-winapi.h ├── primitives.h ├── primitives_part2.h ├── printf.cpp ├── ptr_list.h ├── ptrholder.h ├── rcptr.h ├── ref_counter.h ├── selftest.cpp ├── sort.cpp ├── sort.h ├── sort2.h ├── sortstring.h ├── splitString.h ├── splitString2.cpp ├── splitString2.h ├── stdafx.cpp ├── stdsort.h ├── string-compare.cpp ├── string-compare.h ├── string-conv-lite.cpp ├── string-conv-lite.h ├── string-interface.h ├── string-lite.cpp ├── string-lite.h ├── string-part.h ├── string_base.cpp ├── string_base.h ├── string_conv.cpp ├── string_conv.h ├── string_list.h ├── string_simple.h ├── suppress_fb2k_hooks.h ├── syncd_storage.h ├── synchro.h ├── synchro_nix.cpp ├── synchro_nix.h ├── synchro_win.h ├── targetver.h ├── threadSafeObj.h ├── threads.cpp ├── threads.h ├── timers.cpp ├── timers.h ├── traits.h ├── unicode-normalize.cpp ├── unicode-normalize.h ├── utf8.cpp ├── wait_queue.h ├── weakRef.h ├── wildcard.cpp ├── wildcard.h ├── win-objects.cpp └── win-objects.h └── sdk-license.txt /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2016, Nikola Yanakiev 4 | Copyright (c) 2024, Jonas van den Berg 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: package 2 | 3 | component_name=foo_mediacontrol 4 | dll_filename=$(component_name).dll 5 | dll_x86=.\foobar2000\foo_mediacontrol\Release\$(dll_filename) 6 | dll_x64=.\foobar2000\foo_mediacontrol\x64\Release\$(dll_filename) 7 | out_ext=.fb2k-component 8 | 9 | all: 10 | 11 | package: $(dll_x86) $(dll_x64) 12 | rmdir /S /Q package 13 | md package 14 | md package\x86 15 | md package\x64 16 | copy $(dll_x86) .\package\x86\$(dll_filename) 17 | copy $(dll_x64) .\package\x64\$(dll_filename) 18 | powershell Compress-Archive .\package\x86\$(dll_filename) .\package\$(component_name)-x86.zip 19 | powershell Compress-Archive .\package\x64\$(dll_filename) .\package\$(component_name)-x64.zip 20 | powershell $$pwd=(Resolve-Path .); Rename-Item -Path "$$pwd\package\$(component_name)-x86.zip" -NewName "$$pwd\package\$(component_name)-x86$(out_ext)" 21 | powershell $$pwd=(Resolve-Path .); Rename-Item -Path "$$pwd\package\$(component_name)-x64.zip" -NewName "$$pwd\package\$(component_name)-x64$(out_ext)" 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # foo_mediacontrol 2 | Adds the ability for foobar2000 to interact with the Windows 10 media control overlay. 3 | 4 | ### Screenshots 5 | 6 | Screenshot of the Windows 10 Media Control overlay 7 | 8 | ![Display of the current track in Windows Media Control](./assets/screenshot-windows-media-control.png) 9 | 10 | Screenshot of foobar2000 in your Discord status using 11 | [**Music Presence**](https://github.com/ungive/discord-music-presence) 12 | 13 | ![foobar2000 in your Discord status using Music Presence](./assets/screenshot-music-presence.png) 14 | 15 | ### Compilation 16 | #### Windows 17 | 18 | Compilation requires Windows 10 SDK version 10.0.10240.0 or higher. 19 | - Open the provided solution file (foobar2000/foo_mediacontrol/foo_mediacontrol.sln) in Visual Studio. 20 | - Change the target to "Release" and platform to "x86". 21 | - Build the solution (Default: Ctrl+Shift+B). 22 | - Move the resulting foo_mediacontrol.dll to your foobar2000's components folder. 23 | - (Re)Start foobar2000. 24 | 25 | ### Packaging 26 | #### Windows 27 | 28 | Build the project by opening Visual Studio and following these steps: 29 | 30 | - Go to "Build" and click "Clean Solution" 31 | - Select "Release" and "x86". Go to "Build" and click "Rebuild foo_mediacontrol" 32 | - Select "Release" and "x64". Go to "Build" and click "Rebuild foo_mediacontrol" 33 | - Wait until both builds completed successfully 34 | 35 | Now open a command prompt and enter the following command, 36 | presuming you have `make` installed: 37 | 38 | ``` 39 | make package 40 | ``` 41 | 42 | `fb2k-component` files for x86 and x64 will be in the `package` directory. 43 | 44 | ### License 45 | ---- 46 | [BSD-2-Clause](./LICENSE) -------------------------------------------------------------------------------- /assets/screenshot-music-presence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungive/foo_mediacontrol/d07055f5147fcd80277d91d2a306e9e3bacd024e/assets/screenshot-music-presence.png -------------------------------------------------------------------------------- /assets/screenshot-windows-media-control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungive/foo_mediacontrol/d07055f5147fcd80277d91d2a306e9e3bacd024e/assets/screenshot-windows-media-control.png -------------------------------------------------------------------------------- /foobar2000/ATLHelpers/ATLHelpers.h: -------------------------------------------------------------------------------- 1 | #ifndef _8251B63D_2C1C_4e9d_9320_4E12E46331CB_ 2 | #define _8251B63D_2C1C_4e9d_9320_4E12E46331CB_ 3 | 4 | #define _SECURE_ATL 1 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "../SDK/foobar2000.h" 16 | #include "../helpers/helpers.h" 17 | 18 | #include "WTL-PP.h" 19 | #include "misc.h" 20 | #include "GDIUtils.h" 21 | 22 | #include "WindowPositionUtils.h" 23 | #include "CDialogResizeHelper.h" 24 | 25 | #include "BumpableElem.h" 26 | 27 | #include "inplace_edit.h" 28 | #include "inplace_edit_v2.h" 29 | 30 | #include "AutoComplete.h" 31 | 32 | #endif //_8251B63D_2C1C_4e9d_9320_4E12E46331CB_ 33 | -------------------------------------------------------------------------------- /foobar2000/ATLHelpers/AutoComplete.h: -------------------------------------------------------------------------------- 1 | HRESULT InitializeDropdownAC(HWND comboBox, cfg_dropdown_history_mt & var, const char * initVal); 2 | HRESULT InitializeEditAC(HWND edit, const char * values, DWORD opts = ACO_AUTOAPPEND|ACO_AUTOSUGGEST); 3 | HRESULT InitializeEditAC(HWND edit, pfc::const_iterator valueEnum, DWORD opts = ACO_AUTOAPPEND|ACO_AUTOSUGGEST); 4 | HRESULT InitializeSimpleAC(HWND edit, IUnknown * vals, DWORD opts); 5 | pfc::com_ptr_t CreateACList(pfc::const_iterator valueEnum); 6 | pfc::com_ptr_t CreateACList(pfc::const_iterator valueEnum); 7 | pfc::com_ptr_t CreateACList(pfc::const_iterator valueEnum); 8 | pfc::com_ptr_t CreateACList(); 9 | void CreateACList_AddItem(IUnknown * theList, const char * item); 10 | 11 | -------------------------------------------------------------------------------- /foobar2000/ATLHelpers/misc.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | void PaintSeparatorControl(CWindow wnd) { 4 | CPaintDC dc(wnd); 5 | TCHAR buffer[512] = {}; 6 | wnd.GetWindowText(buffer, _countof(buffer)); 7 | const int txLen = pfc::strlen_max_t(buffer, _countof(buffer)); 8 | CRect contentRect; 9 | WIN32_OP_D( wnd.GetClientRect(contentRect) ); 10 | 11 | dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT)); 12 | dc.SetBkMode(TRANSPARENT); 13 | 14 | { 15 | CBrushHandle brush = (HBRUSH) wnd.GetParent().SendMessage(WM_CTLCOLORSTATIC, (WPARAM) (HDC) dc, (LPARAM) wnd.m_hWnd); 16 | if (brush != NULL) dc.FillRect(contentRect, brush); 17 | } 18 | SelectObjectScope scopeFont(dc, wnd.GetFont()); 19 | 20 | if (txLen > 0) { 21 | CRect rcText(contentRect); 22 | WIN32_OP_D( dc.DrawText(buffer,txLen,rcText,DT_NOPREFIX | DT_END_ELLIPSIS | DT_SINGLELINE | DT_VCENTER | DT_LEFT ) > 0); 23 | } 24 | 25 | SIZE txSize, probeSize; 26 | const TCHAR probe[] = _T("#"); 27 | if (dc.GetTextExtent(buffer,txLen,&txSize) && dc.GetTextExtent(probe, _countof(probe), &probeSize)) { 28 | int spacing = txSize.cx > 0 ? (probeSize.cx / 4) : 0; 29 | if (txSize.cx + spacing < contentRect.Width()) { 30 | const CPoint center = contentRect.CenterPoint(); 31 | CRect rcEdge(contentRect.left + txSize.cx + spacing, center.y, contentRect.right, contentRect.bottom); 32 | WIN32_OP_D( dc.DrawEdge(rcEdge, EDGE_ETCHED, BF_TOP) ); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /foobar2000/ATLHelpers/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // foobar2000_ATL_helpers.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /foobar2000/ATLHelpers/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | // https://cplusplus.com/forum/windows/129472/ 9 | #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. 10 | #define _WIN32_WINNT 0x0601 // Change this to the appropriate value to target other versions of Windows. 11 | #endif 12 | 13 | 14 | // TODO: reference additional headers your program requires here 15 | 16 | // #define WIN32_LEAN_AND_MEAN 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "ATLHelpers.h" 24 | -------------------------------------------------------------------------------- /foobar2000/SDK/audioEncoder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace fb2k { 4 | //! \since 2.0 5 | struct audioEncoderSetup_t { 6 | audio_chunk::spec_t spec; 7 | uint32_t bps; 8 | double durationHint; // Optional; if > 0 signals the encoder expected PCM stream length in advance to avoid rewriting headers 9 | }; 10 | //! \since 2.0 11 | class audioEncoderInstance : public service_base { 12 | FB2K_MAKE_SERVICE_INTERFACE( audioEncoderInstance, service_base); 13 | public: 14 | virtual void addChunk( const audio_chunk & chunk, abort_callback & aborter ) = 0; 15 | virtual void finalize( abort_callback & aborter ) = 0; 16 | }; 17 | 18 | //! \since 2.0 19 | class audioEncoder : public service_base { 20 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT( audioEncoder ); 21 | public: 22 | virtual const char * formatExtension() = 0; 23 | virtual audioEncoderInstance::ptr open( file::ptr outFile, audioEncoderSetup_t const & spec, abort_callback & aborter ) = 0; 24 | 25 | static audioEncoderInstance::ptr g_open( const char * targetPath, file::ptr fileHint, audioEncoderSetup_t const & spec, abort_callback & aborter ); 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /foobar2000/SDK/audio_chunk_impl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // header added for fb2k mobile compatibility -------------------------------------------------------------------------------- /foobar2000/SDK/audio_postprocessor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "audio_chunk.h" 4 | #include "mem_block_container.h" 5 | 6 | //! This class handles conversion of audio data (audio_chunk) to various linear PCM types, with optional dithering. 7 | class NOVTABLE audio_postprocessor : public service_base 8 | { 9 | public: 10 | //! Processes one chunk of audio data. 11 | //! @param p_chunk Chunk of audio data to process. 12 | //! @param p_output Receives output linear signed PCM data. 13 | //! @param p_out_bps Desired bit depth of output. 14 | //! @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. 15 | //! @param p_dither Indicates whether dithering should be used. Note that dithering is CPU-heavy. 16 | //! @param p_prescale Value to scale all audio samples by when converting. Set to 1.0 to do nothing. 17 | 18 | virtual void run(const audio_chunk & p_chunk, 19 | mem_block_container & p_output, 20 | t_uint32 p_out_bps, 21 | t_uint32 p_out_bps_physical, 22 | bool p_dither, 23 | audio_sample p_prescale 24 | ) = 0; 25 | 26 | 27 | 28 | FB2K_MAKE_SERVICE_COREAPI(audio_postprocessor); 29 | }; 30 | -------------------------------------------------------------------------------- /foobar2000/SDK/callback_merit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace fb2k { 4 | // callback_merit_t controls in what order callbacks are executed. \n 5 | // In specific corner cases, you want your callback executed before other callbacks of the same kind. 6 | typedef double callback_merit_t; 7 | 8 | // Note REVERSE sort. HIGHER merit called first. 9 | static constexpr callback_merit_t callback_merit_default = 0; 10 | static constexpr callback_merit_t callback_merit_indexer = 1000; // indexer: does nothing else than updating internal state, called early before UI updates, in case UI updates might rely on indexed data. 11 | static constexpr callback_merit_t callback_merit_serializer = 2000; // serializer: does nothing else than saving new state, called early. 12 | 13 | //! Special class that can be optionally implemented by 'static' callbacks, such as library_callback, to control callback merit. \n 14 | //! See also: callback_merit_t \n 15 | //! Some callback classes support get_callback_merit() natively, such as metadb_io_callback_v2. \n 16 | //! With callbacks registered dynamically, other means of controlling merit are provided. 17 | class callback_with_merit : public service_base { 18 | FB2K_MAKE_SERVICE_INTERFACE(callback_with_merit, service_base); 19 | public: 20 | virtual callback_merit_t get_callback_merit() = 0; 21 | }; 22 | 23 | callback_merit_t callback_merit_of(service_ptr obj); 24 | } -------------------------------------------------------------------------------- /foobar2000/SDK/chapterizer.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000-sdk-pch.h" 2 | #include "chapterizer.h" 3 | 4 | void chapter_list::copy(const chapter_list & p_source) 5 | { 6 | t_size n, count = p_source.get_chapter_count(); 7 | set_chapter_count(count); 8 | for(n=0;n & p_out,const char * p_path) 19 | { 20 | for (auto ptr : enumerate()) { 21 | if (ptr->is_our_path(p_path)) { 22 | p_out = ptr; 23 | return true; 24 | } 25 | } 26 | return false; 27 | } 28 | 29 | bool chapterizer::g_is_pregap_capable(const char * p_path) { 30 | for (auto ptr : enumerate()) { 31 | if (ptr->supports_pregaps() && ptr->is_our_path(p_path)) { 32 | return true; 33 | } 34 | } 35 | return false; 36 | } 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /foobar2000/SDK/commandline.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000-sdk-pch.h" 2 | 3 | #include "commandline.h" 4 | #include "metadb.h" 5 | #include "console.h" 6 | 7 | void commandline_handler_metadb_handle::on_file(const char * url) { 8 | metadb_handle_list handles; 9 | try { 10 | metadb_io::get()->path_to_handles_simple(url, handles); 11 | } catch(std::exception const & e) { 12 | console::complain("Path evaluation failure", e); 13 | return; 14 | } 15 | for(t_size walk = 0; walk < handles.get_size(); ++walk) on_file(handles[walk]); 16 | } 17 | -------------------------------------------------------------------------------- /foobar2000/SDK/commandline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //! Service for handling commandline arguments passed to foobar2000.exe 4 | class NOVTABLE commandline_handler : public service_base 5 | { 6 | public: 7 | enum result 8 | { 9 | RESULT_NOT_OURS,//not our command 10 | RESULT_PROCESSED,//command processed 11 | RESULT_PROCESSED_EXPECT_FILES,//command processed, we want to takeover file urls after this command 12 | }; 13 | virtual result on_token(const char * token)=0; 14 | virtual void on_file(const char * url) {};//optional 15 | virtual void on_files_done() {};//optional 16 | virtual bool want_directories() {return false;} 17 | 18 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(commandline_handler); 19 | }; 20 | 21 | //! Helper automatically turning passed file locations into metadb_handle objects (audio track references) 22 | class commandline_handler_metadb_handle : public commandline_handler { 23 | protected: 24 | void on_file(const char * url) override final; 25 | bool want_directories() override {return true;} 26 | public: 27 | //! Override me 28 | virtual result on_token(const char * token) override = 0; 29 | //! Override me 30 | virtual void on_files_done() override {}; 31 | //! Override me 32 | virtual void on_file(const metadb_handle_ptr & ptr) = 0; 33 | }; 34 | 35 | /* 36 | 37 | how commandline_handler is used: 38 | 39 | scenario #1: 40 | creation => on_token() => deletion 41 | scenario #2: 42 | creation => on_token() returning RESULT_PROCESSED_EXPECT_FILES => on_file(), on_file().... => on_files_done() => deletion 43 | */ 44 | 45 | template 46 | class commandline_handler_factory_t : public service_factory_t {}; 47 | -------------------------------------------------------------------------------- /foobar2000/SDK/commonObjects-Apple.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __APPLE__ 4 | 5 | namespace fb2k { 6 | class NSObjectWrapper : public service_base { 7 | FB2K_MAKE_SERVICE_INTERFACE(NSObjectWrapper, service_base); 8 | public: 9 | virtual void * get_() = 0; 10 | #ifdef __OBJC__ 11 | id get() { return (__bridge id) get_(); } 12 | #endif 13 | 14 | }; 15 | #ifdef __OBJC__ 16 | service_ptr wrapNSObject(id); 17 | id unwrapNSObject(service_ptr); 18 | #endif 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /foobar2000/SDK/commonObjects-Apple.mm: -------------------------------------------------------------------------------- 1 | #include "foobar2000-sdk-pch.h" 2 | #include "commonObjects-Apple.h" 3 | #include 4 | 5 | namespace { 6 | class NSObjectWrapperImpl : public fb2k::NSObjectWrapper { 7 | public: 8 | id obj; 9 | void * get_() override { 10 | return (__bridge void*) obj; 11 | } 12 | }; 13 | } 14 | namespace fb2k { 15 | service_ptr wrapNSObject(id arg) { 16 | if (!arg) return nullptr; 17 | auto ret = fb2k::service_new(); 18 | ret->obj = arg; 19 | return ret; 20 | } 21 | id unwrapNSObject(service_ptr arg) { 22 | id ret = nil; 23 | fb2k::NSObjectWrapper::ptr obj; 24 | if ( obj &= arg ) { 25 | ret = obj->get(); 26 | } 27 | return ret; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /foobar2000/SDK/component_client.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMPONENT_CLIENT_H_ 2 | #define _COMPONENT_CLIENT_H_ 3 | 4 | 5 | 6 | #endif //_COMPONENT_CLIENT_H_ -------------------------------------------------------------------------------- /foobar2000/SDK/components_menu.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMPONENTS_MENU_H_ 2 | #define _COMPONENTS_MENU_H_ 3 | 4 | #error deprecated, see menu_item.h 5 | 6 | 7 | #endif -------------------------------------------------------------------------------- /foobar2000/SDK/componentversion.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000-sdk-pch.h" 2 | 3 | #ifdef _WIN32 4 | #include "componentversion.h" 5 | #include "filesystem.h" 6 | #include "console.h" 7 | 8 | bool component_installation_validator::test_my_name(const char * fn) { 9 | const char * path = core_api::get_my_full_path(); 10 | path += pfc::scan_filename(path); 11 | bool retVal = ( strcmp(path, fn) == 0 ); 12 | PFC_ASSERT( retVal ); 13 | if (!retVal) uAddDebugEvent(pfc::format("Component rename detected: ", fn, " >> ", path)); 14 | return retVal; 15 | } 16 | bool component_installation_validator::have_other_file(const char * fn) { 17 | for(int retry = 0;;) { 18 | pfc::string_formatter path = core_api::get_my_full_path(); 19 | path.truncate(path.scan_filename()); 20 | path << fn; 21 | try { 22 | try { 23 | bool v = filesystem::g_exists(path, fb2k::noAbort); 24 | PFC_ASSERT( v ); 25 | return v; 26 | } catch(std::exception const & e) { 27 | FB2K_console_formatter() << "Component integrity check error: " << e << " (on: " << fn << ")"; 28 | throw; 29 | } 30 | } catch(exception_io_denied const &) { 31 | 32 | } catch(exception_io_sharing_violation const &) { 33 | 34 | } catch(exception_io_file_corrupted const &) { // happens 35 | return false; 36 | } catch(...) { 37 | uBugCheck(); 38 | } 39 | if (++retry == 10) uBugCheck(); 40 | 41 | Sleep(100); 42 | } 43 | } 44 | 45 | #endif // _WIN32 46 | 47 | -------------------------------------------------------------------------------- /foobar2000/SDK/configCache.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace fb2k { 6 | // cache of config values 7 | // STATIC USE ONLY 8 | class configBoolCache { 9 | public: 10 | configBoolCache(const char* var, bool def = false) : m_var(var), m_def(def) {} 11 | bool get(); 12 | operator bool() { return get(); } 13 | void set(bool); 14 | void operator=(bool v) { set(v); } 15 | 16 | configBoolCache(const configBoolCache&) = delete; 17 | void operator=(const configBoolCache&) = delete; 18 | private: 19 | const char* const m_var; 20 | const bool m_def; 21 | std::atomic_bool m_value = { false }; 22 | std::once_flag m_init; 23 | }; 24 | 25 | class configIntCache { 26 | public: 27 | configIntCache(const char* var, int64_t def = 0) : m_var(var), m_def(def) {} 28 | int64_t get(); 29 | operator int64_t() { return get(); } 30 | void set(int64_t); 31 | void operator=(int64_t v) { set(v); } 32 | 33 | configIntCache(const configIntCache&) = delete; 34 | void operator=(const configIntCache&) = delete; 35 | private: 36 | const char* const m_var; 37 | const int64_t m_def; 38 | std::atomic_int64_t m_value = { 0 }; 39 | std::once_flag m_init; 40 | }; 41 | } -------------------------------------------------------------------------------- /foobar2000/SDK/config_io_callback.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000-sdk-pch.h" 2 | #include "filesystem.h" 3 | #include "config_io_callback.h" 4 | 5 | static filesystem::ptr defaultFS() { 6 | return filesystem::get( core_api::get_profile_path() ); 7 | } 8 | 9 | void config_io_callback_v3::on_quicksave() { 10 | this->on_quicksave_v3(defaultFS()); 11 | } 12 | void config_io_callback_v3::on_write(bool bReset) { 13 | auto fs = defaultFS(); 14 | if (bReset) this->on_reset_v3(fs); 15 | else this->on_write_v3(fs); 16 | } 17 | -------------------------------------------------------------------------------- /foobar2000/SDK/console_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "commonObjects.h" 3 | 4 | namespace fb2k { 5 | //! \since 2.0 6 | class NOVTABLE console_notify { 7 | public: 8 | virtual void onConsoleRefresh() = 0; 9 | virtual void onConsoleLines(size_t oldLinesGone, arrayRef newLines, arrayRef newLinesTS) { onConsoleRefresh(); } 10 | }; 11 | //! \since 2.0 12 | class NOVTABLE console_manager : public service_base { 13 | FB2K_MAKE_SERVICE_COREAPI(console_manager); 14 | public: 15 | virtual void clearBacklog() = 0; 16 | virtual fb2k::arrayRef getLines() = 0; 17 | virtual fb2k::arrayRef getLinesTimestamped() = 0; 18 | virtual void addNotify(console_notify* notify) = 0; 19 | virtual void removeNotify(console_notify* notify) = 0; 20 | virtual void saveBacklog() = 0; 21 | virtual bool isVerbose() = 0; 22 | }; 23 | } // namespace fb2k 24 | 25 | namespace console { 26 | void addNotify(fb2k::console_notify*); 27 | void removeNotify(fb2k::console_notify*); 28 | fb2k::arrayRef getLines(); 29 | void clearBacklog(); 30 | } 31 | -------------------------------------------------------------------------------- /foobar2000/SDK/coreversion.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class NOVTABLE core_version_info : public service_base { 4 | FB2K_MAKE_SERVICE_COREAPI(core_version_info); 5 | public: 6 | virtual const char * get_version_string() = 0; 7 | static const char * g_get_version_string() {return core_version_info::get()->get_version_string();} 8 | 9 | }; 10 | 11 | struct t_core_version_data { 12 | t_uint32 m_major, m_minor1, m_minor2, m_minor3; 13 | }; 14 | 15 | //! New (0.9.4.2) 16 | class NOVTABLE core_version_info_v2 : public core_version_info { 17 | FB2K_MAKE_SERVICE_COREAPI_EXTENSION(core_version_info_v2, core_version_info); 18 | public: 19 | virtual const char * get_name() = 0;//"foobar2000" 20 | virtual const char * get_version_as_text() = 0;//"N.N.N.N" 21 | virtual t_core_version_data get_version() = 0; 22 | 23 | //! Determine whether running foobar2000 version is newer or equal to the specified version, eg. test_version(0,9,5,0) for 0.9.5. 24 | bool test_version(t_uint32 major, t_uint32 minor1, t_uint32 minor2, t_uint32 minor3) { 25 | const t_core_version_data v = get_version(); 26 | if (v.m_major < major) return false; 27 | else if (v.m_major > major) return true; 28 | // major version matches 29 | else if (v.m_minor1 < minor1) return false; 30 | else if (v.m_minor1 > minor1) return true; 31 | // minor1 version matches 32 | else if (v.m_minor2 < minor2) return false; 33 | else if (v.m_minor2 > minor2) return true; 34 | // minor2 version matches 35 | else if (v.m_minor3 < minor3) return false; 36 | else return true; 37 | } 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /foobar2000/SDK/dsp-frontend.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "keyValueIO.h" 3 | 4 | typedef fb2k::keyValueIO dsp_preset_edit_callback_v3; 5 | 6 | namespace fb2k { 7 | static const double dsp_slider_lag = 0.2; 8 | } 9 | -------------------------------------------------------------------------------- /foobar2000/SDK/exceptions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | //! Base class for exceptions that should show a human readable message when caught in app entrypoint function rather than crash and send a crash report. 3 | PFC_DECLARE_EXCEPTION(exception_messagebox,pfc::exception,"Internal Error"); 4 | 5 | //! Base class for exceptions that should result in a quiet app shutdown. 6 | PFC_DECLARE_EXCEPTION(exception_shutdownrequest,pfc::exception,"Shutdown Request"); 7 | 8 | 9 | PFC_DECLARE_EXCEPTION(exception_installdamaged, exception_messagebox, "Internal error - one or more of the installed components have been damaged; please run the foobar2000 installer again."); 10 | PFC_DECLARE_EXCEPTION(exception_osfailure, exception_messagebox, "Internal error - broken Windows installation?"); 11 | PFC_DECLARE_EXCEPTION(exception_out_of_resources, exception_messagebox, "Not enough system resources available."); 12 | 13 | PFC_DECLARE_EXCEPTION(exception_configdamaged, exception_messagebox, "Internal error - configuration files are unreadable."); 14 | -------------------------------------------------------------------------------- /foobar2000/SDK/file_info_filter_impl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "file_info_filter.h" 3 | #include "file_info_impl.h" 4 | 5 | //! Generic implementation of file_info_filter_impl. 6 | class file_info_filter_impl : public file_info_filter { 7 | public: 8 | file_info_filter_impl(const pfc::list_base_const_t & p_list, const pfc::list_base_const_t & p_new_info) { 9 | FB2K_DYNAMIC_ASSERT(p_list.get_count() == p_new_info.get_count()); 10 | pfc::array_t order; 11 | order.set_size(p_list.get_count()); 12 | order_helper::g_fill(order.get_ptr(), order.get_size()); 13 | p_list.sort_get_permutation_t(pfc::compare_t, order.get_ptr()); 14 | m_handles.set_count(order.get_size()); 15 | m_infos.set_size(order.get_size()); 16 | for (t_size n = 0; n < order.get_size(); n++) { 17 | m_handles[n] = p_list[order[n]]; 18 | m_infos[n] = *p_new_info[order[n]]; 19 | } 20 | } 21 | 22 | bool apply_filter(metadb_handle_ptr p_location, t_filestats p_stats, file_info & p_info) { 23 | t_size index; 24 | if (m_handles.bsearch_t(pfc::compare_t, p_location, index)) { 25 | p_info = m_infos[index]; 26 | return true; 27 | } 28 | else { 29 | return false; 30 | } 31 | } 32 | private: 33 | metadb_handle_list m_handles; 34 | pfc::array_t m_infos; 35 | }; 36 | -------------------------------------------------------------------------------- /foobar2000/SDK/filesystem_transacted.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "filesystem.h" 4 | 5 | // Since 1.5, transacted filesystem is no longer supported 6 | // as it adds extra complexity without actually solving any problems. 7 | // Even Microsoft recommends not to use this API. 8 | #define FB2K_SUPPORT_TRANSACTED_FILESYSTEM 0 9 | -------------------------------------------------------------------------------- /foobar2000/SDK/foobar2000-all.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // Redirect to foobar2000.h 3 | #include "foobar2000.h" 4 | -------------------------------------------------------------------------------- /foobar2000/SDK/foobar2000-lite.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "foobar2000-winver.h" 4 | 5 | #include "foobar2000-versions.h" 6 | 7 | #include "foobar2000-pfc.h" 8 | #include "../shared/shared.h" 9 | 10 | #ifndef NOTHROW 11 | #ifdef _MSC_VER 12 | #define NOTHROW __declspec(nothrow) 13 | #else 14 | #define NOTHROW 15 | #endif 16 | #endif 17 | 18 | #define FB2KAPI /*NOTHROW*/ 19 | 20 | typedef const char* pcchar; 21 | 22 | #include "core_api.h" 23 | #include "service.h" 24 | #include "service_impl.h" 25 | #include "service_by_guid.h" 26 | #include "service_compat.h" 27 | 28 | #include "forward_types.h" 29 | 30 | #include "abort_callback.h" 31 | #include "threadsLite.h" 32 | 33 | #include "playable_location.h" 34 | #include "console.h" 35 | #include "filesystem.h" 36 | #include "metadb.h" 37 | -------------------------------------------------------------------------------- /foobar2000/SDK/foobar2000-pfc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../pfc/pfc.h" 4 | 5 | // These were in a global namespace before and are commonly referenced as such. 6 | using pfc::bit_array; 7 | using pfc::bit_array_var; 8 | using pfc::bit_array_true; 9 | using pfc::bit_array_false; 10 | using pfc::bit_array_val; 11 | using pfc::bit_array_bittable; 12 | using pfc::bit_array_one; 13 | using pfc::bit_array_range; 14 | #ifdef _WIN32 15 | using pfc::LastErrorRevertScope; 16 | #endif 17 | 18 | -------------------------------------------------------------------------------- /foobar2000/SDK/foobar2000-sdk-pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "foobar2000-lite.h" 3 | -------------------------------------------------------------------------------- /foobar2000/SDK/foobar2000-winver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define FOOBAR2000_DESKTOP 4 | 5 | #define FOOBAR2000_HAVE_FILE_FORMAT_SANITIZER 6 | #define FOOBAR2000_HAVE_CHAPTERIZER 7 | #define FOOBAR2000_HAVE_ALBUM_ART 8 | #define FOOBAR2000_DECLARE_FILE_TYPES 9 | #define FOOBAR2000_HAVE_DSP 10 | #define FOOBAR2000_HAVE_CONSOLE 11 | #define FOOBAR2000_INTERACTIVE 12 | #define FOOBAR2000_HAVE_METADB 13 | 14 | 15 | #ifdef _WIN32 16 | #define FOOBAR2000_HAVE_CFG_VAR_LEGACY 17 | #define FOOBAR2000_WINAPI_CLASSIC 18 | #define FOOBAR2000_DESKTOP_WINDOWS 19 | #define FOOBAR2000_DESKTOP_WINDOWS_OR_BOOM 20 | #define FOOBAR2000_SUPPORT_DLLS 1 21 | #define FOOBAR2000_HAVE_KEYBOARD_SHORTCUTS 22 | #endif 23 | 24 | #ifdef __APPLE__ 25 | #define FOOBAR2000_SUPPORT_DLLS 1 26 | #define FOOBAR2000_MAC 27 | #endif 28 | 29 | #ifndef FOOBAR2000_SUPPORT_DLLS 30 | #define FOOBAR2000_SUPPORT_DLLS 0 31 | #endif 32 | -------------------------------------------------------------------------------- /foobar2000/SDK/foosort.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // #define FOOSORT_LIMIT_THREADS 1 4 | 5 | 6 | namespace fb2k { 7 | 8 | // foosort 9 | // abortable multithreaded quicksort 10 | // expects cb to handle concurrent calls as long as they do not touch the same items concurrently 11 | void sort(pfc::sort_callback & cb, size_t count, size_t concurrency, abort_callback & aborter); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /foobar2000/SDK/foosortstring.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #ifdef _WIN32 5 | #include // std::unique_ptr<> 6 | #endif 7 | 8 | namespace fb2k { 9 | using pfc::sortString_t; 10 | using pfc::sortStringCompare; 11 | using pfc::makeSortString; 12 | } 13 | -------------------------------------------------------------------------------- /foobar2000/SDK/forward_types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace foobar2000_io 4 | { 5 | class abort_callback; 6 | } 7 | 8 | namespace fb2k { 9 | class image; 10 | typedef service_ptr_t imageRef; 11 | 12 | class memBlock; 13 | } 14 | 15 | typedef fb2k::memBlock album_art_data; 16 | 17 | typedef service_ptr_t album_art_data_ptr; 18 | 19 | class file_info; 20 | class playable_location; 21 | 22 | class titleformat_object; 23 | class titleformat_hook; 24 | class titleformat_text_filter; 25 | 26 | typedef service_ptr_t titleformat_object_ptr; 27 | 28 | class mem_block_container; 29 | 30 | class file_info_filter; 31 | 32 | class metadb_handle; 33 | typedef service_ptr_t metadb_handle_ptr; 34 | 35 | namespace foobar2000_io { 36 | class stream_reader; class stream_writer; 37 | } 38 | 39 | class metadb_io_callback_v2_data; 40 | -------------------------------------------------------------------------------- /foobar2000/SDK/genrand.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | //! PRNG service. Implemented by the core, do not reimplement. Use g_create() helper function to instantiate. 3 | class NOVTABLE genrand_service : public service_base 4 | { 5 | public: 6 | void seedAuto() {seed( 0 ) ;} 7 | //! Seeds the PRNG with specified value. \n 8 | //! Default value of zero seeds automatically using available system functions. 9 | virtual void seed(unsigned val = 0) = 0; 10 | //! Returns random value N, where 0 <= N < range. 11 | virtual unsigned genrand(unsigned range)=0; 12 | 13 | double genrand_f() { return (double)genrand(0xFFFFFFFF) / (double)0xFFFFFFFF; } 14 | 15 | void genrand_blob( void * out, size_t bytes ) { 16 | size_t dwords = bytes/4; 17 | uint32_t * out32 = (uint32_t*) out; 18 | for(size_t w = 0; w < dwords; ++w ) { 19 | out32[w] = genrand32(); 20 | } 21 | size_t left = bytes % 4; 22 | if (left > 0) { 23 | auto leftptr = (uint8_t*) out + (bytes-left); 24 | for( size_t w = 0; w < left; ++w) leftptr[w] = genrand8(); 25 | } 26 | } 27 | 28 | uint32_t genrand32() { 29 | return (uint32_t) genrand(0xFFFFFFFF); 30 | } 31 | uint8_t genrand8() { 32 | return (uint8_t) genrand(0x100); 33 | } 34 | 35 | static service_ptr_t g_create() {return standard_api_create_t();} 36 | 37 | void generate_random_order(t_size * out, t_size count) { 38 | unsigned genrandMax = (unsigned) pfc::min_t(count, 0xFFFFFFFF); 39 | t_size n; 40 | for(n=0;n(¶m); 8 | byte_order::order_le_to_native_t(temp); 9 | return temp; 10 | } 11 | 12 | GUID hasher_md5_result::asGUID() const { 13 | return hasher_md5::guid_from_result( *this ); 14 | } 15 | 16 | hasher_md5_result hasher_md5::process_single(const void * p_buffer,t_size p_bytes) 17 | { 18 | hasher_md5_state state; 19 | initialize(state); 20 | process(state,p_buffer,p_bytes); 21 | return get_result(state); 22 | } 23 | 24 | GUID hasher_md5::process_single_guid(const void * p_buffer,t_size p_bytes) 25 | { 26 | return guid_from_result(process_single(p_buffer,p_bytes)); 27 | } 28 | 29 | t_uint64 hasher_md5_result::xorHalve() const { 30 | #if PFC_BYTE_ORDER_IS_BIG_ENDIAN 31 | t_uint64 ret = 0; 32 | for(int walk = 0; walk < 8; ++walk) { 33 | ret |= (t_uint64)((t_uint8)m_data[walk] ^ (t_uint8)m_data[walk+8]) << (walk * 8); 34 | } 35 | return ret; 36 | #else 37 | const t_uint64 * v = reinterpret_cast(&m_data); 38 | return v[0] ^ v[1]; 39 | #endif 40 | } 41 | 42 | pfc::string8 hasher_md5_result::asString() const { 43 | return pfc::format_hexdump( this->m_data, sizeof(m_data), ""); 44 | } 45 | 46 | GUID hasher_md5_result::toGUID() const { 47 | return hasher_md5::guid_from_result( *this ); 48 | } 49 | -------------------------------------------------------------------------------- /foobar2000/SDK/icon_remap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //! New in 0.9.5; allows your file format to use another icon than .ico when registering the file type with Windows shell. \n 4 | //! Implementation: use icon_remapping_impl, or simply: static service_factory_single_t myicon("ext","iconname.ico"); 5 | class icon_remapping : public service_base { 6 | public: 7 | //! @param p_extension File type extension being queried. 8 | //! @param p_iconname Receives the icon name to use, including the .ico extension. 9 | //! @returns True when p_iconname has been set, false if we don't recognize the specified extension. 10 | virtual bool query(const char * p_extension,pfc::string_base & p_iconname) = 0; 11 | 12 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(icon_remapping); 13 | }; 14 | 15 | //! Standard implementation of icon_remapping. 16 | class icon_remapping_impl : public icon_remapping { 17 | public: 18 | icon_remapping_impl(const char * p_extension,const char * p_iconname) : m_extension(p_extension), m_iconname(p_iconname) {} 19 | bool query(const char * p_extension,pfc::string_base & p_iconname) { 20 | if (pfc::stricmp_ascii(p_extension,m_extension) == 0) { 21 | p_iconname = m_iconname; return true; 22 | } else { 23 | return false; 24 | } 25 | } 26 | private: 27 | pfc::string8 m_extension,m_iconname; 28 | }; 29 | -------------------------------------------------------------------------------- /foobar2000/SDK/imageViewer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace fb2k { 4 | //! \since 1.6.2 5 | class imageViewer : public service_base { 6 | FB2K_MAKE_SERVICE_COREAPI(imageViewer); 7 | public: 8 | //! Spawns an image viewer window, showing the specified picture already loaded into application memory. 9 | virtual void show(fb2k::hwnd_t parent, fb2k::memBlockRef data) = 0; 10 | //! Spawns an image viewer window, showing album art from the specified list of items. 11 | //! @param aaType Type of picture to load, front cover, back cover or other. 12 | //! @param pageno Reserved for future use, set to 0. 13 | virtual void load_and_show(fb2k::hwnd_t parent, metadb_handle_list_cref items, const GUID & aaType, unsigned pageno = 0) = 0; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /foobar2000/SDK/keyValueIO.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace fb2k { 4 | // Generic interface for writing frontends in high level programming languages 5 | class NOVTABLE keyValueIO : public service_base { 6 | FB2K_MAKE_SERVICE_INTERFACE(keyValueIO, service_base); 7 | public: 8 | virtual fb2k::stringRef get(const char * name) = 0; 9 | virtual void put(const char * name, const char * value) = 0; 10 | virtual void commit() = 0; 11 | virtual void reset() = 0; 12 | virtual void dismiss(bool bOK) = 0; 13 | 14 | int getInt( const char * name ); 15 | void putInt( const char * name, int val ); 16 | }; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /foobar2000/SDK/keyValueIOimpl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "keyValueIO.h" 3 | 4 | #include 5 | #include 6 | 7 | namespace fb2k { 8 | class keyValueIOimpl : public keyValueIO { 9 | public: 10 | fb2k::stringRef get(const char * name) { 11 | auto i = m_content.find(name); 12 | if (i == m_content.end()) return fb2k::makeString(""); 13 | return fb2k::makeString(i->second.c_str()); 14 | } 15 | void put(const char * name, const char * value) { 16 | m_content[name] = value; 17 | } 18 | // OVERRIDE ME 19 | void commit() {} 20 | // OVERRIDE ME 21 | void reset() {} 22 | // OVERRIDE ME 23 | void dismiss(bool bOK) {} 24 | 25 | protected: 26 | std::map m_content; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /foobar2000/SDK/library_index.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "search_tools.h" 4 | 5 | //! OBSOLETE, DO NOT USE \n 6 | //! Please use search_index instead. 7 | class NOVTABLE library_index : public service_base { 8 | FB2K_MAKE_SERVICE_COREAPI(library_index); 9 | public: 10 | virtual void hit_test(search_filter::ptr pattern, metadb_handle_list_cref items, bool* out, abort_callback & a) = 0; 11 | 12 | enum { 13 | flag_sort = 1 << 0, 14 | }; 15 | 16 | virtual fb2k::arrayRef search(search_filter::ptr pattern, uint32_t flags, abort_callback& abort) = 0; 17 | }; -------------------------------------------------------------------------------- /foobar2000/SDK/link_resolver.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000-sdk-pch.h" 2 | #include "link_resolver.h" 3 | 4 | bool link_resolver::g_find(service_ptr_t & p_out,const char * p_path) 5 | { 6 | const auto ext = pfc::string_extension(p_path); 7 | for (auto ptr : enumerate()) { 8 | if (ptr->is_our_path(p_path,ext)) { 9 | p_out = ptr; 10 | return true; 11 | } 12 | } 13 | return false; 14 | } 15 | -------------------------------------------------------------------------------- /foobar2000/SDK/mem_block_container.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000-sdk-pch.h" 2 | #include "mem_block_container.h" 3 | 4 | void mem_block_container::from_stream(stream_reader * p_stream,t_size p_bytes,abort_callback & p_abort) { 5 | if (p_bytes == 0) {set_size(0);} 6 | set_size(p_bytes); 7 | p_stream->read_object(get_ptr(),p_bytes,p_abort); 8 | } 9 | 10 | void mem_block_container::set(const void * p_buffer,t_size p_size) { 11 | set_size(p_size); 12 | memcpy(get_ptr(),p_buffer,p_size); 13 | } 14 | -------------------------------------------------------------------------------- /foobar2000/SDK/messageBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _WIN32 4 | #define IDOK 1 5 | #define IDCANCEL 2 6 | #define IDABORT 3 7 | #define IDRETRY 4 8 | #define IDIGNORE 5 9 | #define IDYES 6 10 | #define IDNO 7 11 | 12 | #define MB_OK 0x00000000L 13 | #define MB_OKCANCEL 0x00000001L 14 | #define MB_ABORTRETRYIGNORE 0x00000002L 15 | #define MB_YESNOCANCEL 0x00000003L 16 | #define MB_YESNO 0x00000004L 17 | #define MB_RETRYCANCEL 0x00000005L 18 | #define MB_CANCELTRYCONTINUE 0x00000006L 19 | 20 | #define MB_ICONHAND 0x00000010L 21 | #define MB_ICONQUESTION 0x00000020L 22 | #define MB_ICONEXCLAMATION 0x00000030L 23 | #define MB_ICONASTERISK 0x00000040L 24 | 25 | #define MB_DEFBUTTON1 0x00000000L 26 | #define MB_DEFBUTTON2 0x00000100L 27 | #define MB_DEFBUTTON3 0x00000200L 28 | #define MB_DEFBUTTON4 0x00000300L 29 | 30 | #define MB_ICONWARNING MB_ICONEXCLAMATION 31 | #define MB_ICONERROR MB_ICONHAND 32 | #define MB_ICONINFORMATION MB_ICONASTERISK 33 | #define MB_ICONSTOP MB_ICONHAND 34 | 35 | #endif // ! _WIN32 36 | 37 | namespace fb2k { 38 | // Minimalist MessageBox() drop-in replacement, calls popup_message_v3 method 39 | // Works properly on non-Windows! 40 | int messageBox(fb2k::hwnd_t, const char*, const char*, unsigned); 41 | void messageBoxAsync(fb2k::hwnd_t, const char*, const char*, unsigned, std::function f = nullptr); 42 | } 43 | -------------------------------------------------------------------------------- /foobar2000/SDK/metadb_info_container_impl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "file_info_const_impl.h" 4 | 5 | class metadb_info_container_const_impl : public metadb_info_container_v2 { 6 | public: 7 | file_info const& info() override { return m_info; } 8 | t_filestats const& stats() override { return m_stats.as_legacy(); } 9 | bool isInfoPartial() override { return false; } 10 | t_filestats2 const& stats2() override { return m_stats; } 11 | file_info_const_impl m_info; 12 | t_filestats2 m_stats; 13 | }; 14 | -------------------------------------------------------------------------------- /foobar2000/SDK/modeless_dialog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifdef _WIN32 3 | //! Service for plugging your nonmodal dialog windows into main app loop to receive IsDialogMessage()-translated messages.\n 4 | //! Note that all methods are valid from main app thread only.\n 5 | //! Usage: call the static methods - modeless_dialog_manager::g_add / modeless_dialog_manager::g_remove. 6 | class NOVTABLE modeless_dialog_manager : public service_base { 7 | FB2K_MAKE_SERVICE_COREAPI(modeless_dialog_manager); 8 | public: 9 | //! Adds specified window to global list of windows to receive IsDialogMessage(). 10 | virtual void add(HWND p_wnd) = 0; 11 | //! Removes specified window from global list of windows to receive IsDialogMessage(). 12 | virtual void remove(HWND p_wnd) = 0; 13 | 14 | //! Static helper; see add(). 15 | static void g_add(HWND p_wnd) {modeless_dialog_manager::get()->add(p_wnd);} 16 | //! Static helper; see remove(). 17 | static void g_remove(HWND p_wnd) {modeless_dialog_manager::get()->remove(p_wnd);} 18 | 19 | }; 20 | #endif 21 | -------------------------------------------------------------------------------- /foobar2000/SDK/playlistColumnProvider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace fb2k { 4 | //! Declares a column to be made available in Default UI playlist view, \n 5 | //! without user having to manually enter title formatting patterns. 6 | class playlistColumnProvider : public service_base { 7 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(playlistColumnProvider); 8 | public: 9 | //! Number of columns published by this object. 10 | virtual size_t numColumns() = 0; 11 | //! Unique identifier of a column. 12 | virtual GUID columnID(size_t col) = 0; 13 | //! Formatting pattern used for displaying a column. 14 | virtual fb2k::stringRef columnFormatSpec(size_t col) = 0; 15 | //! Optional; sorting pattern used for this column. Return null to use display pattern for sorting. 16 | virtual fb2k::stringRef columnSortScript(size_t col) = 0; 17 | //! Name of the column shown to the user. 18 | virtual fb2k::stringRef columnName(size_t col) = 0; 19 | //! Display flags (alignment). \n 20 | //! See flag_* constants. 21 | virtual unsigned columnFlags(size_t col) = 0; 22 | 23 | static constexpr unsigned 24 | flag_alignLeft = 0, flag_alignRight = 1 << 0, flag_alignCenter = 1 << 1, // alignment 25 | flag_numeric = 1 << 2, // prefer fixed width font, not all renderers support this 26 | flag_positionDependant = 1 << 3, // value changes with position in playlist, mainly used by list index etc 27 | flag_glyphs = 1 << 4; // internal/reserved 28 | static constexpr unsigned flag_alignMask = (flag_alignLeft|flag_alignRight|flag_alignCenter); 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /foobar2000/SDK/powerManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace fb2k { 4 | //! \since 2.0 5 | class powerManager : public service_base { 6 | public: 7 | enum { 8 | flagStrong = 1 << 0, 9 | flagPlayback = 1 << 1, 10 | 11 | flagDisplay = flagStrong 12 | }; 13 | 14 | //! Blocks device sleep for the duration of returned object's lifetime. \n 15 | //! By default we ask politely but can be still put to sleep by the OS. Specify flagStrong to force the device into awake state (possibly at cost of keeping the screen up). \n 16 | //! Thread safety: OK to call from any thread. 17 | virtual objRef makeTask(const char* name, unsigned flags) = 0; 18 | 19 | //! Returns whether we're running on AC power (not on battery). \n 20 | //! Thread safety: OK to call from any thread. 21 | virtual bool haveACPower() = 0; 22 | 23 | objRef makeTaskWeak(const char* name) { return makeTask(name, 0); } 24 | objRef makeTaskStrong(const char* name) { return makeTask(name, flagStrong); } 25 | objRef makePlaybackTask() { return makeTask("Playback", flagPlayback); } 26 | 27 | FB2K_MAKE_SERVICE_COREAPI(powerManager) 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /foobar2000/SDK/preferences_page.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000-sdk-pch.h" 2 | #include "preferences_page.h" 3 | #include "coreversion.h" 4 | 5 | void preferences_page::get_help_url_helper(pfc::string_base & out, const char * category, const GUID & id, const char * name) { 6 | out = "https://help.foobar2000.org/"; 7 | pfc::urlEncodeAppend(out, core_version_info::g_get_version_string()); 8 | out << "/"; 9 | pfc::urlEncodeAppend(out, category); 10 | out << "/" << pfc::print_guid(id) << "/"; 11 | pfc::urlEncodeAppend(out, name); 12 | } 13 | bool preferences_page::get_help_url(pfc::string_base & p_out) { 14 | get_help_url_helper(p_out,"preferences",get_guid(), get_name()); 15 | return true; 16 | } 17 | 18 | double preferences_page::get_sort_priority_() { 19 | preferences_page_v2::ptr v2; 20 | if ( v2 &= this ) return v2->get_sort_priority(); 21 | else return 0; 22 | } 23 | -------------------------------------------------------------------------------- /foobar2000/SDK/progress_meter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //! Interface for setting current operation progress state to be visible on Windows 7 taskbar. Use progress_meter::get()->acquire() to instantiate. 4 | class NOVTABLE progress_meter_instance : public service_base { 5 | FB2K_MAKE_SERVICE_INTERFACE(progress_meter_instance, service_base); 6 | public: 7 | //! Sets the current progress state. 8 | //! @param value Progress state, in 0..1 range. 9 | virtual void set_progress(float value) = 0; 10 | //! Toggles paused state. 11 | virtual void set_pause(bool isPaused) = 0; 12 | 13 | static bool serviceRequiresMainThreadDestructor() { return true; } 14 | }; 15 | 16 | //! Entrypoint interface for instantiating progress_meter_instance objects. 17 | class NOVTABLE progress_meter : public service_base { 18 | FB2K_MAKE_SERVICE_COREAPI(progress_meter); 19 | public: 20 | //! Creates a progress_meter_instance object. 21 | virtual progress_meter_instance::ptr acquire() = 0; 22 | }; 23 | -------------------------------------------------------------------------------- /foobar2000/SDK/service_compat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Obsolete features 4 | 5 | //! Special hack to ensure errors when someone tries to ->service_add_ref()/->service_release() on a service_ptr_t 6 | template class service_obscure_refcounting : public T { 7 | private: 8 | int service_add_ref() throw(); 9 | int service_release() throw(); 10 | }; 11 | 12 | //! Converts a service interface pointer to a pointer that obscures service counter functionality. 13 | template static inline service_obscure_refcounting* service_obscure_refcounting_cast(T * p_source) throw() {return static_cast*>(p_source);} 14 | 15 | template class t_alloc = pfc::alloc_fast> 16 | class service_list_t : public pfc::list_t, t_alloc > 17 | { 18 | }; 19 | 20 | //! Helper; simulates array with instance of each available implementation of given service class. 21 | template class service_instance_array_t { 22 | public: 23 | typedef service_ptr_t t_ptr; 24 | service_instance_array_t() { 25 | service_class_helper_t helper; 26 | const t_size count = helper.get_count(); 27 | m_data.set_size(count); 28 | for(t_size n=0;n m_data; 38 | }; 39 | -------------------------------------------------------------------------------- /foobar2000/SDK/shortcut_actions.h: -------------------------------------------------------------------------------- 1 | #error DEPRECATED 2 | -------------------------------------------------------------------------------- /foobar2000/SDK/stdafx.cpp: -------------------------------------------------------------------------------- 1 | //cpp used to generate precompiled header 2 | #include "foobar2000-sdk-pch.h" -------------------------------------------------------------------------------- /foobar2000/SDK/threadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | namespace fb2k { 5 | void inWorkerThread(std::function f); 6 | void inCpuWorkerThread(std::function f); 7 | 8 | //! \since 2.0 9 | class threadEntry : public service_base { 10 | FB2K_MAKE_SERVICE_INTERFACE(threadEntry, service_base); 11 | public: 12 | virtual void run() = 0; 13 | 14 | static threadEntry::ptr make(std::function f); 15 | }; 16 | 17 | //! \since 2.0 18 | //! A class interfacing with shared pool of threads intended for use with CPU bound tasks. \n 19 | //! Use this instead of creating threads directly to avoid making the system unresponsive by creating too many CPU bound threads. 20 | class cpuThreadPool : public service_base { 21 | FB2K_MAKE_SERVICE_COREAPI(cpuThreadPool); 22 | public: 23 | //! Run one time task on a thread pool. Returns immediately. 24 | virtual void runSingle(threadEntry::ptr trd) = 0; 25 | //! Run the task multiple times concurrently. Optionally block until all done. \n 26 | //! Exceptions: if nonblocking, they're discarded; if blocking; rethrown to caller. If multiple are thrown, one of them is rethrown, precedence undefined. 27 | virtual void runMulti(threadEntry::ptr trd, size_t numRuns, bool blocking) = 0; 28 | 29 | virtual size_t numRunsSanity(size_t suggested) = 0; 30 | 31 | //! Helper around blocking runMulti(), with fallback for pre-v2.0 32 | static void runMultiHelper(std::function, size_t numRuns); 33 | void runMulti_(std::function, size_t numRuns); 34 | }; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /foobar2000/SDK/timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "completion_notify.h" 4 | 5 | #if FOOBAR2020 6 | namespace fb2k { 7 | //! \since 2.0 8 | class NOVTABLE timerManager : public service_base { 9 | FB2K_MAKE_SERVICE_COREAPI(timerManager); 10 | public: 11 | virtual objRef addTimer( double interval, completion_notify::ptr callback ) = 0; 12 | }; 13 | 14 | objRef registerTimer( double interval, std::function func ); 15 | void callLater( double timeAfter, std::function< void () > func ); 16 | } 17 | #endif // FOOBAR2020 -------------------------------------------------------------------------------- /foobar2000/SDK/titleformat_object.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // titleformat_object extracted from titleformat.h as it's more commonly used than other titleformat.h stuff 4 | 5 | class file_info; class titleformat_hook; class titleformat_text_filter; 6 | 7 | //! Represents precompiled executable title-formatting script. Use titleformat_compiler to instantiate; do not reimplement. 8 | class NOVTABLE titleformat_object : public service_base 9 | { 10 | public: 11 | virtual void run(titleformat_hook * p_source,pfc::string_base & p_out,titleformat_text_filter * p_filter)=0; 12 | 13 | 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); 14 | void run_simple(const playable_location & p_location,const file_info * p_source,pfc::string_base & p_out); 15 | 16 | //! Helper, see titleformat_object_v2::requires_metadb_info() 17 | bool requires_metadb_info_(); 18 | 19 | FB2K_MAKE_SERVICE_INTERFACE(titleformat_object,service_base); 20 | }; 21 | -------------------------------------------------------------------------------- /foobar2000/SDK/toolbarDropDown.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace fb2k { 4 | 5 | //! \since 2.0 6 | class toolbarDropDownNotify { 7 | public: 8 | virtual void contentChanged() = 0; 9 | virtual void selectionChanged() = 0; 10 | protected: 11 | ~toolbarDropDownNotify() {} 12 | }; 13 | 14 | //! \since 2.0 15 | class toolbarDropDown : public service_base { 16 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(toolbarDropDown) 17 | public: 18 | virtual GUID getGuid() = 0; 19 | virtual void getShortName(pfc::string_base& out) = 0; // name to appear in toolbar 20 | virtual void getLongName(pfc::string_base& out) = 0; // long descriptive name 21 | virtual size_t getNumValues() = 0; 22 | virtual void getValue(size_t idx, pfc::string_base& out) = 0; 23 | virtual void setSelectedIndex(size_t) = 0; 24 | virtual size_t getSelectedIndex() = 0; 25 | virtual void addNotify(toolbarDropDownNotify*) = 0; 26 | virtual void removeNotify(toolbarDropDownNotify*) = 0; 27 | virtual void onDropDown() = 0; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /foobar2000/SDK/ui_element_typable_window_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // API obsoleted in 1.5 and should no longer be used by anything 4 | // Core-implemented to keep components that specifically rely on it working 5 | 6 | class NOVTABLE ui_element_typable_window_manager : public service_base { 7 | FB2K_MAKE_SERVICE_COREAPI(ui_element_typable_window_manager); 8 | public: 9 | virtual void add(HWND wnd) = 0; 10 | virtual void remove(HWND wnd) = 0; 11 | virtual bool is_registered(HWND wnd) = 0; 12 | }; 13 | 14 | FOOGUIDDECL const GUID ui_element_typable_window_manager::class_guid = { 0xbaa99ee2, 0xf770, 0x4981,{ 0x9e, 0x50, 0xf3, 0x4c, 0x5c, 0x6d, 0x98, 0x81 } }; 15 | -------------------------------------------------------------------------------- /foobar2000/foo_input_validator/foo_input_validator.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungive/foo_mediacontrol/d07055f5147fcd80277d91d2a306e9e3bacd024e/foobar2000/foo_input_validator/foo_input_validator.dll -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/PCH.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | // This is a dummy source code file that just generates the precompiled header (PCH) file for use when compiling the rest of the source code, to speed compilation up. -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/foo_mediacontrol.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungive/foo_mediacontrol/d07055f5147fcd80277d91d2a306e9e3bacd024e/foobar2000/foo_mediacontrol/foo_mediacontrol.rc -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/initquit.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "playback_listener.h" 4 | #include "message_listener.h" 5 | #include "preferences.h" 6 | 7 | class myinitquit : public initquit { 8 | public: 9 | void on_init() { 10 | // create a playback listener 11 | m_playback_listener = new playback_listener(); 12 | m_message_listener = new message_listener(); 13 | } 14 | void on_quit() { 15 | // free memory of playback listener 16 | delete m_playback_listener; 17 | delete m_message_listener; 18 | } 19 | 20 | private: 21 | playback_listener* m_playback_listener; 22 | message_listener* m_message_listener; 23 | 24 | }; 25 | 26 | static initquit_factory_t g_initquit_factory; 27 | -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/input_listener.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "input_listener.h" 4 | #include "media_controls.h" 5 | 6 | void input_listener::on_button_pressed(Windows::Media::SystemMediaTransportControls^ sender, Windows::Media::SystemMediaTransportControlsButtonPressedEventArgs^ args) { 7 | // create a notification object 8 | service_ptr_t notification_ptr = new service_impl_t(args->Button); 9 | // run the code on main thread as playback_control only works from the main thread 10 | static_api_ptr_t()->add_callback(notification_ptr.get_ptr()); 11 | } 12 | 13 | void input_listener::media_notification::callback_run() { 14 | switch (m_button) { 15 | case Windows::Media::SystemMediaTransportControlsButton::Play: 16 | m_playback_control->play_or_unpause(); 17 | 18 | break; 19 | case Windows::Media::SystemMediaTransportControlsButton::Pause: 20 | m_playback_control->pause(true); 21 | 22 | break; 23 | case Windows::Media::SystemMediaTransportControlsButton::Stop: 24 | m_playback_control->stop(); 25 | 26 | break; 27 | case Windows::Media::SystemMediaTransportControlsButton::Next: 28 | media_controls::get().set_status(Windows::Media::MediaPlaybackStatus::Changing); 29 | m_playback_control->next(); 30 | 31 | break; 32 | case Windows::Media::SystemMediaTransportControlsButton::Previous: 33 | media_controls::get().set_status(Windows::Media::MediaPlaybackStatus::Changing); 34 | m_playback_control->previous(); 35 | 36 | break; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/input_listener.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | ref class input_listener sealed { 4 | public: 5 | void on_button_pressed(Windows::Media::SystemMediaTransportControls^ sender, Windows::Media::SystemMediaTransportControlsButtonPressedEventArgs^ args); 6 | 7 | private: 8 | class media_notification : public main_thread_callback { 9 | public: 10 | inline media_notification(Windows::Media::SystemMediaTransportControlsButton button) : m_button(button) { } 11 | void callback_run() override; 12 | 13 | private: 14 | const static_api_ptr_t m_playback_control; 15 | const Windows::Media::SystemMediaTransportControlsButton m_button; 16 | 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/main.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | DECLARE_COMPONENT_VERSION("Windows 10 Media Controls","1.3","Adds the ability for foobar2000 to interact with the Windows 10 media control overlay."); 4 | VALIDATE_COMPONENT_FILENAME("foo_mediacontrol.dll"); 5 | -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/message_listener.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "message_listener.h" 4 | #include "media_controls.h" 5 | #include "preferences.h" 6 | 7 | // required to disable media key duplication when the media controls are enabled 8 | bool message_listener::pretranslate_message(MSG* p_msg) { 9 | if (!preferences::get_setting_passthrough() && media_controls::get().get_enabled()) { 10 | if (p_msg->wParam == HSHELL_APPCOMMAND) { 11 | switch (HIWORD(p_msg->lParam)) { 12 | case APPCOMMAND_MEDIA_PLAY: 13 | case APPCOMMAND_MEDIA_PAUSE: 14 | case APPCOMMAND_MEDIA_PLAY_PAUSE: 15 | case APPCOMMAND_MEDIA_STOP: 16 | case APPCOMMAND_MEDIA_PREVIOUSTRACK: 17 | case APPCOMMAND_MEDIA_NEXTTRACK: 18 | return true; 19 | 20 | } 21 | } 22 | } 23 | 24 | return false; 25 | } 26 | -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/message_listener.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SHELLHOOK_NAME L"SHELLHOOK" 4 | 5 | class message_listener : private message_filter_impl_base { 6 | public: 7 | // doesn't actually register a message-receiving window since foobar has already registered it; just receives the message's ID 8 | message_listener(t_uint32 message = RegisterWindowMessage(SHELLHOOK_NAME)) : message_filter_impl_base(message, message) { } 9 | bool pretranslate_message(MSG* p_msg); 10 | 11 | }; 12 | 13 | #undef SHELLHOOK_NAME 14 | -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/playback_listener.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class playback_listener : private play_callback_impl_base { 4 | private: 5 | void on_playback_starting(play_control::t_track_command p_command, bool p_paused); 6 | void on_playback_new_track(metadb_handle_ptr p_track); 7 | void on_playback_stop(play_control::t_stop_reason p_reason); 8 | void on_playback_pause(bool p_state); 9 | void on_playback_seek(double p_time); 10 | 11 | void reset_playback(double duration, bool playing); 12 | bool has_duration() const; 13 | double get_duration() const; 14 | void set_position(double position); 15 | double get_live_position() const; 16 | double get_live_position(std::chrono::milliseconds when) const; 17 | void freeze_live_position(); 18 | void set_playing(bool playing); 19 | bool is_playing() const; 20 | 21 | Windows::Media::SystemMediaTransportControlsTimelineProperties^ current_timeline_properties() const; 22 | void update_timeline_properties(double position) const; 23 | void update_timeline_properties() const; 24 | 25 | double m_last_duration{ -1.0 }; 26 | double m_position{ 0.0 }; 27 | std::chrono::milliseconds m_position_timestamp{ std::chrono::milliseconds::zero() }; 28 | bool m_playing{ false }; 29 | }; 30 | -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/preferences.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "preferences.h" 4 | 5 | const GUID preferences::guid_cfg_setting_passthrough = { 0x7d8a2294, 0x36d0, 0x4ee9, {0xaa, 0x71, 0x36, 0x70, 0x5f, 0x0f, 0x43, 0xac } }; 6 | const GUID preferences::guid_advconfig_branch = { 0x1260bbfa, 0x0806, 0x434e, {0x91, 0x7c, 0xc8, 0x91, 0x89, 0xd3, 0x9c, 0x54 } }; 7 | 8 | cfg_bool preferences::cfg_setting_passthrough(guid_cfg_setting_passthrough, false); 9 | advconfig_branch_factory preferences::g_advconfig_branch(PREFERENCES_SECTION_NAME, guid_advconfig_branch, advconfig_branch::guid_branch_tools, 0); 10 | 11 | BOOL preferences::on_init(CWindow, LPARAM) { 12 | uButton_SetCheck(this->m_hWnd, IDC_PREFERENCES_PASSTHROUGH, cfg_setting_passthrough); 13 | 14 | return FALSE; 15 | } 16 | 17 | void preferences::on_edit(UINT, int, CWindow) { 18 | on_changed(); 19 | } 20 | 21 | void preferences::on_changed() { 22 | m_callback->on_state_changed(); 23 | } 24 | 25 | t_uint32 preferences::get_state() { 26 | t_uint32 state = preferences_state::resettable; 27 | if (uButton_GetCheck(this->m_hWnd, IDC_PREFERENCES_PASSTHROUGH) != cfg_setting_passthrough) { 28 | state |= preferences_state::changed; 29 | } 30 | 31 | return state; 32 | } 33 | 34 | void preferences::apply() { 35 | cfg_setting_passthrough = uButton_GetCheck(this->m_hWnd, IDC_PREFERENCES_PASSTHROUGH); 36 | 37 | on_changed(); 38 | } 39 | 40 | void preferences::reset() { 41 | cfg_setting_passthrough = false; 42 | 43 | on_changed(); 44 | } 45 | 46 | static preferences_page_factory_t g_preferences_page_factory; 47 | -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/preferences.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "resource.h" 4 | 5 | #define PREFERENCES_SECTION_NAME "Windows 10 Media Controls" 6 | 7 | class preferences : public CDialogImpl, public preferences_page_instance { 8 | public: 9 | preferences(preferences_page_callback::ptr callback) : m_callback(callback) {} 10 | 11 | enum { IDD = IDD_PREFERENCES }; 12 | 13 | BEGIN_MSG_MAP(CPreferences) 14 | MSG_WM_INITDIALOG(on_init) 15 | COMMAND_HANDLER_EX(IDC_PREFERENCES_PASSTHROUGH, BN_CLICKED, on_edit) 16 | END_MSG_MAP() 17 | 18 | t_uint32 get_state(); 19 | void apply(); 20 | void reset(); 21 | 22 | inline static bool get_setting_passthrough() { return cfg_setting_passthrough; } 23 | 24 | private: 25 | BOOL on_init(CWindow, LPARAM); 26 | void on_edit(UINT, int, CWindow); 27 | void on_changed(); 28 | 29 | preferences_page_callback::ptr m_callback; 30 | 31 | static const GUID guid_cfg_setting_passthrough; 32 | static const GUID guid_advconfig_branch; 33 | 34 | static cfg_bool cfg_setting_passthrough; 35 | 36 | static advconfig_branch_factory g_advconfig_branch; 37 | }; 38 | 39 | class preferences_page_custom_impl : public preferences_page_impl { 40 | public: 41 | const char * get_name() { return PREFERENCES_SECTION_NAME; } 42 | GUID get_guid() { 43 | static const GUID guid = { 0x779304fc, 0x27da, 0x4bad,{ 0xaf, 0x72, 0x8c, 0x4b, 0xeb, 0x2c, 0xd4, 0xac } }; 44 | return guid; 45 | } 46 | GUID get_parent_guid() { return guid_tools; } 47 | 48 | }; 49 | -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungive/foo_mediacontrol/d07055f5147fcd80277d91d2a306e9e3bacd024e/foobar2000/foo_mediacontrol/resource.h -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/stdafx.h: -------------------------------------------------------------------------------- 1 | #define NOMINMAX 2 | 3 | #include 4 | // Fix: 'ACO_AUTOAPPEND': undeclared identifier and more 5 | #include 6 | #include 7 | 8 | #include "../ATLHelpers/ATLHelpers.h" 9 | -------------------------------------------------------------------------------- /foobar2000/foo_mediacontrol/util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stdafx.h" 4 | 5 | namespace util { 6 | inline wchar_t* utf8_to_wide(const char* src) { 7 | t_size in_size; 8 | t_size out_size; 9 | 10 | in_size = strlen(src); 11 | out_size = pfc::stringcvt::estimate_utf8_to_wide(src, in_size); 12 | wchar_t* genres = new wchar_t[out_size]; 13 | pfc::stringcvt::convert_utf8_to_wide(genres, out_size, src, in_size); 14 | 15 | return genres; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/CFObject.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | using pfc::CFObject; 4 | 5 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/NSAttributedString+ppaddons.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NSAttributedString (ppaddons) 4 | + (NSAttributedString*) attributedStringWithImage: (NSImage*) img; 5 | + (NSAttributedString*) attributedStringWithImageNamed: (NSString*) name; 6 | + (NSAttributedString*) attributedStringWithImageNamed:(NSString *)name size: (NSSize) size; 7 | + (NSAttributedString*) attributedStringWithImageNamed:(NSString *)name squareSize: (CGFloat) size; 8 | + (NSAttributedString*) hyperlinkFromString:(NSString*)inString withURL:(NSURL*)aURL; 9 | + (NSAttributedString*) string: (NSString*) text withFont: (NSFont*) font; 10 | @end 11 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/NSButton+checked.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NSButton (checked) 4 | 5 | @property BOOL checked; 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/NSButton+checked.m: -------------------------------------------------------------------------------- 1 | #import "NSButton+checked.h" 2 | 3 | @implementation NSButton (checked) 4 | 5 | - (BOOL)checked { 6 | return self.state == NSOnState; 7 | } 8 | 9 | - (void)setChecked:(BOOL)checked { 10 | self.state = checked ? NSOnState : NSOffState; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/NSComboBox+fb2k.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import 4 | #import 5 | 6 | @interface NSComboBox (fb2k) 7 | - (void) setupHistory: (cfg_dropdown_history&) var; 8 | - (void) addToHistory: (cfg_dropdown_history&) var; 9 | @end 10 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/NSComboBox+fb2k.mm: -------------------------------------------------------------------------------- 1 | #import "NSComboBox+fb2k.h" 2 | #import "NSMenu+ppaddons.h" 3 | 4 | @implementation NSComboBox (fb2k) 5 | - (void) setupHistory: (cfg_dropdown_history&) var { 6 | [self removeAllItems]; 7 | pfc::string8 temp; var.get_state( temp ); 8 | NSString * str = [NSString stringWithUTF8String: temp.c_str()]; 9 | if ( str.length == 0 ) return; 10 | NSArray * arr = [str componentsSeparatedByCharactersInSet: [NSCharacterSet newlineCharacterSet]]; 11 | if ( arr.count == 0 ) return; 12 | for( NSString * str in arr ) { 13 | if ( str.length > 0 ) [self addItemWithObjectValue: str]; 14 | } 15 | self.stringValue = arr.firstObject; 16 | 17 | [self.menu addSeparator]; 18 | } 19 | 20 | - (void)addToHistory:(cfg_dropdown_history &)var { 21 | NSString * str = self.stringValue; 22 | if ( str.length > 0 ) var.add_item( str.UTF8String ); 23 | } 24 | @end 25 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/NSEvent+ppstuff.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface NSEvent (ppstuff) 6 | 7 | @property (readonly) BOOL isKeyDown; 8 | @property (readonly) BOOL isCmdKeyDown; 9 | @property (readonly) BOOL isShiftKeyDown; 10 | @property (readonly) NSEventModifierFlags modifierFlagsDI; 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/NSEvent+ppstuff.m: -------------------------------------------------------------------------------- 1 | #import "NSEvent+ppstuff.h" 2 | 3 | @implementation NSEvent (ppstuff) 4 | 5 | - (BOOL)isKeyDown { 6 | return self.type == NSEventTypeKeyDown; 7 | } 8 | - (BOOL)isCmdKeyDown { 9 | return self.isKeyDown && self.modifierFlagsDI == NSEventModifierFlagCommand; 10 | } 11 | - (BOOL)isShiftKeyDown { 12 | return self.isKeyDown && self.modifierFlagsDI == NSEventModifierFlagShift; 13 | } 14 | - (NSEventModifierFlags)modifierFlagsDI { 15 | return self.modifierFlags & NSEventModifierFlagDeviceIndependentFlagsMask; 16 | } 17 | @end 18 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/NSMenu+ppaddons.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NSMenu (ppaddons) 4 | 5 | - (NSMenuItem*) addItemWithTitle: (NSString*) title action: (SEL) action target: (id) target; 6 | - (void) addSeparator; 7 | - (NSMenuItem*) addSubMenu: (NSMenu*) menu withTitle: (NSString*) title; 8 | - (void)popUpForView:(NSView *)view; 9 | 10 | - (void) textToSeparators: (NSString*) text; 11 | - (void) textToSeparators; 12 | @end 13 | 14 | @interface NSMenuItem (ppaddons) 15 | 16 | @property BOOL checked; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/NSTextField+grayed.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NSTextField (grayed) 4 | 5 | @property BOOL grayed; 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/NSTextField+grayed.m: -------------------------------------------------------------------------------- 1 | #import "NSTextField+grayed.h" 2 | 3 | @implementation NSTextField (grayed) 4 | 5 | - (void)setGrayed:(BOOL)grayed { 6 | if (grayed) self.textColor = [NSColor disabledControlTextColor]; 7 | else self.textColor = [NSColor labelColor]; 8 | } 9 | 10 | - (BOOL)grayed { 11 | return [self.textColor isEqualTo: [NSColor disabledControlTextColor]]; 12 | } 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/NSView+embed.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NSView (embed) 4 | - (void) embedInView: (NSView*) superview; 5 | - (void) embedInViewV2: (NSView*) superview; // adds autolayout constraints 6 | @end 7 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/NSView+embed.m: -------------------------------------------------------------------------------- 1 | #import "NSView+embed.h" 2 | 3 | @implementation NSView (embed) 4 | 5 | - (void)embedInView:(NSView *)superview { 6 | self.autoresizingMask = NSViewHeightSizable | NSViewWidthSizable; 7 | self.frame = superview.bounds; 8 | [superview addSubview: self]; 9 | } 10 | 11 | - (void)embedInViewV2:(NSView *)superview { 12 | 13 | self.autoresizingMask = 0; 14 | [superview addSubview: self]; 15 | NSMutableArray * constraints = [NSMutableArray arrayWithCapacity: 4]; 16 | static const NSLayoutAttribute params[4] = { NSLayoutAttributeLeft, NSLayoutAttributeRight, NSLayoutAttributeTop, NSLayoutAttributeBottom }; 17 | for( unsigned i = 0; i < 4; ++ i) { 18 | NSLayoutAttribute a = params[i]; 19 | [constraints addObject: [NSLayoutConstraint constraintWithItem: self attribute:a relatedBy:NSLayoutRelationEqual toItem:superview attribute:a multiplier:1 constant:0]]; 20 | } 21 | 22 | [superview addConstraints: constraints]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/NSView+ppsubviews.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NSView (ppsubviews) 4 | - (NSView*) recurFindSubViewOfClass: (Class) cls identifier: (NSString*) identifier; 5 | - (NSView*) findSubViewOfClass: (Class) cls identifier: (NSString*) identifier; 6 | - (NSView*) findSubViewOfClass: (Class) cls; 7 | - (NSButton*) findButton; 8 | - (NSTextView*) findTextView; 9 | - (NSTextField*) findTextField; 10 | - (NSImageView*) findImageView; 11 | @end 12 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/fb2k-platform.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #import 4 | #import 5 | 6 | namespace fb2k { 7 | NSString * strToPlatform( const char * ); 8 | NSString * strToPlatform( const char * , size_t ); 9 | NSString * strToPlatform( stringRef ); 10 | stringRef strFromPlatform( NSString * ); 11 | 12 | stringRef urlFromPlatform( id url /* can be NSString or NSURL */ ); 13 | 14 | typedef NSImage* platformImage_t; 15 | platformImage_t imageToPlatform( fb2k::objRef ); 16 | 17 | 18 | // These two functions do the same, openWebBrowser() was added for compatiblity with fb2k mobile 19 | void openWebBrowser(const char * URL); 20 | void openURL( const char * URL); 21 | } 22 | 23 | namespace pfc { 24 | string8 strFromPlatform(NSString*); 25 | NSString * strToPlatform( const char * ); 26 | NSString * strToPlatform(string8 const&); 27 | string8 strFromPlatform(CFStringRef); 28 | } 29 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/fooDecibelFormatter.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "foobar2000-mac-helpers.h" 4 | 5 | #define fooDecibelFormatter FB2K_OBJC_CLASS(fooDecibelFormatter) 6 | 7 | @interface fooDecibelFormatter : NSFormatter 8 | 9 | @property (nonatomic) NSNumber * minValue; 10 | @property (nonatomic) NSNumber * maxValue; 11 | @property (nonatomic) BOOL showSignAlways; 12 | @end 13 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/fooPreferencesCommon.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | typedef NSViewController fooPreferencesCommon; 5 | 6 | template 7 | class preferences_mac_common : public preferences_page_v4 { 8 | public: 9 | service_ptr instantiate() override { 10 | return fb2k::wrapNSObject( [obj_t new] ); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/fooTimeFormatter.h: -------------------------------------------------------------------------------- 1 | // 2 | // fooTimeFormatter.h 3 | // foo_abx 4 | // 5 | // Created by P on 06/09/2023. 6 | // 7 | 8 | #import 9 | #import "foobar2000-mac-helpers.h" 10 | 11 | #define fooTimeFormatter FB2K_OBJC_CLASS(fooTimeFormatter) 12 | 13 | @interface fooTimeFormatter : NSFormatter 14 | @property (nonatomic) NSNumber * digits; 15 | @end 16 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/fooTimeFormatter.mm: -------------------------------------------------------------------------------- 1 | // 2 | // fooTimeFormatter.m 3 | // foo_abx 4 | // 5 | // Created by P on 06/09/2023. 6 | // 7 | 8 | #import "stdafx.h" 9 | #import "fooTimeFormatter.h" 10 | 11 | @implementation fooTimeFormatter 12 | 13 | - (NSString *)stringForObjectValue:(id)obj { 14 | double v = 0; 15 | if ( [obj respondsToSelector: @selector(doubleValue)]) v = [obj doubleValue]; 16 | else if ( [obj respondsToSelector: @selector(longValue)]) v = [obj longValue]; 17 | else if ( [obj respondsToSelector: @selector(intValue)]) v = [obj intValue]; 18 | 19 | unsigned digits = 3; 20 | if ( _digits ) digits = _digits.unsignedIntValue; 21 | return [NSString stringWithUTF8String: pfc::format_time_ex(v, digits)]; 22 | } 23 | 24 | - (NSString *)editingStringForObjectValue:(id)obj { 25 | return [self stringForObjectValue: obj]; 26 | } 27 | - (BOOL)getObjectValue:(out id _Nullable __autoreleasing *)obj forString:(NSString *)string errorDescription:(out NSString * _Nullable __autoreleasing *)error { 28 | if ( string == nil ) return NO; 29 | try { 30 | double v = pfc::parse_timecode( string.UTF8String ); 31 | *obj = [NSNumber numberWithDouble: v]; 32 | return YES; 33 | } catch(...) { 34 | return NO; 35 | } 36 | } 37 | @end 38 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/fooWindowWithCancel.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "foobar2000-mac-helpers.h" 3 | 4 | #define fooWindowWithCancel FB2K_OBJC_CLASS(fooWindowWithCancel) 5 | 6 | @interface fooWindowWithCancel : NSWindow 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/fooWindowWithCancel.m: -------------------------------------------------------------------------------- 1 | #import "fooWindowWithCancel.h" 2 | 3 | @implementation fooWindowWithCancel 4 | - (void) cancelOperation: (id) sender { 5 | id d = self.delegate; 6 | if ( [d respondsToSelector: @selector(cancelOperation:)]) { 7 | [d cancelOperation: sender]; 8 | } 9 | } 10 | @end 11 | -------------------------------------------------------------------------------- /foobar2000/helpers-mac/foobar2000-mac-helpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Mitigation for Objective-C class name clashes 4 | // Your component must have its own foobar2000-mac-class-suffix.h, with a single line: 5 | // #define FOOBAR2000_MAC_CLASS_SUFFIX _foo_mycomponentname 6 | // This suffixes all common class names with _foo_mycomponentname preventing clashes 7 | 8 | #include "foobar2000-mac-class-suffix.h" 9 | 10 | #ifndef FOOBAR2000_MAC_CLASS_SUFFIX 11 | #error PLEASE DECLARE FOOBAR2000_MAC_CLASS_SUFFIX PROPERLY 12 | #endif 13 | 14 | #define FB2K_OBJC_CLASS(X) _FB2K_OBJC_CONCAT(X, FOOBAR2000_MAC_CLASS_SUFFIX) 15 | #define _FB2K_OBJC_CONCAT(a, b) _FB2K_OBJC_CONCAT_INNER(a, b) 16 | #define _FB2K_OBJC_CONCAT_INNER(a, b) a ## b 17 | -------------------------------------------------------------------------------- /foobar2000/helpers/AutoComplete.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "AutoComplete.h" 3 | #include // CLSID_AutoComplete 4 | #include "../helpers/COM_utils.h" 5 | #include "../helpers/dropdown_helper.h" 6 | #include 7 | 8 | using PP::CEnumString; 9 | 10 | namespace { 11 | class CACList_History : public CEnumString { 12 | public: 13 | CACList_History(cfg_dropdown_history_mt * var) : m_var(var) { Reset(); } 14 | typedef ImplementCOMRefCounter TImpl; 15 | 16 | HRESULT STDMETHODCALLTYPE Reset() { 17 | /*if (core_api::assert_main_thread())*/ { 18 | ResetStrings(); 19 | pfc::string8 state; m_var->get_state(state); 20 | for (const char * walk = state;;) { 21 | const char * next = strchr(walk, cfg_dropdown_history_mt::separator); 22 | t_size len = (next != NULL) ? next - walk : ~0; 23 | AddStringU(walk, len); 24 | if (next == NULL) break; 25 | walk = next + 1; 26 | } 27 | } 28 | return __super::Reset(); 29 | } 30 | 31 | HRESULT STDMETHODCALLTYPE Clone(IEnumString **ppenum) { 32 | *ppenum = new TImpl(*this); return S_OK; 33 | } 34 | 35 | private: 36 | cfg_dropdown_history_mt * const m_var; 37 | }; 38 | } 39 | 40 | HRESULT InitializeDropdownAC(HWND comboBox, cfg_dropdown_history_mt & var, const char * initVal) { 41 | var.on_init(comboBox, initVal); 42 | COMBOBOXINFO ci = {}; ci.cbSize = sizeof(ci); 43 | if (!GetComboBoxInfo(comboBox, &ci)) { 44 | PFC_ASSERT(!"Should not get here - GetComboBoxInfo fail!"); 45 | return E_FAIL; 46 | } 47 | pfc::com_ptr_t acl = new CACList_History::TImpl(&var); 48 | return InitializeSimpleAC(ci.hwndItem, acl.get_ptr(), ACO_AUTOAPPEND|ACO_AUTOSUGGEST); 49 | } 50 | -------------------------------------------------------------------------------- /foobar2000/helpers/AutoComplete.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "dropdown_helper.h" 6 | 7 | HRESULT InitializeDropdownAC(HWND comboBox, cfg_dropdown_history_mt & var, const char * initVal); 8 | -------------------------------------------------------------------------------- /foobar2000/helpers/CDialogResizeHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "WindowPositionUtils.h" 4 | 5 | #include 6 | 7 | template class CDialogResizeHelperTracking : public CDialogResizeHelper { 8 | public: 9 | template CDialogResizeHelperTracking(const TParam (& src)[paramCount],CRect const& minMaxRange, TCfgVar & cfgVar) : CDialogResizeHelper(src, minMaxRange), m_tracker(cfgVar) {} 10 | 11 | BEGIN_MSG_MAP_EX(CDialogResizeHelperST) 12 | CHAIN_MSG_MAP(CDialogResizeHelper) 13 | CHAIN_MSG_MAP_MEMBER(m_tracker) 14 | END_MSG_MAP() 15 | 16 | private: 17 | TTracker m_tracker; 18 | }; 19 | 20 | typedef CDialogResizeHelperTracking CDialogResizeHelperST; 21 | typedef CDialogResizeHelperTracking CDialogResizeHelperPT; 22 | typedef CDialogResizeHelperTracking CDialogResizeHelperST2; 23 | 24 | #define REDRAW_DIALOG_ON_RESIZE() if (uMsg == WM_SIZE) RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN); 25 | -------------------------------------------------------------------------------- /foobar2000/helpers/CModelessDialogMessages.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class CModelessDialogMessages { 5 | public: 6 | static BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult) { 7 | switch (uMsg) { 8 | case WM_INITDIALOG: 9 | modeless_dialog_manager::g_add(hWnd); break; 10 | case WM_DESTROY: 11 | modeless_dialog_manager::g_remove(hWnd); break; 12 | } 13 | return FALSE; 14 | } 15 | }; 16 | 17 | #define FB2K_MODELESS_DIALOG_MESSAGES() CHAIN_MSG_MAP(CModelessDialogMessages) 18 | -------------------------------------------------------------------------------- /foobar2000/helpers/COM_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #include 5 | 6 | #define FB2K_COM_CATCH PP_COM_CATCH 7 | -------------------------------------------------------------------------------- /foobar2000/helpers/CPropVariant.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include -------------------------------------------------------------------------------- /foobar2000/helpers/CTableEditHelper-Legacy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "inplace_edit.h" 3 | #include 4 | 5 | namespace InPlaceEdit { 6 | class CTableEditHelper { 7 | public: 8 | 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); 9 | void TableEdit_Abort(bool p_forwardcontent); 10 | bool TableEdit_IsActive() const {return m_notify.is_valid();} 11 | 12 | virtual bool TableEdit_GetItemText(unsigned p_item, unsigned p_column, pfc::string_base & p_out, unsigned & p_linecount); 13 | virtual void TableEdit_SetItemText(unsigned p_item, unsigned p_column, const char * p_text); 14 | 15 | virtual void TableEdit_Finished() {} 16 | 17 | void on_task_completion(unsigned p_taskid, unsigned p_state); 18 | ~CTableEditHelper(); 19 | protected: 20 | HWND TableEdit_GetListView() const { return m_listview; } 21 | //return false to abort 22 | virtual bool TableEdit_OnEditCompleted(unsigned item, unsigned column, unsigned state) { return true; } 23 | private: 24 | void _Start(); 25 | enum { 26 | KTaskID = 0xc0ffee 27 | }; 28 | HWND m_listview; 29 | unsigned m_item, m_column; 30 | unsigned m_itemcount, m_columncount, m_basecolumn; 31 | unsigned m_flags; 32 | pfc::rcptr_t m_content; 33 | service_ptr_t m_notify; 34 | }; 35 | } -------------------------------------------------------------------------------- /foobar2000/helpers/DarkMode.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | #include "DarkMode.h" 3 | 4 | bool fb2k::isDarkMode() { 5 | auto api = ui_config_manager::tryGet(); 6 | if (api.is_valid()) return api->is_dark_mode(); 7 | else return false; 8 | } 9 | -------------------------------------------------------------------------------- /foobar2000/helpers/DarkMode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _WIN32 4 | 5 | #include 6 | #include 7 | 8 | // fb2k::CDarkModeHooks 9 | // foobar2000 specific helper on top of libPPUI DarkMode::CHooks 10 | // Automatically determines whether dark mode should be on or off 11 | // Keeps track of dark mode preference changes at runtime 12 | // Does nothing if used in foobar2000 older than 2.0 13 | 14 | // IMPORTANT 15 | // See also: SDK/coreDarkMode.h 16 | // Using CCoreDarkMode lets you invoke foobar2000's instance of this code instead of static linking it, resulting in much smaller component binary. 17 | // Using CDarkModeHooks directly is good mainly for debugging or troubleshooting. 18 | 19 | namespace fb2k { 20 | bool isDarkMode(); 21 | 22 | #ifndef CDarkModeHooks 23 | class CDarkModeHooks : public DarkMode::CHooks, private ui_config_callback_impl { 24 | public: 25 | CDarkModeHooks() : CHooks(isDarkMode()) {} 26 | 27 | private: 28 | void ui_fonts_changed() override {} 29 | void ui_colors_changed() override { this->SetDark(isDarkMode()); } 30 | }; 31 | #endif 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /foobar2000/helpers/ProfileCache.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ProfileCache { 4 | inline file::ptr FetchFile(const char * context, const char * name, const char * webURL, t_filetimestamp acceptableAge, abort_callback & abort) { 5 | const double timeoutVal = 5; 6 | 7 | auto path = core_api::pathInProfile( context ); 8 | auto fsLocal = filesystem::get(path); 9 | fsLocal->make_directory(path, abort); 10 | path.add_filename( name ); 11 | 12 | bool fetch = false; 13 | file::ptr fLocal; 14 | 15 | try { 16 | fLocal = fsLocal->openWriteExisting(path, abort, timeoutVal ); 17 | fetch = fLocal->get_timestamp(abort) < filetimestamp_from_system_timer() - acceptableAge; 18 | } catch(exception_io_not_found const &) { 19 | fLocal = fsLocal->openWriteNew(path, abort, timeoutVal); 20 | fetch = true; 21 | } 22 | if (fetch) { 23 | try { 24 | fLocal->resize(0, abort); 25 | file::ptr fRemote; 26 | filesystem::g_open(fRemote, webURL, filesystem::open_mode_read, abort); 27 | file::g_transfer_file(fRemote, fLocal, abort ); 28 | } catch(exception_io const &) { 29 | fLocal.release(); 30 | try { 31 | retryOnSharingViolation(timeoutVal, abort, [&] {fsLocal->remove(path, abort);} ); 32 | } catch(...) {} 33 | throw; 34 | } 35 | fLocal->seek(0, abort); 36 | } 37 | return fLocal; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /foobar2000/helpers/StdAfx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // foobar2000_sdk_helpers.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "StdAfx.h" 6 | 7 | -------------------------------------------------------------------------------- /foobar2000/helpers/StdAfx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #if !defined(AFX_STDAFX_H__6356EC2B_6DD1_4BE8_935C_87ECBA8697E4__INCLUDED_) 7 | #define AFX_STDAFX_H__6356EC2B_6DD1_4BE8_935C_87ECBA8697E4__INCLUDED_ 8 | 9 | #if _MSC_VER > 1000 10 | #pragma once 11 | #endif // _MSC_VER > 1000 12 | 13 | #include "foobar2000+atl.h" 14 | 15 | // TODO: reference additional headers your program requires here 16 | 17 | //{{AFX_INSERT_LOCATION}} 18 | // Microsoft Visual C++ will insert additional declarations immediately before the previous line. 19 | 20 | #endif // !defined(AFX_STDAFX_H__6356EC2B_6DD1_4BE8_935C_87ECBA8697E4__INCLUDED_) 21 | -------------------------------------------------------------------------------- /foobar2000/helpers/VisUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | 3 | #include "VisUtils.h" 4 | 5 | namespace VisUtils { 6 | void PrepareFFTChunk(audio_chunk const & source, audio_chunk & out, double centerOffset) { 7 | const t_uint32 channels = source.get_channel_count(); 8 | const t_uint32 sampleRate = source.get_sample_rate(); 9 | FB2K_DYNAMIC_ASSERT( sampleRate > 0 ); 10 | out.set_channels(channels, source.get_channel_config()); 11 | out.set_sample_rate(sampleRate); 12 | const t_size inSize = source.get_sample_count(); 13 | const t_size fftSize = MatchFFTSize(inSize); 14 | out.set_sample_count(fftSize); 15 | out.set_data_size(fftSize * channels); 16 | if (fftSize >= inSize) { //rare case with *REALLY* small input 17 | pfc::memcpy_t( out.get_data(), source.get_data(), inSize * channels ); 18 | pfc::memset_null_t( out.get_data() + inSize * channels, (fftSize - inSize) * channels ); 19 | } else { //inSize > fftSize, we're using a subset of source chunk for the job, pick a subset around centerOffset. 20 | const double baseOffset = pfc::max_t(0, centerOffset - 0.5 * (double)fftSize / (double)sampleRate); 21 | const t_size baseSample = pfc::min_t( (t_size) audio_math::time_to_samples(baseOffset, sampleRate), inSize - fftSize); 22 | pfc::memcpy_t( out.get_data(), source.get_data() + baseSample * channels, fftSize * channels); 23 | } 24 | } 25 | 26 | bool IsValidFFTSize(t_size p_size) { 27 | return p_size >= 2 && (p_size & (p_size - 1)) == 0; 28 | } 29 | 30 | t_size MatchFFTSize(t_size samples) { 31 | if (samples <= 2) return 2; 32 | t_size mask = 1; 33 | while(!IsValidFFTSize(samples)) { 34 | samples &= ~mask; mask <<= 1; 35 | } 36 | return samples; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /foobar2000/helpers/VisUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace VisUtils { 4 | //! Turns an arbitrary audio_chunk into a valid chunk to run FFT on, with proper sample count etc. 5 | //! @param centerOffset Time offset (in seconds) inside the source chunk to center the output on, in case the FFT window is smaller than input data. 6 | void PrepareFFTChunk(audio_chunk const & source, audio_chunk & out, double centerOffset); 7 | 8 | bool IsValidFFTSize(t_size size); 9 | t_size MatchFFTSize(t_size samples); 10 | }; 11 | -------------------------------------------------------------------------------- /foobar2000/helpers/VolumeMap.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | #include "VolumeMap.h" 3 | 4 | static const double powval = 2.0; 5 | static const double silence = -100.0; 6 | 7 | double VolumeMap::SliderToDB2(double slider) { 8 | double v = SliderToDB(slider); 9 | v = floor(v * 2.0 + 0.5) * 0.5; 10 | return v; 11 | } 12 | 13 | double VolumeMap::SliderToDB(double slider) { 14 | if (slider > 0) { 15 | return pfc::max_t(silence,10.0 * log(slider) / log(powval)); 16 | } else { 17 | return silence; 18 | } 19 | } 20 | double VolumeMap::DBToSlider(double volumeDB) { 21 | return pfc::clip_t(pow(powval,volumeDB / 10.0), 0, 1); 22 | } 23 | -------------------------------------------------------------------------------- /foobar2000/helpers/VolumeMap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace VolumeMap { 4 | double SliderToDB(double slider /*0..1 range*/); 5 | double SliderToDB2(double slider); // rounds to 0.5dB 6 | double DBToSlider(double volumeDB); 7 | } 8 | -------------------------------------------------------------------------------- /foobar2000/helpers/advconfig_impl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // fb2k mobile compat 4 | #include "../SDK/advconfig_impl.h" -------------------------------------------------------------------------------- /foobar2000/helpers/album_art_helpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace album_art_helpers { 4 | bool isJPEG(album_art_data_ptr p); 5 | bool isPNG(album_art_data_ptr p); 6 | bool isWebP(album_art_data_ptr p); 7 | 8 | #ifdef _WIN32 9 | album_art_data_ptr encodeJPEG(album_art_data_ptr source, int quality1to100); 10 | #endif 11 | } -------------------------------------------------------------------------------- /foobar2000/helpers/audio_render_float.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template inline void render_float(float_t* out, const audio_sample* in, size_t count) { 4 | audio_math::convert(in, out, count); 5 | } 6 | 7 | template inline const float_t* render_float(mem_block_container& buffer, const audio_sample* in, size_t count) { 8 | if (sizeof(float_t) == sizeof(audio_sample)) { 9 | return reinterpret_cast(in); 10 | } 11 | buffer.set_size(sizeof(float_t) * count); 12 | float_t* out = reinterpret_cast(buffer.get_ptr()); 13 | render_float(out, in, count); 14 | return out; 15 | } 16 | 17 | inline const void* render_float_by_bps(unsigned bps, mem_block_container& buffer, const audio_sample* in, size_t count) { 18 | switch (bps) { 19 | case 32: 20 | return render_float(buffer, in, count); 21 | case 64: 22 | return render_float(buffer, in, count); 23 | default: 24 | throw exception_io_data(); 25 | } 26 | } -------------------------------------------------------------------------------- /foobar2000/helpers/callback_merit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace fb2k { 7 | // Call global callbacks in correct order 8 | // INTENDED FOR CORE USE ONLY 9 | // Not aware of dynamically registered callbacks, if there are such for the same event type 10 | // Usage: for_each_callback_by_merit< metadb_io_edit_callback > ( [] ( metadb_io_edit_callback::ptr ) { ...} ); 11 | template 12 | void for_each_callback_by_merit(std::function)> f) { 13 | struct rec_t { 14 | class_t* obj; // non-autoptr INTENDED, avoid destruction order bugs on shutdown 15 | fb2k::callback_merit_t merit; 16 | }; 17 | auto generator = [] { 18 | std::vector ret; ret.reserve(64); 19 | for (auto ptr : class_t::enumerate()) { 20 | rec_t r; 21 | r.merit = fb2k::callback_merit_of(ptr); 22 | r.obj = ptr.detach(); 23 | ret.push_back( std::move(r) ); 24 | } 25 | std::sort(ret.begin(), ret.end(), [](rec_t const& e1, rec_t const& e2) { return e1.merit > e2.merit; }); 26 | return ret; 27 | }; 28 | static std::vector cache = generator(); 29 | for (auto& walk : cache) f(walk.obj); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /foobar2000/helpers/cfg_guidlist.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | #include "cfg_guidlist.h" -------------------------------------------------------------------------------- /foobar2000/helpers/cfg_guidlist.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cfg_objList.h" 3 | #include 4 | 5 | class cfg_guidlist : public cfg_objList { 6 | public: 7 | cfg_guidlist(const GUID& p_guid) : cfg_objList(p_guid) {} 8 | 9 | void sort() { 10 | auto v = this->get(); 11 | pfc::sort_t(v, pfc::guid_compare, v.size()); 12 | set(std::move(v)); 13 | } 14 | 15 | bool have_item_bsearch(const GUID & p_item) { 16 | size_t dummy; 17 | return pfc::bsearch_simple_inline_t(*this, size(), p_item, pfc::guid_compare, dummy); 18 | } 19 | bool bsearch(const GUID& item, size_t & idx) { 20 | return pfc::bsearch_simple_inline_t(*this, size(), item, pfc::guid_compare, idx); 21 | } 22 | size_t bsearch(const GUID& item) { 23 | size_t ret = SIZE_MAX; 24 | pfc::bsearch_simple_inline_t(*this, size(), item, pfc::guid_compare, ret); 25 | return ret; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /foobar2000/helpers/cfg_var_import.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | #include "cfg_var_import.h" 3 | 4 | // dummy C++ to get intellisense in cfg_var_import.h 5 | -------------------------------------------------------------------------------- /foobar2000/helpers/create_directory_helper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace create_directory_helper { 7 | typedef std::function charReplace_t; 8 | 9 | void create_path(const char * p_path,abort_callback & p_abort); 10 | 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); 11 | void format_filename(const metadb_handle_ptr & handle,titleformat_hook * p_hook,const char * spec,pfc::string_base & out); 12 | void format_filename(const metadb_handle_ptr & handle,titleformat_hook * p_hook,titleformat_object::ptr spec,pfc::string_base & out); 13 | void format_filename_ex(const metadb_handle_ptr & handle,titleformat_hook * p_hook,titleformat_object::ptr spec,const char * suffix, pfc::string_base & out); 14 | void format_filename_ex(const metadb_handle_ptr & handle, titleformat_hook * p_hook, titleformat_object::ptr spec, const char * suffix, pfc::string_base & out, charReplace_t replace); 15 | 16 | 17 | pfc::string sanitize_formatted_path(pfc::stringp str, bool allowWC = false); 18 | pfc::string sanitize_formatted_path_ex(pfc::stringp str, bool allowWC, charReplace_t replace); 19 | 20 | class titleformat_text_filter_myimpl : public titleformat_text_filter { 21 | public: 22 | charReplace_t m_replace; 23 | void write(const GUID & p_inputType,pfc::string_receiver & p_out,const char * p_data,t_size p_dataLength); 24 | }; 25 | 26 | }; 27 | -------------------------------------------------------------------------------- /foobar2000/helpers/cue_creator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cuesheet_index_list.h" 4 | #include 5 | 6 | namespace cue_creator 7 | { 8 | struct t_entry 9 | { 10 | file_info_impl m_infos; 11 | pfc::string8 m_file, m_fileType, m_flags, m_trackType = "AUDIO"; 12 | unsigned m_track_number; 13 | 14 | bool isTrackAudio() const; 15 | 16 | t_cuesheet_index_list m_index_list; 17 | 18 | void set_simple_index(double p_time); 19 | void set_index01(double index0, double index1); 20 | }; 21 | 22 | typedef pfc::chain_list_v2_t t_entry_list; 23 | 24 | void create(pfc::string_formatter & p_out,const t_entry_list & p_list); 25 | pfc::string_formatter create(const t_entry_list& p_list); 26 | }; -------------------------------------------------------------------------------- /foobar2000/helpers/cuesheet_index_list.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | unsigned cuesheet_parse_index_time_ticks_e(const char * p_string,t_size p_length); 4 | double cuesheet_parse_index_time_e(const char * p_string,t_size p_length); 5 | 6 | class cuesheet_format_index_time 7 | { 8 | public: 9 | cuesheet_format_index_time(double p_time); 10 | inline operator const char*() const {return m_buffer;} 11 | private: 12 | pfc::string_formatter m_buffer; 13 | }; 14 | 15 | 16 | struct t_cuesheet_index_list 17 | { 18 | enum {count = 100}; 19 | t_cuesheet_index_list() {reset();} 20 | void reset() {for(unsigned n=0;n 6 | 7 | // Legacy class referenced by old code 8 | // Do not use in new code, use libPPUI instead 9 | class dialog_resize_helper : public CDialogResizeHelperCompat 10 | { 11 | pfc::array_t rects; 12 | RECT orig_client; 13 | HWND parent; 14 | HWND sizegrip; 15 | unsigned min_x,min_y,max_x,max_y; 16 | 17 | pfc::array_t m_table; 18 | 19 | void set_parent(HWND wnd); 20 | void reset(); 21 | void on_wm_size(); 22 | public: 23 | inline void set_min_size(unsigned x,unsigned y) {min_x = x; min_y = y;} 24 | inline void set_max_size(unsigned x,unsigned y) {max_x = x; max_y = y;} 25 | void add_sizegrip(); 26 | 27 | //the old way 28 | bool process_message(HWND wnd,UINT msg,WPARAM wp,LPARAM lp); 29 | 30 | //ATL-compatible 31 | BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult); 32 | 33 | dialog_resize_helper(const param * src,unsigned count,unsigned p_min_x,unsigned p_min_y,unsigned p_max_x,unsigned p_max_y); 34 | 35 | ~dialog_resize_helper(); 36 | 37 | PFC_CLASS_NOT_COPYABLE_EX(dialog_resize_helper); 38 | }; 39 | 40 | #endif // FOOBAR2000_DESKTOP_WINDOWS -------------------------------------------------------------------------------- /foobar2000/helpers/dynamic_bitrate_helper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class dynamic_bitrate_helper 4 | { 5 | public: 6 | dynamic_bitrate_helper(); 7 | void on_frame(double p_duration,t_size p_bits); 8 | bool on_update(file_info & p_out, double & p_timestamp_delta); 9 | void reset(); 10 | private: 11 | void init(); 12 | double m_last_duration; 13 | t_size m_update_bits; 14 | double m_update_time; 15 | double m_update_interval; 16 | bool m_inited, m_enabled; 17 | }; -------------------------------------------------------------------------------- /foobar2000/helpers/fb2k_wfx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct fb2k_wfx { 4 | audio_chunk::spec_t spec; 5 | bool bFloat; 6 | unsigned bps; 7 | void parse( const WAVEFORMATEX * wfx ) { 8 | spec.sampleRate = wfx->nSamplesPerSec; 9 | spec.chanCount = wfx->nChannels; 10 | spec.chanMask = audio_chunk::g_guess_channel_config( spec.chanCount ); 11 | bps = wfx->wBitsPerSample; 12 | switch( wfx->wFormatTag ) { 13 | case WAVE_FORMAT_PCM: 14 | bFloat = false; break; 15 | case WAVE_FORMAT_IEEE_FLOAT: 16 | bFloat = true; break; 17 | case WAVE_FORMAT_EXTENSIBLE: 18 | { 19 | auto wfxe = (const WAVEFORMATEXTENSIBLE*) wfx; 20 | auto newMask = audio_chunk::g_channel_config_from_wfx( wfxe->dwChannelMask ); 21 | if ( audio_chunk::g_count_channels(newMask) == spec.chanCount ) { 22 | spec.chanMask = newMask; 23 | } 24 | if ( wfxe->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT ) { 25 | bFloat = true; 26 | } else if ( wfxe->SubFormat == KSDATAFORMAT_SUBTYPE_PCM ) { 27 | bFloat = false; 28 | } else { 29 | throw exception_io_data(); 30 | } 31 | } 32 | break; 33 | default: 34 | throw exception_io_data(); 35 | } 36 | 37 | } 38 | }; -------------------------------------------------------------------------------- /foobar2000/helpers/fileReadAhead.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //! Creates a file with a background thread reading ahead of the current position 4 | file::ptr fileCreateReadAhead(file::ptr chain, size_t readAheadBytes, abort_callback & aborter ); 5 | -------------------------------------------------------------------------------- /foobar2000/helpers/file_cached.h: -------------------------------------------------------------------------------- 1 | // obsolete, moved to SDK -------------------------------------------------------------------------------- /foobar2000/helpers/file_info_const_impl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../SDK/file_info_const_impl.h" -------------------------------------------------------------------------------- /foobar2000/helpers/file_list_helper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace file_list_helper 4 | { 5 | typedef pfc::list_base_const_t base_t; 6 | 7 | //list guaranteed to be sorted by metadb::path_compare 8 | class file_list_from_metadb_handle_list : public base_t { 9 | public: 10 | file_list_from_metadb_handle_list() {} 11 | file_list_from_metadb_handle_list( metadb_handle_list_cref lst, bool bDisplayPaths = false ); 12 | 13 | static t_size g_get_count(const list_base_const_t & p_list, t_size max = SIZE_MAX); 14 | 15 | void init_from_list(const list_base_const_t & p_list); 16 | void init_from_list_display(const list_base_const_t & p_list); 17 | 18 | t_size get_count() const; 19 | void get_item_ex(const char * & p_out,t_size n) const; 20 | 21 | ~file_list_from_metadb_handle_list(); 22 | 23 | private: 24 | void _add(const char * p_what); 25 | pfc::ptr_list_t m_data; 26 | }; 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /foobar2000/helpers/file_move_helper.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | 3 | #include "file_move_helper.h" 4 | #include 5 | 6 | bool file_move_helper::g_on_deleted(const pfc::list_base_const_t & p_files) 7 | { 8 | file_operation_callback::g_on_files_deleted(p_files); 9 | return true; 10 | } 11 | 12 | t_size file_move_helper::g_filter_dead_files_sorted_make_mask(pfc::list_base_t & p_data,const pfc::list_base_const_t & p_dead,bit_array_var & p_mask) 13 | { 14 | t_size n, m = p_data.get_count(); 15 | t_size found = 0; 16 | for(n=0;nget_path(),dummy); 20 | if (dead) found++; 21 | p_mask.set(n,dead); 22 | } 23 | return found; 24 | } 25 | 26 | t_size file_move_helper::g_filter_dead_files_sorted(pfc::list_base_t & p_data,const pfc::list_base_const_t & p_dead) 27 | { 28 | pfc::bit_array_bittable mask(p_data.get_count()); 29 | t_size found = g_filter_dead_files_sorted_make_mask(p_data,p_dead,mask); 30 | if (found > 0) p_data.remove_mask(mask); 31 | return found; 32 | } 33 | 34 | t_size file_move_helper::g_filter_dead_files(pfc::list_base_t & p_data,const pfc::list_base_const_t & p_dead) 35 | { 36 | pfc::ptr_list_t temp; 37 | temp.add_items(p_dead); 38 | temp.sort_t(metadb::path_compare); 39 | return g_filter_dead_files_sorted(p_data,temp); 40 | } 41 | 42 | -------------------------------------------------------------------------------- /foobar2000/helpers/file_move_helper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class file_move_helper { 4 | public: 5 | static bool g_on_deleted(const pfc::list_base_const_t & p_files); 6 | 7 | static t_size g_filter_dead_files_sorted_make_mask(pfc::list_base_t & p_data,const pfc::list_base_const_t & p_dead,bit_array_var & p_mask); 8 | static t_size g_filter_dead_files_sorted(pfc::list_base_t & p_data,const pfc::list_base_const_t & p_dead); 9 | static t_size g_filter_dead_files(pfc::list_base_t & p_data,const pfc::list_base_const_t & p_dead); 10 | }; 11 | -------------------------------------------------------------------------------- /foobar2000/helpers/file_streamstub.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //! Stub implementation of file object, no file content, only info. 4 | class file_streamstub : public file_readonly { 5 | public: 6 | t_size read(void*, t_size, abort_callback&) override { return 0; } 7 | t_filesize get_size(abort_callback&) override { return filesize_invalid; } 8 | t_filesize get_position(abort_callback&) override { return 0; } 9 | bool get_content_type(pfc::string_base& out) override { 10 | if (m_contentType.length() > 0) { out = m_contentType; return true; } else return false; 11 | } 12 | bool is_remote() override { return m_remote; } 13 | void reopen(abort_callback&) override {} 14 | void seek(t_filesize, abort_callback&) override { throw exception_io_object_not_seekable(); } 15 | bool can_seek() override { return false; } 16 | 17 | pfc::string8 m_contentType; 18 | bool m_remote = true; 19 | }; 20 | -------------------------------------------------------------------------------- /foobar2000/helpers/filetimetools.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | 3 | #include "filetimetools.h" 4 | 5 | #include 6 | 7 | // Stub - functionality moved to PFC 8 | 9 | namespace foobar2000_io { 10 | t_filetimestamp filetimestamp_from_string(const char* date) { 11 | return pfc::filetimestamp_from_string( date ); 12 | } 13 | t_filetimestamp filetimestamp_from_string_utc(const char* date) { 14 | return pfc::filetimestamp_from_string_utc( date ); 15 | } 16 | 17 | pfc::string_formatter format_filetimestamp(t_filetimestamp p_timestamp) { 18 | return pfc::format_filetimestamp( p_timestamp ); 19 | } 20 | 21 | pfc::string_formatter format_filetimestamp_utc(t_filetimestamp p_timestamp) { 22 | return pfc::format_filetimestamp_utc( p_timestamp ); 23 | } 24 | 25 | pfc::string_formatter format_filetimestamp_ms(t_filetimestamp p_timestamp) { 26 | return pfc::format_filetimestamp_ms( p_timestamp ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /foobar2000/helpers/filetimetools.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace foobar2000_io { 4 | t_filetimestamp filetimestamp_from_string(const char * date); 5 | t_filetimestamp filetimestamp_from_string_utc(const char* date); 6 | 7 | //! Warning: this formats according to system timezone settings, created strings should be used for display only, never for storage. 8 | pfc::string_formatter format_filetimestamp(t_filetimestamp p_timestamp); 9 | //! UTC timestamp 10 | pfc::string_formatter format_filetimestamp_utc(t_filetimestamp p_timestamp); 11 | //! Local timestamp with milliseconds 12 | pfc::string_formatter format_filetimestamp_ms(t_filetimestamp p_timestamp); 13 | } 14 | -------------------------------------------------------------------------------- /foobar2000/helpers/foobar2000+atl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "foobar2000-lite+atl.h" 3 | #include -------------------------------------------------------------------------------- /foobar2000/helpers/foobar2000-lite+atl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../SDK/foobar2000-winver.h" 4 | 5 | #ifdef _WIN32 6 | #define _SECURE_ATL 1 7 | #endif 8 | 9 | #include "../SDK/foobar2000-lite.h" 10 | 11 | #ifdef _WIN32 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #endif 21 | 22 | #pragma once 23 | -------------------------------------------------------------------------------- /foobar2000/helpers/fullFileBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class fullFileBuffer { 4 | public: 5 | fullFileBuffer() { 6 | //hMutex = CreateMutex(NULL, FALSE, pfc::stringcvt::string_os_from_utf8(pfc::string_formatter() << "{3ABC4D98-2510-431C-A720-26BEB45F0278}-" << (uint32_t) GetCurrentProcessId())); 7 | } 8 | ~fullFileBuffer() { 9 | //CloseHandle(hMutex); 10 | } 11 | file::ptr open(const char * path, abort_callback & abort, file::ptr hint, t_filesize sizeMax = 1024 * 1024 * 256); 12 | 13 | private: 14 | fullFileBuffer(const fullFileBuffer&); 15 | void operator=(const fullFileBuffer&); 16 | 17 | //HANDLE hMutex; 18 | }; 19 | -------------------------------------------------------------------------------- /foobar2000/helpers/helpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // #pragma message("Avoid using this header. #include individual ones instead.") 3 | 4 | #include "duration_counter.h" 5 | #include "input_helpers.h" 6 | #include "create_directory_helper.h" 7 | #include "dialog_resize_helper.h" 8 | #include "dropdown_helper.h" 9 | #include "window_placement_helper.h" 10 | #include "win32_dialog.h" 11 | #include "cuesheet_index_list.h" 12 | #include "cue_creator.h" 13 | #include "cue_parser.h" 14 | #include "text_file_loader.h" 15 | #include "file_list_helper.h" 16 | #include "stream_buffer_helper.h" 17 | #include "file_info_const_impl.h" 18 | #include "dynamic_bitrate_helper.h" 19 | #include "cfg_guidlist.h" 20 | #include "file_move_helper.h" 21 | #include "file_cached.h" 22 | #include "seekabilizer.h" 23 | #include "bitreader_helper.h" 24 | #include "mp3_utils.h" 25 | #include "win32_misc.h" 26 | #include "fb2k_threads.h" 27 | #include "COM_utils.h" 28 | #include "metadb_io_hintlist.h" 29 | #include "meta_table_builder.h" 30 | #include "icon_remapping_wildcard.h" 31 | #include "CallForwarder.h" 32 | #include "playlist_position_reference_tracker.h" 33 | #include "ThreadUtils.h" 34 | #include "ProcessUtils.h" 35 | #include "VisUtils.h" 36 | #include "filetimetools.h" 37 | #include "ProfileCache.h" 38 | #include "file_win32_wrapper.h" 39 | #include "fullFileBuffer.h" 40 | #include "writer_wav.h" 41 | #include "readers.h" -------------------------------------------------------------------------------- /foobar2000/helpers/icon_remapping_wildcard.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class icon_remapping_wildcard_impl : public icon_remapping { 4 | public: 5 | icon_remapping_wildcard_impl(const char * p_pattern,const char * p_iconname) : m_pattern(p_pattern), m_iconname(p_iconname) {} 6 | bool query(const char * p_extension,pfc::string_base & p_iconname) { 7 | if (wildcard_helper::test(p_extension,m_pattern,true)) { 8 | p_iconname = m_iconname; return true; 9 | } else { 10 | return false; 11 | } 12 | } 13 | private: 14 | pfc::string8 m_pattern,m_iconname; 15 | }; 16 | -------------------------------------------------------------------------------- /foobar2000/helpers/image_load_save.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace fb2k { 4 | bool imageLoadDialog( pfc::string_base & outFN, HWND wndParent, const char * initDir ); 5 | 6 | album_art_data::ptr imageLoadDialog( HWND wndParent, const char * initDir ); 7 | 8 | //! bAllowAsync: run file writing offthread. In such case the caller will not be made aware if writing failed. \n 9 | //! Error popup is shown if actual file writing fails. 10 | bool imageSaveDialog(album_art_data_ptr content, HWND wndParent, const char * initDir , bool bAllowAsync = true ); 11 | 12 | album_art_data::ptr readPictureFile( const char * path, abort_callback & a); 13 | } -------------------------------------------------------------------------------- /foobar2000/helpers/inplace_edit.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "inplace_edit.h" 3 | 4 | // Functionality moved to libPPUI 5 | 6 | namespace InPlaceEdit { 7 | static reply_t wrapCN( completion_notify::ptr cn ) { 8 | return [cn](unsigned code) { cn->on_completion(code); }; 9 | } 10 | HWND Start(HWND p_parentwnd, const RECT & p_rect, bool p_multiline, pfc::rcptr_t p_content, completion_notify_ptr p_notify) { 11 | return Start(p_parentwnd, p_rect, p_multiline, p_content, wrapCN(p_notify) ); 12 | } 13 | 14 | HWND StartEx(HWND p_parentwnd, const RECT & p_rect, unsigned p_flags, pfc::rcptr_t p_content, completion_notify_ptr p_notify, IUnknown * ACData, DWORD ACOpts ) { 15 | return StartEx(p_parentwnd, p_rect, p_flags, p_content, wrapCN(p_notify), ACData, ACOpts ); 16 | } 17 | 18 | void Start_FromListView(HWND p_listview, unsigned p_item, unsigned p_subitem, unsigned p_linecount, pfc::rcptr_t p_content, completion_notify_ptr p_notify) { 19 | Start_FromListView(p_listview,p_item, p_subitem, p_linecount, p_content, wrapCN(p_notify) ); 20 | } 21 | void Start_FromListViewEx(HWND p_listview, unsigned p_item, unsigned p_subitem, unsigned p_linecount, unsigned p_flags, pfc::rcptr_t p_content, completion_notify_ptr p_notify) { 22 | Start_FromListViewEx(p_listview, p_item, p_subitem, p_linecount, p_flags, p_content, wrapCN(p_notify) ); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /foobar2000/helpers/inplace_edit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace InPlaceEdit { 6 | 7 | HWND Start(HWND p_parentwnd,const RECT & p_rect,bool p_multiline,pfc::rcptr_t p_content,completion_notify_ptr p_notify); 8 | 9 | HWND StartEx(HWND p_parentwnd,const RECT & p_rect,unsigned p_flags,pfc::rcptr_t p_content,completion_notify_ptr p_notify, IUnknown * ACData = NULL, DWORD ACOpts = 0); 10 | 11 | void Start_FromListView(HWND p_listview,unsigned p_item,unsigned p_subitem,unsigned p_linecount,pfc::rcptr_t p_content,completion_notify_ptr p_notify); 12 | void Start_FromListViewEx(HWND p_listview,unsigned p_item,unsigned p_subitem,unsigned p_linecount,unsigned p_flags,pfc::rcptr_t p_content,completion_notify_ptr p_notify); 13 | } 14 | -------------------------------------------------------------------------------- /foobar2000/helpers/input_helper_cue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "input_helpers.h" 4 | 5 | 6 | class input_helper_cue { 7 | public: 8 | void open(service_ptr_t p_filehint,const playable_location & p_location,unsigned p_flags,abort_callback & p_abort,double p_start,double p_length, bool binary = false); 9 | static void get_info_binary( const char * path, file_info & out, abort_callback & abort ); 10 | 11 | void close(); 12 | bool is_open(); 13 | bool run(audio_chunk & p_chunk,abort_callback & p_abort); 14 | bool run_raw(audio_chunk & p_chunk, mem_block_container & p_raw, abort_callback & p_abort); 15 | void seek(double seconds,abort_callback & p_abort); 16 | bool can_seek(); 17 | void on_idle(abort_callback & p_abort); 18 | bool get_dynamic_info(file_info & p_out,double & p_timestamp_delta); 19 | bool get_dynamic_info_track(file_info & p_out,double & p_timestamp_delta); 20 | void set_logger(event_logger::ptr ptr) {m_input.set_logger(ptr);} 21 | 22 | const char * get_path() const; 23 | 24 | void get_info(t_uint32 p_subsong,file_info & p_info,abort_callback & p_abort); 25 | 26 | private: 27 | bool _run(audio_chunk & p_chunk, mem_block_container * p_raw, abort_callback & p_abort); 28 | bool _m_input_run(audio_chunk & p_chunk, mem_block_container * p_raw, abort_callback & p_abort); 29 | input_helper m_input; 30 | double m_start,m_length,m_position; 31 | bool m_dynamic_info_trigger,m_dynamic_info_track_trigger; 32 | }; 33 | -------------------------------------------------------------------------------- /foobar2000/helpers/input_logging.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | class input_logging : public input_stubs { 5 | public: 6 | input_logging() { 7 | set_logger(nullptr); 8 | } 9 | 10 | event_logger_recorder::ptr log_record( std::function f ) { 11 | auto rec = event_logger_recorder::create(); 12 | { 13 | pfc::vartoggle_t< event_logger::ptr > toggle( m_logger, rec ); 14 | f(); 15 | } 16 | return rec; 17 | } 18 | 19 | void set_logger( event_logger::ptr logger ) { 20 | if ( logger.is_valid() ) { 21 | m_haveCustomLogger = true; 22 | m_logger = logger; 23 | } else { 24 | m_haveCustomLogger = false; 25 | m_logger = new service_impl_t(); 26 | } 27 | } 28 | protected: 29 | event_logger::ptr m_logger; 30 | bool m_haveCustomLogger = false; 31 | }; 32 | 33 | #define FB2K_INPUT_LOG_STATUS(X) FB2K_LOG_STATUS(m_logger, X) 34 | #define FB2K_INPUT_LOG_WARNING(X) FB2K_LOG_WARNING(m_logger, X) 35 | #define FB2K_INPUT_LOG_ERROR(X) FB2K_LOG_ERROR(m_logger, X) 36 | -------------------------------------------------------------------------------- /foobar2000/helpers/input_stream_info_reader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef FOOBAR2000_DESKTOP 4 | 5 | template 6 | class input_stream_info_reader_impl : public input_stream_info_reader { 7 | public: 8 | input_t theInput; 9 | 10 | uint32_t get_stream_count() { 11 | return theInput.get_stream_count(); 12 | } 13 | void get_stream_info(uint32_t index, file_info & out, abort_callback & a) { 14 | theInput.get_stream_info(index, out, a); 15 | } 16 | uint32_t get_default_stream() { 17 | return theInput.get_default_stream(); 18 | } 19 | }; 20 | 21 | template 22 | class input_stream_info_reader_entry_impl : public input_stream_info_reader_entry { 23 | public: 24 | input_stream_info_reader::ptr open(const char * path, file::ptr fileHint, abort_callback & abort) { 25 | typedef input_stream_info_reader_impl obj_t; 26 | service_ptr_t p = new service_impl_t(); 27 | p->theInput.open(fileHint, path, input_open_info_read, abort); 28 | return p; 29 | } 30 | GUID get_guid() { 31 | return input_t::g_get_guid(); 32 | } 33 | }; 34 | 35 | #endif // FOOBAR2000_DESKTOP 36 | -------------------------------------------------------------------------------- /foobar2000/helpers/metadb_handle_array.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class metadb_handle_array : public fb2k::array { 4 | public: 5 | metadb_handle_array() {} 6 | metadb_handle_array(metadb_handle_list&& lst) : m_items(std::move(lst)) {} 7 | size_t count() const override { return m_items.get_size(); } 8 | fb2k::objRef itemAt(size_t index) const override { return m_items[index]; } 9 | 10 | t_size get_count() const override { return m_items.get_size(); } 11 | void get_item_ex(service_ptr& p_out, t_size n) const override { p_out = m_items[n]; } 12 | 13 | metadb_handle_list m_items; 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /foobar2000/helpers/metadb_info_container_impl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../SDK/metadb_info_container_impl.h" -------------------------------------------------------------------------------- /foobar2000/helpers/metadb_io_hintlist.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "metadb_info_container_impl.h" 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | // Obsolete, use metadb_hint_list instead when possible, wrapper provided for compatibility with old code 10 | 11 | class metadb_io_hintlist { 12 | public: 13 | void hint_reader(service_ptr_t p_reader, const char * p_path,abort_callback & p_abort) { 14 | init(); 15 | m_hints->add_hint_reader( p_path, p_reader, p_abort ); 16 | m_pendingCount += p_reader->get_subsong_count(); 17 | } 18 | void add(metadb_handle_ptr const& h, const file_info& i, t_filestats2 const& s, bool f) { 19 | init(); 20 | metadb_hint_list_v3::ptr v3; 21 | v3 ^= m_hints; 22 | 23 | auto infoObj = fb2k::service_new< metadb_info_container_const_impl >(); 24 | infoObj->m_info = i; infoObj->m_stats = s; 25 | v3->add_hint_v3(h, infoObj, f); 26 | 27 | ++m_pendingCount; 28 | } 29 | void add(metadb_handle_ptr const & p_handle,const file_info & p_info,t_filestats const & p_stats,bool p_fresh) { 30 | init(); 31 | m_hints->add_hint( p_handle, p_info, p_stats, p_fresh ); 32 | ++m_pendingCount; 33 | } 34 | void run() { 35 | if ( m_hints.is_valid() ) { 36 | m_hints->on_done(); 37 | m_hints.release(); 38 | } 39 | m_pendingCount = 0; 40 | } 41 | size_t get_pending_count() const { return m_pendingCount; } 42 | private: 43 | void init() { 44 | if ( m_hints.is_empty() ) { 45 | m_hints = metadb_io_v2::get()->create_hint_list(); 46 | } 47 | } 48 | metadb_hint_list::ptr m_hints; 49 | size_t m_pendingCount = 0; 50 | }; 51 | -------------------------------------------------------------------------------- /foobar2000/helpers/packet_decoder_mp3_common.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | #include "packet_decoder_mp3_common.h" 3 | #include "mp3_utils.h" 4 | 5 | unsigned packet_decoder_mp3_common::parseDecoderSetup( const GUID & p_owner,t_size p_param1,const void * p_param2,t_size p_param2size ) 6 | { 7 | if (p_owner == owner_MP3) return 3; 8 | else if (p_owner == owner_MP2) return 2; 9 | else if (p_owner == owner_MP1) return 1; 10 | else if (p_owner == owner_MP4) 11 | { 12 | switch(p_param1) 13 | { 14 | case 0x6B: 15 | return 3; 16 | break; 17 | case 0x69: 18 | return 3; 19 | break; 20 | default: 21 | return 0; 22 | } 23 | } 24 | else if (p_owner == owner_matroska) 25 | { 26 | if (p_param2size==sizeof(matroska_setup)) 27 | { 28 | const matroska_setup * setup = (const matroska_setup*) p_param2; 29 | if (!strcmp(setup->codec_id,"A_MPEG/L3")) return 3; 30 | else if (!strcmp(setup->codec_id,"A_MPEG/L2")) return 2; 31 | else if (!strcmp(setup->codec_id,"A_MPEG/L1")) return 1; 32 | else return 0; 33 | } 34 | else return 0; 35 | } 36 | else return 0; 37 | } 38 | 39 | unsigned packet_decoder_mp3_common::layer_from_frame(const void * frame, size_t size) { 40 | using namespace mp3_utils; 41 | TMPEGFrameInfo info; 42 | if (!ParseMPEGFrameHeader(info, frame, size)) throw exception_io_data(); 43 | return info.m_layer; 44 | } 45 | -------------------------------------------------------------------------------- /foobar2000/helpers/readers_lite.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | file::ptr createFileWithMemBlock(fb2k::memBlock::ptr mem, t_filestats stats = filestats_invalid, const char* contentType = nullptr, bool remote = false); 4 | file::ptr createFileLimited(file::ptr base, t_filesize offset, t_filesize size, abort_callback& abort); 5 | file::ptr createFileBigMemMirror(file::ptr source, abort_callback& abort); 6 | file::ptr createFileMemMirror(file::ptr source, abort_callback& abort); 7 | file::ptr createFileMemMirrorAsync(file::ptr source, completion_notify::ptr optionalDoneReading, abort_callback & a); 8 | -------------------------------------------------------------------------------- /foobar2000/helpers/rethrow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace ThreadUtils { 8 | class CRethrow { 9 | private: 10 | std::exception_ptr m_exception; 11 | public: 12 | bool exec( std::function f ) throw(); 13 | void rethrow() const; 14 | bool didFail() const { return !!m_exception; } 15 | void clear() { m_exception = nullptr; } 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /foobar2000/helpers/seekabilizer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class seekabilizer_backbuffer 4 | { 5 | public: 6 | void initialize(t_size p_size); 7 | void write(const void * p_buffer,t_size p_bytes); 8 | void read(t_size p_backlogdepth,void * p_buffer,t_size p_bytes) const; 9 | t_size get_depth() const; 10 | void reset(); 11 | t_size get_max_depth() const; 12 | private: 13 | pfc::array_t m_buffer; 14 | t_size m_depth,m_cursor; 15 | }; 16 | 17 | class seekabilizer : public file_readonly_t { 18 | public: 19 | void initialize(service_ptr_t p_base,t_size p_buffer_size,abort_callback & p_abort); 20 | 21 | static void g_seekabilize(service_ptr_t & p_reader,t_size p_buffer_size,abort_callback & p_abort); 22 | 23 | t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort); 24 | t_filesize get_size(abort_callback & p_abort); 25 | t_filesize get_position(abort_callback & p_abort); 26 | void seek(t_filesize p_position,abort_callback & p_abort); 27 | bool can_seek(); 28 | bool get_content_type(pfc::string_base & p_out); 29 | bool is_in_memory(); 30 | void on_idle(abort_callback & p_abort); 31 | t_filetimestamp get_timestamp(abort_callback & p_abort); 32 | void reopen(abort_callback & p_abort); 33 | bool is_remote(); 34 | 35 | service_ptr get_metadata(abort_callback&); 36 | t_filestats2 get_stats2(uint32_t s2flags, abort_callback&); 37 | size_t lowLevelIO(const GUID& guid, size_t arg1, void* arg2, size_t arg2size, abort_callback& abort); 38 | private: 39 | service_ptr_t m_file; 40 | seekabilizer_backbuffer m_buffer; 41 | t_filesize m_size,m_position,m_position_base; 42 | }; -------------------------------------------------------------------------------- /foobar2000/helpers/stream_buffer_helper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class stream_reader_buffered : public stream_reader 4 | { 5 | public: 6 | stream_reader_buffered(stream_reader * p_base,t_size p_buffer); 7 | t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort); 8 | private: 9 | stream_reader * m_base; 10 | pfc::array_t m_buffer; 11 | const char * m_bufferPtr; 12 | size_t m_bufferRemaining; 13 | }; 14 | 15 | class stream_writer_buffered : public stream_writer 16 | { 17 | public: 18 | stream_writer_buffered(stream_writer * p_base,t_size p_buffer); 19 | 20 | void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort); 21 | 22 | void flush(abort_callback & p_abort); 23 | 24 | private: 25 | stream_writer * m_base; 26 | pfc::array_t m_buffer; 27 | t_size m_buffer_ptr; 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /foobar2000/helpers/text_file_loader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace text_file_loader 4 | { 5 | constexpr size_t hardlimit_bytes = 1024 * 1024 * 128; 6 | 7 | void write(const service_ptr_t & p_file,abort_callback & p_abort,const char * p_string,bool is_utf8); 8 | void read(const service_ptr_t & p_file,abort_callback & p_abort,pfc::string_base & p_out,bool & is_utf8); 9 | void read_v2(const service_ptr_t & p_file, abort_callback & p_abort, pfc::string_base & p_out, bool & is_utf8, bool forceUTF8); 10 | 11 | 12 | void write(const char * p_path,abort_callback & p_abort,const char * p_string,bool is_utf8); 13 | void read(const char * p_path,abort_callback & p_abort,pfc::string_base & p_out,bool & is_utf8); 14 | void read_v2(const char * p_path, abort_callback & p_abort, pfc::string_base & p_out, bool & is_utf8, bool forceUTF8); 15 | 16 | }; -------------------------------------------------------------------------------- /foobar2000/helpers/text_file_loader_v2.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | #include "text_file_loader_v2.h" 3 | #include "text_file_loader.h" 4 | 5 | void text_file_loader_v2::load(file::ptr f, abort_callback & abort) { 6 | m_lines.clear(); 7 | bool dummy; 8 | text_file_loader::read_v2(f, abort, m_data, dummy, m_forceUTF8); 9 | 10 | m_lines.reserve(128); 11 | 12 | char * p = const_cast(m_data.get_ptr()); 13 | bool line = false; 14 | const size_t len = m_data.length(); 15 | for (size_t walk = 0; walk < len; ++walk) { 16 | char & c = p[walk]; 17 | if (c == '\n' || c == '\r') { 18 | c = 0; 19 | line = false; 20 | } else if (!line) { 21 | m_lines.push_back(&c); 22 | line = true; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /foobar2000/helpers/text_file_loader_v2.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class text_file_loader_v2 { 6 | public: 7 | bool m_forceUTF8 = false; 8 | 9 | void load(file::ptr f, abort_callback & abort); 10 | 11 | std::vector< char * > m_lines; 12 | 13 | pfc::string8 m_data; 14 | }; -------------------------------------------------------------------------------- /foobar2000/helpers/win-MulDiv.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _WIN32 4 | inline int MulDiv(int v1, int v2, int v3) { 5 | return pfc::rint32((double) v1 * (double) v2 / (double) v3); 6 | } 7 | #endif 8 | -------------------------------------------------------------------------------- /foobar2000/helpers/win-systemtime.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace winTimeWrapper { 4 | typedef struct _SYSTEMTIME { 5 | uint16_t wYear; 6 | uint16_t wMonth; 7 | uint16_t wDayOfWeek; 8 | uint16_t wDay; 9 | uint16_t wHour; 10 | uint16_t wMinute; 11 | uint16_t wSecond; 12 | uint16_t wMilliseconds; 13 | } SYSTEMTIME, * PSYSTEMTIME, * LPSYSTEMTIME; 14 | 15 | typedef struct _FILETIME { 16 | uint32_t dwLowDateTime; 17 | uint32_t dwHighDateTime; 18 | } FILETIME, * PFILETIME, * LPFILETIME; 19 | 20 | 21 | bool SystemTimeToFileTime(const SYSTEMTIME* lpSystemTime, FILETIME* lpFileTime); 22 | bool LocalFileTimeToFileTime(const FILETIME* lpLocalFileTime, FILETIME* lpFileTime); 23 | 24 | uint64_t FileTimeToInt(FILETIME); 25 | FILETIME FileTimeFromInt(uint64_t); 26 | 27 | #ifdef _WIN32 28 | void selfTest(); 29 | #endif 30 | } 31 | 32 | #ifndef _WIN32 33 | using namespace winTimeWrapper; 34 | #endif 35 | -------------------------------------------------------------------------------- /foobar2000/shared/filedialogs.h: -------------------------------------------------------------------------------- 1 | class uGetOpenFileNameMultiResult_impl : public uGetOpenFileNameMultiResult { 2 | pfc::list_t m_data; 3 | public: 4 | void AddItem(pfc::stringp param) {m_data.add_item(param);} 5 | t_size get_count() const {return m_data.get_count();} 6 | void get_item_ex(const char * & out,t_size n) const {out = m_data[n].ptr();} 7 | }; 8 | -------------------------------------------------------------------------------- /foobar2000/shared/modal_dialog.cpp: -------------------------------------------------------------------------------- 1 | #include "shared.h" 2 | 3 | static DWORD g_main_thread = GetCurrentThreadId(); 4 | 5 | static t_modal_dialog_entry g_status = {0,false}; 6 | 7 | static bool TestMainThread() 8 | { 9 | if (GetCurrentThreadId() == g_main_thread) return true; 10 | OutputDebugString(TEXT("This function can be called only from main thread.\n")); 11 | return false; 12 | } 13 | 14 | HWND SHARED_EXPORT FindOwningPopup(HWND p_wnd) 15 | { 16 | return pfc::findOwningPopup(p_wnd); 17 | } 18 | 19 | void SHARED_EXPORT PokeWindow(HWND p_wnd) 20 | { 21 | p_wnd = FindOwningPopup(p_wnd); 22 | if (IsWindowEnabled(p_wnd)) 23 | { 24 | // SetForegroundWindow(p_wnd); 25 | SetActiveWindow(p_wnd); 26 | FlashWindow(p_wnd,FALSE); 27 | } 28 | else 29 | { 30 | HWND child = GetWindow(p_wnd,GW_ENABLEDPOPUP); 31 | if (child != 0) 32 | { 33 | // SetForegroundWindow(child); 34 | SetActiveWindow(child); 35 | FlashWindow(child,FALSE); 36 | } 37 | } 38 | } 39 | 40 | extern "C" { 41 | void SHARED_EXPORT ModalDialog_Switch(t_modal_dialog_entry & p_entry) 42 | { 43 | if (TestMainThread()) 44 | pfc::swap_t(p_entry,g_status); 45 | } 46 | 47 | void SHARED_EXPORT ModalDialog_PokeExisting() 48 | { 49 | if (TestMainThread()) 50 | { 51 | if (g_status.m_in_use && g_status.m_wnd_to_poke != 0) 52 | { 53 | PokeWindow(g_status.m_wnd_to_poke); 54 | MessageBeep(0); 55 | } 56 | } 57 | } 58 | 59 | bool SHARED_EXPORT ModalDialog_CanCreateNew() 60 | { 61 | if (TestMainThread()) 62 | return !g_status.m_in_use; 63 | else 64 | return false; 65 | } 66 | } -------------------------------------------------------------------------------- /foobar2000/shared/shared-ARM64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungive/foo_mediacontrol/d07055f5147fcd80277d91d2a306e9e3bacd024e/foobar2000/shared/shared-ARM64.lib -------------------------------------------------------------------------------- /foobar2000/shared/shared-ARM64EC.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungive/foo_mediacontrol/d07055f5147fcd80277d91d2a306e9e3bacd024e/foobar2000/shared/shared-ARM64EC.lib -------------------------------------------------------------------------------- /foobar2000/shared/shared-Win32.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungive/foo_mediacontrol/d07055f5147fcd80277d91d2a306e9e3bacd024e/foobar2000/shared/shared-Win32.lib -------------------------------------------------------------------------------- /foobar2000/shared/shared-apple.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | bool uSetClipboardString(const char * ptr); 4 | bool uGetClipboardString(pfc::string_base & out); 5 | -------------------------------------------------------------------------------- /foobar2000/shared/shared-nix.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class uFindFile 4 | { 5 | protected: 6 | uFindFile() {} 7 | public: 8 | virtual ~uFindFile() {}; 9 | virtual bool FindNext() = 0; 10 | virtual const char * GetFileName() = 0; 11 | virtual bool IsDirectory() = 0; 12 | }; 13 | 14 | typedef uFindFile * puFindFile; 15 | 16 | puFindFile uFindFirstFile(const char * path); 17 | 18 | pfc::string8 uStringPrintf(const char * format, ...); 19 | void uPrintfV(pfc::string_base & out,const char * fmt,va_list arglist); 20 | void uPrintf(pfc::string_base & out,const char * fmt,...); 21 | 22 | bool uGetTempPath(pfc::string_base & out); 23 | bool uGetTempFileName(const char * path_name,const char * prefix,unsigned unique,pfc::string_base & out); 24 | pfc::string8 uGetTempFileName(); 25 | 26 | 27 | bool uSetCurrentDirectory(const char * path); 28 | bool uGetCurrentDirectory(pfc::string_base & out); 29 | -------------------------------------------------------------------------------- /foobar2000/shared/shared-x64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungive/foo_mediacontrol/d07055f5147fcd80277d91d2a306e9e3bacd024e/foobar2000/shared/shared-x64.lib -------------------------------------------------------------------------------- /foobar2000/shared/stdafx.cpp: -------------------------------------------------------------------------------- 1 | #include "shared.h" -------------------------------------------------------------------------------- /foobar2000/shared/win32_misc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | class win32_font { 5 | public: 6 | win32_font(HFONT p_initval) : m_font(p_initval) {} 7 | win32_font() : m_font(NULL) {} 8 | ~win32_font() {release();} 9 | 10 | void release() { 11 | HFONT temp = detach(); 12 | if (temp != NULL) DeleteObject(temp); 13 | } 14 | 15 | void set(HFONT p_font) {release(); m_font = p_font;} 16 | HFONT get() const {return m_font;} 17 | HFONT detach() {return pfc::replace_t(m_font,(HFONT)NULL);} 18 | 19 | void create(const t_font_description & p_desc) { 20 | SetLastError(NO_ERROR); 21 | HFONT temp = p_desc.create(); 22 | if (temp == NULL) throw exception_win32(GetLastError()); 23 | set(temp); 24 | } 25 | 26 | bool is_valid() const {return m_font != NULL;} 27 | 28 | private: 29 | win32_font(const win32_font&) = delete; 30 | void operator=(const win32_font &) = delete; 31 | 32 | HFONT m_font; 33 | }; 34 | -------------------------------------------------------------------------------- /libPPUI/AutoComplete.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | HRESULT InitializeEditAC(HWND edit, pfc::const_iterator valueEnum, DWORD opts = ACO_AUTOAPPEND | ACO_AUTOSUGGEST); 6 | HRESULT InitializeEditAC(HWND edit, const char * values, DWORD opts = ACO_AUTOAPPEND | ACO_AUTOSUGGEST); 7 | HRESULT InitializeSimpleAC(HWND edit, IUnknown * vals, DWORD opts); 8 | pfc::com_ptr_t CreateACList(pfc::const_iterator valueEnum); 9 | pfc::com_ptr_t CreateACList(pfc::const_iterator valueEnum); 10 | pfc::com_ptr_t CreateACList(); 11 | void CreateACList_AddItem(IUnknown * theList, const char * item); 12 | -------------------------------------------------------------------------------- /libPPUI/CDialogResizeHelperCompat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CDialogResizeHelperCompat { 4 | public: 5 | struct param { 6 | unsigned short id; 7 | unsigned short flags; 8 | }; 9 | 10 | enum { 11 | X_MOVE = 1, X_SIZE = 2, Y_MOVE = 4, Y_SIZE = 8, 12 | XY_MOVE = X_MOVE | Y_MOVE, XY_SIZE = X_SIZE | Y_SIZE, 13 | X_MOVE_Y_SIZE = X_MOVE | Y_SIZE, X_SIZE_Y_MOVE = X_SIZE | Y_MOVE, 14 | }; 15 | 16 | }; -------------------------------------------------------------------------------- /libPPUI/CHeaderCtrlEx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CHeaderCtrlEx : public CHeaderCtrl { 4 | public: 5 | CHeaderCtrlEx(HWND wnd = NULL) : CHeaderCtrl(wnd) {} 6 | CHeaderCtrlEx const & operator=(HWND wnd) { m_hWnd = wnd; return *this; } 7 | 8 | // Column sort marker operations 9 | // If they appear to have no effect, you're probably missing Common Controls 6 manifest, see link-CommonControls6.h 10 | DWORD GetItemFormat(int iItem); 11 | void SetItemFormat(int iItem, DWORD flags); 12 | void SetItemSort(int iItem, int direction); 13 | void SetSingleItemSort(int iItem, int direction); 14 | void ClearSort(); 15 | }; 16 | -------------------------------------------------------------------------------- /libPPUI/CIconOverlayWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "win32_op.h" 4 | 5 | typedef CWinTraits _COverlayWindowTraits; 6 | 7 | class CIconOverlayWindow : public CWindowImpl { 8 | public: 9 | DECLARE_WND_CLASS_EX(TEXT("{384298D0-4370-4f9b-9C36-49FC1A396DC7}"),0,(-1)); 10 | 11 | void AttachIcon(HICON p_icon) {m_icon = p_icon;} 12 | bool HaveIcon() const {return m_icon != NULL;} 13 | 14 | enum { 15 | ColorKey = 0xc0ffee 16 | }; 17 | 18 | BEGIN_MSG_MAP_EX(CIconOverlayWindow) 19 | MESSAGE_HANDLER(WM_CREATE,OnCreate); 20 | MESSAGE_HANDLER(WM_PAINT,OnPaint); 21 | MESSAGE_HANDLER(WM_ERASEBKGND,OnEraseBkgnd); 22 | END_MSG_MAP() 23 | private: 24 | LRESULT OnCreate(UINT,WPARAM,LPARAM,BOOL&) { 25 | ::SetLayeredWindowAttributes(*this,ColorKey,0,LWA_COLORKEY); 26 | return 0; 27 | } 28 | LRESULT OnEraseBkgnd(UINT,WPARAM p_wp,LPARAM,BOOL&) { 29 | CRect rcClient; 30 | WIN32_OP_D( GetClientRect(rcClient) ); 31 | CDCHandle((HDC)p_wp).FillSolidRect(rcClient,ColorKey); 32 | return 1; 33 | } 34 | LRESULT OnPaint(UINT,WPARAM,LPARAM,BOOL& bHandled) { 35 | if (m_icon != NULL) { 36 | CPaintDC dc(*this); 37 | CRect client; 38 | WIN32_OP_D( GetClientRect(&client) ); 39 | dc.DrawIconEx(0,0,m_icon,client.right,client.bottom); 40 | //CDCHandle(ps.hdc).DrawIcon(0,0,m_icon); 41 | } else { 42 | bHandled = FALSE; 43 | } 44 | return 0; 45 | } 46 | CIcon m_icon; 47 | }; 48 | -------------------------------------------------------------------------------- /libPPUI/CListControl-Cell.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include // HTHEME 3 | #include 4 | 5 | class CListCell { 6 | public: 7 | typedef uint32_t cellState_t; 8 | enum { 9 | cellState_none = 0, 10 | cellState_hot = 1 << 0, 11 | cellState_pressed = 1 << 1, 12 | cellState_disabled = 1 << 2, 13 | }; 14 | 15 | struct DrawContentArg_t { 16 | DWORD hdrFormat = 0; 17 | cellState_t cellState = 0; 18 | CRect subItemRect; 19 | CDCHandle dc; 20 | const wchar_t * text = nullptr; 21 | bool allowColors = true; 22 | CRect rcHot; 23 | CRect rcText; 24 | HTHEME theme = NULL; 25 | uint32_t colorHighlight = 0; 26 | CWindow thisWnd; 27 | std::function imageRenderer; 28 | bool darkMode = false; 29 | }; 30 | virtual void DrawContent( DrawContentArg_t const & arg ) = 0; 31 | virtual const char * Theme() { return nullptr; } 32 | virtual bool ApplyTextStyle( LOGFONT & font, double scale, uint32_t state ); 33 | virtual bool IsInteractive() { return false; } 34 | virtual bool TracksMouseMove() { return false; } 35 | virtual bool SuppressRowSelect() { return false; } 36 | virtual bool IsToggle() { return false; } 37 | virtual bool IsRadioToggle() { return false; } 38 | virtual bool AllowTypeFind() { return true; } 39 | virtual CRect HotRect( CRect rc ) { return rc; } 40 | virtual HCURSOR HotCursor() { return NULL; } 41 | virtual bool AllowDrawThemeText() { return false; } 42 | virtual LONG AccRole(); 43 | virtual uint32_t EditFlags() { return 0; } 44 | virtual bool ClickToEdit() { return false; } 45 | }; 46 | -------------------------------------------------------------------------------- /libPPUI/CListControl-Cells-Compat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "CListControl-Cells.h" 3 | 4 | // Wrapper for old code using cell type enum constants 5 | 6 | #define cell_text &PFC_SINGLETON(CListCell_Text) 7 | #define cell_multitext &PFC_SINGLETON(CListCell_MultiText) 8 | #define cell_hyperlink &PFC_SINGLETON(CListCell_Hyperlink) 9 | #define cell_button &PFC_SINGLETON(CListCell_Button) 10 | #define cell_button_lite &PFC_SINGLETON(CListCell_ButtonLite) 11 | #define cell_button_glyph &PFC_SINGLETON(CListCell_ButtonGlyph) 12 | #define cell_checkbox &PFC_SINGLETON(CListCell_Checkbox) 13 | #define cell_radiocheckbox &PFC_SINGLETON(CListCell_RadioCheckbox) 14 | -------------------------------------------------------------------------------- /libPPUI/CListControl-Subst.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | HWND CListControl_ReplaceListView(HWND); 4 | HWND CListControl_ReplaceListBox(HWND); -------------------------------------------------------------------------------- /libPPUI/CListControlComplete.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // ================================================================================ 4 | // CListControlComplete 5 | // ================================================================================ 6 | // Simplified declaration of the base class that most CListControl users will need. 7 | // The other base classes are used directly mainly by old code predating libPPUI. 8 | // ================================================================================ 9 | 10 | #include "CListControlWithSelection.h" 11 | #include "CListControl_EditImpl.h" 12 | #include "CListAccessible.h" 13 | 14 | // ================================================================================ 15 | // CListControlWithSelectionImpl = list control with selection/focus 16 | // CListControl_EditImpl = inplace editbox implementation 17 | // CListControlAccImpl = accessibility API implementation (screen reader interop) 18 | // ================================================================================ 19 | typedef CListControlAccImpl > CListControlComplete; 20 | 21 | // CListControlReadOnly : no inplace edit functionality (CListControl_EditImpl) 22 | typedef CListControlAccImpl CListControlReadOnly; 23 | -------------------------------------------------------------------------------- /libPPUI/CListControlUserOptions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CListControlUserOptions { 4 | public: 5 | CListControlUserOptions() { instance = this; } 6 | virtual bool useSmoothScroll() = 0; 7 | 8 | static CListControlUserOptions * instance; 9 | }; -------------------------------------------------------------------------------- /libPPUI/CListViewCtrlEx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CListViewCtrlEx : public CListViewCtrl { 4 | public: 5 | CListViewCtrlEx( HWND wnd = NULL ) : CListViewCtrl(wnd) {} 6 | CListViewCtrlEx const & operator=( HWND wnd ) { m_hWnd = wnd; return *this; } 7 | unsigned InsertColumnEx(unsigned index, const wchar_t * name, unsigned widthDLU); 8 | unsigned AddColumnEx( const wchar_t * name, unsigned widthDLU ); 9 | void FixContextMenuPoint( CPoint & pt ); 10 | unsigned GetColunnCount(); 11 | 12 | unsigned InsertString( unsigned index, const wchar_t * str ); 13 | unsigned InsertString8( unsigned index, const char * str ); 14 | unsigned AddString( const wchar_t * str ); 15 | unsigned AddString8(const char * str); 16 | void SetItemText(unsigned item, unsigned subItem, const wchar_t * str ); 17 | void SetItemText8(unsigned item, unsigned subItem, const char * str ); 18 | 19 | void AutoSizeColumn( int iCol ) { SetColumnWidth(iCol, LVSCW_AUTOSIZE) ;} 20 | int AddGroup(int iGroupID, const wchar_t * header); 21 | }; 22 | 23 | // BOOL HandleLVKeyDownMod() 24 | #define LVN_KEYDOWN_MOD_HANDLER(id, key, mod, func) \ 25 | if (uMsg == WM_NOTIFY && LVN_KEYDOWN == ((LPNMHDR)lParam)->code && id == ((LPNMHDR)lParam)->idFrom && ((LPNMLVKEYDOWN)lParam)->wVKey == (key) && GetHotkeyModifierFlags() == (mod)) \ 26 | { \ 27 | SetMsgHandled(TRUE); \ 28 | lResult = func()?1:0; \ 29 | if(IsMsgHandled()) \ 30 | return TRUE; \ 31 | } 32 | 33 | // BOOL HandleLVCopy() 34 | #define LVN_COPY_HANDLER(id, func) LVN_KEYDOWN_MOD_HANDLER(id, 'C', MOD_CONTROL, func) 35 | -------------------------------------------------------------------------------- /libPPUI/CMiddleDragLite.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace PP { 4 | //! Single-function-call API to add middle click drag capability to any standard Windows control. \n 5 | //! Works with listviews, listboxes, treeviews, etc. \n 6 | //! Window will be subclassed, lifetime of subclass managed automatically. No further interaction needed from your code. \n 7 | //! If you also subclass it to handle middle click events, pay attention to order in which you install the subclasses to receive your events. 8 | void addMiddleDragToCtrl(HWND wndCtrl); 9 | } 10 | -------------------------------------------------------------------------------- /libPPUI/CMiddleDragOverlay.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "win32_op.h" 4 | #include "win32_utility.h" 5 | 6 | class CMiddleDragOverlay : public CWindowImpl > { 7 | public: 8 | DECLARE_WND_CLASS_EX(TEXT("{61BFC7AD-C00F-4CEA-8E6A-EA22E01F43F9}"),0,(-1)); 9 | 10 | enum { 11 | ColorKey = 0xc0ffee 12 | }; 13 | 14 | BEGIN_MSG_MAP_EX(CMiddleDragOverlay) 15 | MESSAGE_HANDLER(WM_CREATE,OnCreate); 16 | MSG_WM_ERASEBKGND(OnEraseBkgnd) 17 | MSG_WM_PAINT(OnPaint) 18 | END_MSG_MAP() 19 | 20 | void ShowHere(CPoint pt); 21 | private: 22 | LRESULT OnCreate(UINT,WPARAM,LPARAM,BOOL&) { 23 | ::SetLayeredWindowAttributes(*this,ColorKey,0,LWA_COLORKEY); 24 | return 0; 25 | } 26 | BOOL OnEraseBkgnd(CDCHandle dc) { 27 | CRect rcClient; 28 | WIN32_OP_D(GetClientRect(rcClient)); 29 | dc.FillSolidRect(rcClient, ColorKey); 30 | return TRUE; 31 | } 32 | void OnPaint(CDCHandle dc) { 33 | if (dc) { 34 | Paint(dc); 35 | } else { 36 | CPaintDC pdc(*this); 37 | Paint(pdc.m_hDC); 38 | } 39 | } 40 | void Paint(CDCHandle dc); 41 | }; 42 | -------------------------------------------------------------------------------- /libPPUI/CPowerRequest.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _WIN32 4 | 5 | #ifdef WINAPI_FAMILY_PARTITION 6 | #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) 7 | #define CPowerRequestAPI_Avail 8 | #endif 9 | #else // no WINAPI_FAMILY_PARTITION, desktop SDK 10 | #define CPowerRequestAPI_Avail 11 | #endif 12 | 13 | #endif // _WIN32 14 | 15 | #ifdef CPowerRequestAPI_Avail 16 | 17 | class CPowerRequest { 18 | public: 19 | CPowerRequest(const wchar_t * Reason); 20 | void SetSystem(bool bSystem); 21 | void SetExecution(bool bExecution); 22 | void SetDisplay(bool bDisplay); 23 | ~CPowerRequest(); 24 | 25 | CPowerRequest(const CPowerRequest&) = delete; 26 | void operator=(const CPowerRequest&) = delete; 27 | private: 28 | HANDLE m_Request = INVALID_HANDLE_VALUE; 29 | bool m_bSystem = false, m_bDisplay = false; 30 | }; 31 | #else 32 | 33 | class CPowerRequest { 34 | public: 35 | CPowerRequest(const wchar_t * Reason) {} 36 | void SetSystem(bool bSystem) {} 37 | void SetExecution(bool bExecution) {} 38 | void SetDisplay(bool bDisplay) {} 39 | CPowerRequest(const CPowerRequest&) = delete; 40 | void operator=(const CPowerRequest&) = delete; 41 | }; 42 | 43 | #endif // CPowerRequestAPI_Avail 44 | -------------------------------------------------------------------------------- /libPPUI/CPropVariant.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CPropVariant : public PROPVARIANT { 4 | public: 5 | CPropVariant() {init();} 6 | ~CPropVariant() {clear();} 7 | CPropVariant( const CPropVariant & other ) { 8 | init(); 9 | PropVariantCopy( this, &other ); 10 | } 11 | const CPropVariant& operator=( const CPropVariant & other ) { 12 | clear(); 13 | PropVariantCopy(this, &other); 14 | return *this; 15 | } 16 | 17 | bool toInt64(int64_t & out) const { 18 | switch( vt ) { 19 | case VT_I1: out = (int64_t) cVal; return true; 20 | case VT_I2: out = (int64_t) iVal; return true; 21 | case VT_I4: out = (int64_t) lVal; return true; 22 | case VT_I8: out = (int64_t) hVal.QuadPart; return true; 23 | case VT_INT: out = (int64_t) intVal; return true; 24 | default: return false; 25 | } 26 | } 27 | bool toUint64(uint64_t & out) const { 28 | switch( vt ) { 29 | case VT_UI1: out = (uint64_t) bVal; return true; 30 | case VT_UI2: out = (uint64_t) uiVal; return true; 31 | case VT_UI4: out = (uint64_t) ulVal; return true; 32 | case VT_UI8: out = (uint64_t) uhVal.QuadPart; return true; 33 | case VT_UINT: out = (uint64_t) uintVal; return true; 34 | default: return false; 35 | } 36 | } 37 | bool toString( pfc::string_base & out ) const { 38 | switch( vt ) { 39 | case VT_LPSTR: 40 | out = pfc::stringcvt::string_utf8_from_ansi( pszVal ); return true; 41 | case VT_LPWSTR: 42 | out = pfc::stringcvt::string_utf8_from_wide( pwszVal ); return true; 43 | default: return false; 44 | } 45 | } 46 | private: 47 | void clear() { 48 | PropVariantClear( this ); 49 | } 50 | void init() { 51 | PROPVARIANT * pv = this; 52 | PropVariantInit( pv ); 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /libPPUI/CWindowCreateAndDelete.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "win32_op.h" 4 | 5 | template 6 | class CWindowCreateAndDelete : public TClass { 7 | public: 8 | template CWindowCreateAndDelete(HWND parent, arg_t && ... arg) : TClass(std::forward(arg) ...) { WIN32_OP(this->Create(parent) != NULL); } 9 | private: 10 | void OnFinalMessage(HWND wnd) override { PFC_ASSERT_NO_EXCEPTION(TClass::OnFinalMessage(wnd)); PFC_ASSERT_NO_EXCEPTION(delete this); } 11 | }; 12 | -------------------------------------------------------------------------------- /libPPUI/DarkMode-CHyperLink.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "DarkMode.h" 4 | 5 | namespace DarkMode { 6 | static constexpr COLORREF colorHyperLink = 0xCC6600; // taken from screenshot of syslink 7 | 8 | template class CHyperLinkImpl : public ::CHyperLinkImpl { 9 | public: 10 | BEGIN_MSG_MAP_EX(CDarkHyperLinkImpl) 11 | MESSAGE_HANDLER_EX(DarkMode::msgSetDarkMode(), OnSetDarkMode) 12 | CHAIN_MSG_MAP(::CHyperLinkImpl) 13 | END_MSG_MAP() 14 | private: 15 | LRESULT OnSetDarkMode(UINT, WPARAM wp, LPARAM) { 16 | const bool bDark = (wp != 0); 17 | if ( m_clrLinkBackup == CLR_INVALID ) m_clrLinkBackup = this->m_clrLink; 18 | 19 | if (bDark != m_isDark) { 20 | m_isDark = bDark; 21 | this->m_clrLink = bDark ? colorHyperLink : m_clrLinkBackup; 22 | this->Invalidate(); 23 | } 24 | 25 | return 1; 26 | } 27 | COLORREF m_clrLinkBackup = CLR_INVALID; 28 | bool m_isDark = false; 29 | }; 30 | 31 | 32 | class CHyperLink : public CHyperLinkImpl { 33 | public: 34 | DECLARE_WND_CLASS(_T("WTL_DarkHyperLink")) 35 | }; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /libPPUI/DarkModeEx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DarkMode.h" 4 | 5 | namespace DarkMode { 6 | void PaintTabsErase(CTabCtrl, CDCHandle); 7 | void PaintTabs(CTabCtrl, CDCHandle, const RECT* rcPaint = nullptr); 8 | } -------------------------------------------------------------------------------- /libPPUI/EditBoxFix.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "EditBoxFixes.h" 3 | #include "wtl-pp.h" 4 | #include "windowLifetime.h" 5 | 6 | namespace PP { 7 | void editBoxFix(HWND wndEdit) { 8 | PFC_ASSERT( IsWindow(wndEdit) ); 9 | PP::subclassThisWindow(wndEdit); 10 | } 11 | void comboBoxFix(HWND wndCombo) { 12 | PFC_ASSERT( IsWindow(wndCombo) ); 13 | CComboBox combo = wndCombo; 14 | COMBOBOXINFO info = { sizeof(info) }; 15 | if (combo.GetComboBoxInfo(&info)) { 16 | if ( info.hwndItem != NULL ) editBoxFix( info.hwndItem ); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /libPPUI/EditBoxFixes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace PP { 4 | // One-line methods to inject our edit box shims: Ctrl+A, Ctrl+Backspace, etc 5 | void editBoxFix(HWND wndEdit); 6 | void comboBoxFix(HWND wndCombo); 7 | } -------------------------------------------------------------------------------- /libPPUI/HyperLinkCtrl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | namespace PP { 4 | // One-line method to turn static control to hyperlink firing WM_NOTIFY 5 | void createHyperLink(HWND wndReplaceMe); 6 | void createHyperLink(HWND wndReplaceMe, std::function handler); 7 | void createHyperLink(HWND wndReplaceMe, const wchar_t * openURL); 8 | } -------------------------------------------------------------------------------- /libPPUI/ImageEncoder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | namespace Gdiplus { class Image; class Bitmap; }; 4 | 5 | void SaveImage(Gdiplus::Image* bmp, const TCHAR* out, const TCHAR* format, ULONG quality = 100); 6 | void SaveImage( Gdiplus::Bitmap * bmp, const TCHAR * out, const TCHAR * format, ULONG quality = 100); 7 | void ConvertImage(const TCHAR * in, const TCHAR * out, const TCHAR * format, ULONG quality = 100); 8 | std::unique_ptr image16bpcto8(Gdiplus::Bitmap* img); -------------------------------------------------------------------------------- /libPPUI/ImplementOnFinalMessage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class ImplementOnFinalMessage : public class_t { 5 | public: 6 | template ImplementOnFinalMessage(arg_t && ... arg) : class_t(std::forward(arg) ...) {} 7 | void OnFinalMessage(HWND wnd) override { PFC_ASSERT_NO_EXCEPTION(class_t::OnFinalMessage(wnd)); PFC_ASSERT_NO_EXCEPTION(delete this); } 8 | }; 9 | -------------------------------------------------------------------------------- /libPPUI/ReStyleWnd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "win32_op.h" 3 | 4 | namespace PP { 5 | // Recreate std control with a different style, keep position, title, font 6 | template 7 | void reStyleCtrl(CWindowT& btn, DWORD winStyle, DWORD winStyleEx) { 8 | CWindowT btnNew; 9 | CString title; 10 | CWindow parent = btn.GetParent(); 11 | btn.GetWindowText(title); 12 | CRect rc; WIN32_OP_D(btn.GetWindowRect(rc)); WIN32_OP_D(parent.ScreenToClient(rc)); 13 | CWindow wndPrev = parent.GetNextDlgTabItem(btn, TRUE); 14 | auto ctrlID = btn.GetDlgCtrlID(); 15 | auto font = btn.GetFont(); 16 | btn.DestroyWindow(); 17 | WIN32_OP_D(btnNew.Create(parent, rc, title, winStyle | WS_CLIPSIBLINGS, winStyleEx, ctrlID)); 18 | if (wndPrev != NULL) btnNew.SetWindowPos(wndPrev, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 19 | btnNew.SetFont(font); 20 | btn = btnNew; 21 | } 22 | } -------------------------------------------------------------------------------- /libPPUI/SmartStrStr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Moved 4 | #include -------------------------------------------------------------------------------- /libPPUI/TypeFind.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class TypeFind { 4 | public: 5 | static LRESULT Handler(NMHDR* hdr, int subItemFrom = 0, int subItemCnt = 1); 6 | }; 7 | -------------------------------------------------------------------------------- /libPPUI/clipboard.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "clipboard.h" 4 | #include "win32_op.h" 5 | 6 | #ifdef UNICODE 7 | #define CF_TCHAR CF_UNICODETEXT 8 | #else 9 | #define CF_TCHAR CF_TEXT 10 | #endif 11 | 12 | namespace ClipboardHelper { 13 | void OpenScope::Open(HWND p_owner) { 14 | Close(); 15 | WIN32_OP(OpenClipboard(p_owner)); 16 | m_open = true; 17 | } 18 | void OpenScope::Close() { 19 | if (m_open) { 20 | m_open = false; 21 | CloseClipboard(); 22 | } 23 | } 24 | void SetRaw(UINT format,const void * data, t_size size) { 25 | HANDLE buffer = GlobalAlloc(GMEM_DDESHARE,size); 26 | if (buffer == NULL) throw std::bad_alloc(); 27 | try { 28 | CGlobalLockScope lock(buffer); 29 | PFC_ASSERT(lock.GetSize() == size); 30 | memcpy(lock.GetPtr(),data,size); 31 | } catch(...) { 32 | GlobalFree(buffer); throw; 33 | } 34 | 35 | WIN32_OP(SetClipboardData(format,buffer) != NULL); 36 | } 37 | void SetString(const char * in) { 38 | pfc::stringcvt::string_os_from_utf8 temp(in); 39 | SetRaw(CF_TCHAR,temp.get_ptr(),(temp.length() + 1) * sizeof(TCHAR)); 40 | } 41 | 42 | bool GetString(pfc::string_base & out) { 43 | pfc::array_t temp; 44 | if (!GetRaw(CF_TCHAR,temp)) return false; 45 | out = pfc::stringcvt::string_utf8_from_os(reinterpret_cast(temp.get_ptr()),temp.get_size() / sizeof(TCHAR)); 46 | return true; 47 | } 48 | bool IsTextAvailable() { 49 | return IsClipboardFormatAvailable(CF_TCHAR) == TRUE; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /libPPUI/clipboard.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ClipboardHelper { 4 | 5 | class OpenScope { 6 | public: 7 | OpenScope() : m_open(false) {} 8 | ~OpenScope() {Close();} 9 | void Open(HWND p_owner); 10 | void Close(); 11 | private: 12 | bool m_open; 13 | 14 | PFC_CLASS_NOT_COPYABLE_EX(OpenScope) 15 | }; 16 | 17 | void SetRaw(UINT format,const void * buffer, t_size size); 18 | void SetString(const char * in); 19 | 20 | bool GetString(pfc::string_base & out); 21 | 22 | template 23 | bool GetRaw(UINT format,TArray & out) { 24 | pfc::assert_byte_type(); 25 | HANDLE data = GetClipboardData(format); 26 | if (data == NULL) return false; 27 | CGlobalLockScope lock(data); 28 | out.set_size( lock.GetSize() ); 29 | memcpy(out.get_ptr(), lock.GetPtr(), lock.GetSize() ); 30 | return true; 31 | } 32 | bool IsTextAvailable(); 33 | }; 34 | -------------------------------------------------------------------------------- /libPPUI/commandline_parser.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "commandline_parser.h" 3 | 4 | commandline_parser::commandline_parser() { 5 | init(pfc::stringcvt::string_utf8_from_os(GetCommandLine())); 6 | } 7 | 8 | void commandline_parser::init(const char * cmd) 9 | { 10 | pfc::string8_fastalloc temp; 11 | pfc::chain_list_v2_t out; 12 | while(*cmd) 13 | { 14 | temp.reset(); 15 | while(*cmd && *cmd!=' ') 16 | { 17 | if (*cmd=='\"') 18 | { 19 | cmd++; 20 | while(*cmd && *cmd!='\"') temp.add_byte(*(cmd++)); 21 | if (*cmd == '\"') cmd++; 22 | } 23 | else temp.add_byte(*(cmd++)); 24 | } 25 | out.insert_last(temp); 26 | while(*cmd==' ') cmd++; 27 | } 28 | pfc::list_to_array(m_data,out); 29 | } 30 | 31 | size_t commandline_parser::find_param(const char * ptr) const { 32 | for(size_t n=1;n m_data; 22 | }; 23 | -------------------------------------------------------------------------------- /libPPUI/hookWindowMessages.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "windowLifetime.h" 4 | 5 | namespace PP { 6 | // CContainedWindow replacement 7 | // Rationale: 8 | // With CContainedWindow, all messages that the window gets are routed through the message map of your class. 9 | // The window might bounce some of the messages to other windows (say, mouse4/5 handlers, WM_CONTEXTMENU), or do modal loops. 10 | // If some events triggered by those destroy your CContainedWindow host, crash happens, because your object is still on stack. 11 | // hookWindowMessages() sends only the messages you ask for to your class, also managing hook lifetime behind the scenes. 12 | void hookWindowMessages(HWND wnd, CMessageMap* target, DWORD targetID, std::initializer_list&& msgs); 13 | 14 | typedef std::function messageHook_t; 15 | void hookWindowMessages(HWND wnd, messageHook_t h); 16 | } -------------------------------------------------------------------------------- /libPPUI/libPPUI-license.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2002-2024 Peter Pawlowski 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------------------------- /libPPUI/libPPUI-readme.txt: -------------------------------------------------------------------------------- 1 | libPPUI 2 | 3 | A library of user interface classes used by foobar2000 codebase; freely available for anyone to use in their programming projects. 4 | -------------------------------------------------------------------------------- /libPPUI/link-CommonControls6.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' processorArchitecture='*'\"") 4 | -------------------------------------------------------------------------------- /libPPUI/pp-COM-macros.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define COM_QI_BEGIN() HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,void ** ppvObject) override { if (ppvObject == NULL) return E_INVALIDARG; 4 | #define COM_QI_ENTRY(IWhat) { if (iid == __uuidof(IWhat)) {IWhat * temp = this; temp->AddRef(); * ppvObject = temp; return S_OK;} } 5 | #define COM_QI_ENTRY_(IWhat, IID) { if (iid == IID) {IWhat * temp = this; temp->AddRef(); * ppvObject = temp; return S_OK;} } 6 | #define COM_QI_END() * ppvObject = NULL; return E_NOINTERFACE; } 7 | 8 | #define COM_QI_CHAIN(Parent) { HRESULT status = Parent::QueryInterface(iid, ppvObject); if (SUCCEEDED(status)) return status; } 9 | 10 | #define COM_QI_SIMPLE(IWhat) COM_QI_BEGIN() COM_QI_ENTRY(IUnknown) COM_QI_ENTRY(IWhat) COM_QI_END() 11 | 12 | 13 | #define PP_COM_CATCH catch(exception_com const & e) {return e.get_code();} catch(std::bad_alloc) {return E_OUTOFMEMORY;} catch(pfc::exception_invalid_params) {return E_INVALIDARG;} catch(...) {return E_UNEXPECTED;} -------------------------------------------------------------------------------- /libPPUI/stdafx.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | -------------------------------------------------------------------------------- /libPPUI/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define _SECURE_ATL 1 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | 24 | #ifndef _UNICODE 25 | #error seriously? 26 | #endif -------------------------------------------------------------------------------- /libPPUI/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _WIN32_WINNT 4 | #define _WIN32_WINNT 0x0601 5 | #include 6 | #endif -------------------------------------------------------------------------------- /libPPUI/win32_op.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "win32_op.h" 3 | #include 4 | 5 | PFC_NORETURN PFC_NOINLINE void WIN32_OP_FAIL() { 6 | const DWORD code = GetLastError(); 7 | PFC_ASSERT(code != NO_ERROR); 8 | throw exception_win32(code); 9 | } 10 | 11 | PFC_NORETURN PFC_NOINLINE void WIN32_OP_FAIL_CRITICAL(const char * what) { 12 | (void)what; 13 | #if PFC_DEBUG 14 | const DWORD code = GetLastError(); 15 | PFC_ASSERT(code != NO_ERROR); 16 | #endif 17 | pfc::crash(); 18 | #if 0 19 | pfc::string_formatter msg; msg << what << " failure #" << (uint32_t)code; 20 | TRACK_CODE(msg.get_ptr(), uBugCheck()); 21 | #endif 22 | } 23 | 24 | #if PFC_DEBUG 25 | void WIN32_OP_D_FAIL(const wchar_t * _Message, const wchar_t *_File, unsigned _Line) { 26 | const DWORD code = GetLastError(); 27 | pfc::array_t msgFormatted; msgFormatted.set_size(pfc::strlen_t(_Message) + 64); 28 | wsprintfW(msgFormatted.get_ptr(), L"%s (code: %u)", _Message, code); 29 | if (IsDebuggerPresent()) { 30 | OutputDebugString(TEXT("WIN32_OP_D() failure:\n")); 31 | OutputDebugString(msgFormatted.get_ptr()); 32 | OutputDebugString(TEXT("\n")); 33 | pfc::crash(); 34 | } 35 | _wassert(msgFormatted.get_ptr(), _File, _Line); 36 | } 37 | #endif 38 | -------------------------------------------------------------------------------- /libPPUI/win32_op.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | PFC_NORETURN PFC_NOINLINE void WIN32_OP_FAIL(); 4 | PFC_NORETURN PFC_NOINLINE void WIN32_OP_FAIL_CRITICAL(const char * what); 5 | 6 | #ifdef _DEBUG 7 | void WIN32_OP_D_FAIL(const wchar_t * _Message, const wchar_t *_File, unsigned _Line); 8 | #endif 9 | 10 | //Throws an exception when (OP) evaluates to false/zero. 11 | #define WIN32_OP(OP) \ 12 | { \ 13 | SetLastError(NO_ERROR); \ 14 | if (!(OP)) WIN32_OP_FAIL(); \ 15 | } 16 | 17 | // Kills the application with appropriate debug info when (OP) evaluates to false/zero. 18 | #define WIN32_OP_CRITICAL(WHAT, OP) \ 19 | { \ 20 | SetLastError(NO_ERROR); \ 21 | if (!(OP)) WIN32_OP_FAIL_CRITICAL(WHAT); \ 22 | } 23 | 24 | //WIN32_OP_D() acts like an assert specialized for win32 operations in debug build, ignores the return value / error codes in release build. 25 | //Use WIN32_OP_D() instead of WIN32_OP() on operations that are extremely unlikely to fail, so failure condition checks are performed in the debug build only, to avoid bloating release code with pointless error checks. 26 | #ifdef _DEBUG 27 | #define WIN32_OP_D(OP) \ 28 | { \ 29 | SetLastError(NO_ERROR); \ 30 | if (!(OP)) WIN32_OP_D_FAIL(PFC_WIDESTRING(#OP), PFC_WIDESTRING(__FILE__), __LINE__); \ 31 | } 32 | 33 | #else 34 | #define WIN32_OP_D(OP) (void)( (OP), 0); 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /pfc/CFObject.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace pfc { 6 | template 7 | class CFObject { 8 | public: 9 | typedef CFObject self_t; 10 | type_t p = NULL; 11 | 12 | ~CFObject() { 13 | if ( p ) CFRelease(p); 14 | } 15 | 16 | void Retain(type_t arg) { 17 | if ( p ) CFRelease(p); 18 | p = arg; 19 | if ( p ) CFRetain(p); 20 | } 21 | 22 | void Attach(type_t arg) { 23 | if ( p ) CFRelease(p); 24 | p = arg; 25 | } 26 | 27 | void operator=( self_t const & arg ) { 28 | if ( p ) CFRelease(p); 29 | p = arg.p; 30 | if ( p ) CFRetain(p); 31 | } 32 | CFObject() {} 33 | CFObject( self_t const & arg ) { 34 | p = arg.p; 35 | if ( p ) CFRetain(p); 36 | } 37 | 38 | CFObject(self_t && arg ) { 39 | p = arg.p; arg.p = NULL; 40 | } 41 | void operator=(self_t && arg) { 42 | if ( p ) CFRelease(p); 43 | p = arg.p; arg.p = NULL; 44 | } 45 | 46 | operator bool() const { return p != NULL; } 47 | operator type_t() const { return p;} 48 | 49 | 50 | void reset() { 51 | if ( p ) CFRelease(p); 52 | p = NULL; 53 | } 54 | 55 | void operator=(nullptr_t) { 56 | reset(); 57 | } 58 | }; 59 | } 60 | -------------------------------------------------------------------------------- /pfc/SmartStrStr-twoCharMappings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | static constexpr struct { 4 | unsigned from; 5 | const char* to; 6 | } twoCharMappings[] = { 7 | {0x00C6, "AE"}, 8 | {0x00E6, "ae"}, 9 | {0x00DF, "ss"}, 10 | 11 | #if 0 12 | // umlauts 13 | // the problem with these is that changing them to two-letter represenatations prevents search by non-umlaut vowel from working. 14 | {0x00C4, "AE"}, 15 | {0x00E4, "ae"}, 16 | {0x00D6, "OE"}, 17 | {0x00F6, "oe"}, 18 | {0x00DC, "UE"}, 19 | {0x00FC, "ue"}, 20 | #endif 21 | 22 | #if 0 23 | // Incomplete list, hence disabled. Nobody uses these. 24 | {0x01E2, "AE"}, 25 | {0x01FC, "AE"}, 26 | {0x01E3, "ae"}, 27 | {0x01FD, "ae"}, 28 | {0x0152, "OE"}, 29 | {0x0153, "oe"}, 30 | {0x0276, "oe"}, 31 | {0x01C3, "dz"}, 32 | {0x01C4, "DZ"}, 33 | {0x01C5, "Dz"}, 34 | {0x01C6, "dz"}, 35 | {0x01F1, "DZ"}, 36 | {0x01F2, "Dz"}, 37 | {0x01F3, "dz"}, 38 | {0x02A3, "dz"}, 39 | {0x02A5, "dz"}, 40 | {0x01C7, "LJ"}, 41 | {0x01C8, "Lj"}, 42 | {0x01C9, "lj"}, 43 | {0x01CA, "NJ"}, 44 | {0x01CB, "Nj"}, 45 | {0x01CC, "nj"}, 46 | {0x0132, "IJ"}, 47 | {0x0133, "ij"}, 48 | #endif 49 | }; 50 | -------------------------------------------------------------------------------- /pfc/autoref.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "ptrholder.h" 4 | 5 | namespace pfc { 6 | 7 | // autoref<> : turn arbitrary ptr that needs to be delete'd into a shared_ptr<> alike 8 | template class autoref { 9 | public: 10 | autoref() {} 11 | autoref(std::nullptr_t) {} 12 | autoref(obj_t * source) { 13 | attach(source); 14 | } 15 | void attach(obj_t * source) { 16 | PFC_ASSERT( source != nullptr ); 17 | m_obj = std::make_shared(source); 18 | } 19 | void reset() { 20 | m_obj.reset(); 21 | } 22 | 23 | obj_t * operator->() const { 24 | return m_obj->get_ptr(); 25 | } 26 | 27 | obj_t * get() const { 28 | if (! m_obj ) return nullptr; 29 | return m_obj->get_ptr(); 30 | } 31 | 32 | operator bool() const { 33 | return !!m_obj; 34 | } 35 | private: 36 | typedef pfc::ptrholder_t< obj_t > holder_t; 37 | std::shared_ptr< holder_t > m_obj; 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /pfc/base64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace pfc { 4 | class string_base; 5 | void base64_encode(pfc::string_base & out, const void * in, t_size inSize); 6 | void base64_encode_append(pfc::string_base & out, const void * in, t_size inSize); 7 | void base64_encode_from_string( pfc::string_base & out, const char * in ); 8 | t_size base64_decode_estimate(const char * text); 9 | void base64_decode(const char * text, void * out); 10 | mem_block base64_decode(const char* text); 11 | 12 | template void base64_decode_array(t_buffer & out, const char * text) { 13 | PFC_STATIC_ASSERT( sizeof(out[0]) == 1 ); 14 | out.set_size_discard( base64_decode_estimate(text) ); 15 | base64_decode(text, out.get_ptr()); 16 | } 17 | 18 | void base64_decode_to_string( pfc::string_base & out, const char * text ); 19 | } 20 | -------------------------------------------------------------------------------- /pfc/bigmem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "array.h" 4 | 5 | namespace pfc { 6 | class bigmem { 7 | public: 8 | enum {slice = 1024*1024}; 9 | bigmem() : m_size() {} 10 | ~bigmem() {clear();} 11 | 12 | void resize(size_t newSize); 13 | size_t size() const {return m_size;} 14 | void clear(); 15 | void read(void * ptrOut, size_t bytes, size_t offset) const; 16 | void write(const void * ptrIn, size_t bytes, size_t offset); 17 | uint8_t * _slicePtr(size_t which); 18 | size_t _sliceCount(); 19 | size_t _sliceSize(size_t which); 20 | private: 21 | array_t m_data; 22 | size_t m_size; 23 | 24 | PFC_CLASS_NOT_COPYABLE_EX(bigmem) 25 | }; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /pfc/bsearch.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc-lite.h" 2 | #include "bsearch.h" 3 | #include "bsearch_inline.h" 4 | 5 | //deprecated 6 | 7 | /* 8 | class NOVTABLE bsearch_callback 9 | { 10 | public: 11 | virtual int test(t_size p_index) const = 0; 12 | }; 13 | */ 14 | 15 | namespace pfc { 16 | 17 | bool bsearch(t_size p_count, bsearch_callback const & p_callback,t_size & p_result) { 18 | return bsearch_inline_t(p_count,p_callback,p_result); 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /pfc/cmd_thread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wait_queue.h" 4 | #include 5 | #include 6 | #include 7 | 8 | namespace pfc { 9 | 10 | class cmdThread { 11 | public: 12 | typedef std::function cmd_t; 13 | typedef pfc::waitQueue queue_t; 14 | 15 | void add(cmd_t c) { 16 | std::call_once(m_once, [this] { 17 | auto q = std::make_shared(); 18 | pfc::splitThread([q] { 19 | cmd_t cmd; 20 | while (q->get(cmd)) { 21 | cmd(); 22 | } 23 | }); 24 | m_queue = q; 25 | }); 26 | m_queue->put(c); 27 | } 28 | 29 | void shutdown() { 30 | if (m_queue) { 31 | m_queue->set_eof(); 32 | m_queue.reset(); 33 | } 34 | } 35 | ~cmdThread() { 36 | shutdown(); 37 | } 38 | private: 39 | 40 | std::shared_ptr< queue_t > m_queue; 41 | 42 | 43 | std::once_flag m_once; 44 | }; 45 | 46 | } -------------------------------------------------------------------------------- /pfc/cpuid.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // CPUID stuff supported only on MSVC for now, irrelevant for non x86 4 | #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) 5 | #define PFC_HAVE_CPUID 1 6 | namespace pfc { 7 | enum { 8 | CPU_HAVE_SSE = 1 << 2, 9 | CPU_HAVE_SSE2 = 1 << 3, 10 | CPU_HAVE_SSE3 = 1 << 4, 11 | CPU_HAVE_SSSE3 = 1 << 5, 12 | CPU_HAVE_SSE41 = 1 << 6, 13 | CPU_HAVE_SSE42 = 1 << 7, 14 | CPU_HAVE_AVX = 1 << 8, 15 | }; 16 | 17 | bool query_cpu_feature_set(unsigned p_value); 18 | }; 19 | #endif 20 | 21 | #ifndef PFC_HAVE_CPUID 22 | #define PFC_HAVE_CPUID 0 23 | #endif 24 | 25 | namespace pfc { 26 | const char* cpuArch(); 27 | } 28 | 29 | #ifdef _M_ARM64EC 30 | #define PFC_CPU_ARCH "ARM64EC" 31 | #elif defined(_M_X64) || defined(__x86_64__) 32 | #define PFC_CPU_ARCH "x64" 33 | #elif defined(_M_IX86) || defined(__i386__) 34 | #define PFC_CPU_ARCH "x86" 35 | #elif defined(_M_ARM64) || defined(__aarch64__) 36 | #define PFC_CPU_ARCH "ARM64" 37 | #elif defined(_M_ARM) || defined(__arm__) 38 | #define PFC_CPU_ARCH "ARM" 39 | #endif 40 | -------------------------------------------------------------------------------- /pfc/event.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // All in win-objects.h & nix-objects.h 4 | #include "platform-objects.h" -------------------------------------------------------------------------------- /pfc/filehandle.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc-lite.h" 2 | #include "filehandle.h" 3 | 4 | #ifndef _WIN32 5 | #include 6 | #endif 7 | 8 | namespace pfc { 9 | void fileHandleClose( fileHandle_t h ) noexcept { 10 | if (h == fileHandleInvalid) return; 11 | #ifdef _WIN32 12 | CloseHandle( h ); 13 | #else 14 | close( h ); 15 | #endif 16 | } 17 | 18 | fileHandle_t fileHandleDup( fileHandle_t h ) { 19 | #ifdef _WIN32 20 | auto proc = GetCurrentProcess(); 21 | HANDLE out; 22 | if (!DuplicateHandle ( proc, h, proc, &out, 0, FALSE, DUPLICATE_SAME_ACCESS )) return fileHandleInvalid; 23 | return out; 24 | #else 25 | return dup( h ); 26 | #endif 27 | } 28 | 29 | void fileHandle::close() noexcept { 30 | fileHandleClose( h ); 31 | clear(); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /pfc/filehandle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace pfc { 4 | #ifdef _WIN32 5 | typedef HANDLE fileHandle_t; 6 | const fileHandle_t fileHandleInvalid = INVALID_HANDLE_VALUE; 7 | #else 8 | typedef int fileHandle_t; 9 | constexpr fileHandle_t fileHandleInvalid = -1; 10 | #endif 11 | 12 | void fileHandleClose( fileHandle_t h ) noexcept; 13 | fileHandle_t fileHandleDup( fileHandle_t h ); 14 | 15 | class fileHandle { 16 | public: 17 | fileHandle( fileHandle_t val ) : h(val) {} 18 | fileHandle() : h ( fileHandleInvalid ) {} 19 | ~fileHandle() noexcept { close(); } 20 | fileHandle( fileHandle && other ) noexcept { h = other.h; other.clear(); } 21 | void operator=( fileHandle && other ) noexcept { close(); h = other.h; other.clear(); } 22 | void operator=( fileHandle_t other ) { close(); h = other; } 23 | void close() noexcept; 24 | void clear() noexcept { h = fileHandleInvalid; } 25 | bool isValid() noexcept { return h != fileHandleInvalid; } 26 | fileHandle_t h; 27 | private: 28 | fileHandle( const fileHandle & ) = delete; 29 | void operator=( const fileHandle & ) = delete; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /pfc/filetimetools.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace pfc { 4 | typedef uint64_t t_filetimestamp; 5 | static constexpr t_filetimestamp filetimestamp_invalid = 0; 6 | static constexpr t_filetimestamp filetimestamp_1second_increment = 10000000; 7 | 8 | t_filetimestamp filetimestamp_from_string(const char * date); 9 | t_filetimestamp filetimestamp_from_string_utc(const char* date); 10 | // From ISO 8601 time 11 | t_filetimestamp filetimestamp_from_string_ISO_8601(const char* date); 12 | 13 | //! Warning: this formats according to system timezone settings, created strings should be used for display only, never for storage. 14 | pfc::string_formatter format_filetimestamp(t_filetimestamp p_timestamp); 15 | //! UTC timestamp 16 | pfc::string_formatter format_filetimestamp_utc(t_filetimestamp p_timestamp); 17 | //! Local timestamp with milliseconds 18 | pfc::string_formatter format_filetimestamp_ms(t_filetimestamp p_timestamp); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /pfc/fixed_map.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | template class fixed_map { 8 | public: 9 | typedef std::map source_t; 10 | 11 | void initialize(source_t&& src) { 12 | const size_t size = src.size(); 13 | m_keys.resize(size); m_values.resize(size); 14 | size_t walk = 0; 15 | for (auto iter = src.begin(); iter != src.end(); ++iter) { 16 | m_keys[walk] = iter->first; 17 | m_values[walk] = std::move(iter->second); 18 | ++walk; 19 | } 20 | src.clear(); 21 | } 22 | 23 | value_t query(key_t key) const { 24 | auto iter = std::lower_bound(m_keys.begin(), m_keys.end(), key); 25 | if (iter == m_keys.end() || *iter != key) return 0; 26 | return m_values[iter - m_keys.begin()]; 27 | } 28 | 29 | const value_t* query_ptr(key_t key) const { 30 | auto iter = std::lower_bound(m_keys.begin(), m_keys.end(), key); 31 | if (iter == m_keys.end() || *iter != key) return nullptr; 32 | return &m_values[iter - m_keys.begin()]; 33 | } 34 | private: 35 | std::vector m_keys; 36 | std::vector m_values; 37 | }; -------------------------------------------------------------------------------- /pfc/fpu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _MSC_VER 4 | 5 | class fpu_control 6 | { 7 | unsigned old_val; 8 | unsigned mask; 9 | public: 10 | inline fpu_control(unsigned p_mask,unsigned p_val) 11 | { 12 | mask = p_mask; 13 | _controlfp_s(&old_val,p_val,mask); 14 | } 15 | inline ~fpu_control() 16 | { 17 | unsigned dummy; 18 | _controlfp_s(&dummy,old_val,mask); 19 | } 20 | }; 21 | 22 | class fpu_control_roundnearest : private fpu_control 23 | { 24 | public: 25 | fpu_control_roundnearest() : fpu_control(_MCW_RC,_RC_NEAR) {} 26 | }; 27 | 28 | class fpu_control_flushdenormal : private fpu_control 29 | { 30 | public: 31 | fpu_control_flushdenormal() : fpu_control(_MCW_DN,_DN_FLUSH) {} 32 | }; 33 | 34 | class fpu_control_default : private fpu_control 35 | { 36 | public: 37 | fpu_control_default() : fpu_control(_MCW_DN|_MCW_RC,_DN_FLUSH|_RC_NEAR) {} 38 | }; 39 | 40 | #ifdef _M_IX86 41 | class sse_control { 42 | public: 43 | sse_control(unsigned p_mask,unsigned p_val) : m_mask(p_mask) { 44 | __control87_2(p_val,p_mask,NULL,&m_oldval); 45 | } 46 | ~sse_control() { 47 | __control87_2(m_oldval,m_mask,NULL,&m_oldval); 48 | } 49 | private: 50 | unsigned m_mask,m_oldval; 51 | }; 52 | class sse_control_flushdenormal : private sse_control { 53 | public: 54 | sse_control_flushdenormal() : sse_control(_MCW_DN,_DN_FLUSH) {} 55 | }; 56 | #endif 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /pfc/guid.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "primitives.h" 4 | 5 | namespace pfc { 6 | 7 | GUID GUID_from_text(const char * text); 8 | 9 | inline int guid_compare(const GUID & g1,const GUID & g2) {return memcmp(&g1,&g2,sizeof(GUID));} 10 | 11 | inline bool guid_equal(const GUID & g1,const GUID & g2) {return (g1 == g2) ? true : false;} 12 | template<> inline int compare_t(const GUID & p_item1,const GUID & p_item2) {return guid_compare(p_item1,p_item2);} 13 | 14 | static constexpr GUID guid_null = {}; 15 | 16 | void print_hex_raw(const void * buffer,unsigned bytes,char * p_out); 17 | 18 | inline GUID makeGUID(t_uint32 Data1, t_uint16 Data2, t_uint16 Data3, t_uint8 Data4_1, t_uint8 Data4_2, t_uint8 Data4_3, t_uint8 Data4_4, t_uint8 Data4_5, t_uint8 Data4_6, t_uint8 Data4_7, t_uint8 Data4_8) { 19 | GUID guid = { Data1, Data2, Data3, {Data4_1, Data4_2, Data4_3, Data4_4, Data4_5, Data4_6, Data4_7, Data4_8 } }; 20 | return guid; 21 | } 22 | inline GUID xorGUID(const GUID & v1, const GUID & v2) { 23 | GUID temp; memxor(&temp, &v1, &v2, sizeof(GUID)); return temp; 24 | } 25 | 26 | string8 format_guid_cpp( const GUID & ); 27 | string8 print_guid( const GUID & ); 28 | 29 | GUID createGUID(); 30 | uint64_t halveGUID( const GUID & ); 31 | 32 | struct predicateGUID { 33 | inline bool operator() ( const GUID & v1, const GUID & v2 ) const {return guid_compare(v1, v2) > 0;} 34 | }; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /pfc/instance_tracker_legacy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // OBSOLETE, DO NOT USE 3 | namespace pfc { 4 | template 5 | class instance_tracker_server_t { 6 | public: 7 | void add(t_object * p_object) { 8 | m_list.add_item(p_object); 9 | } 10 | void remove(t_object * p_object) { 11 | m_list.remove_item(p_object); 12 | } 13 | 14 | t_size get_count() const {return m_list.get_count();} 15 | t_object * get_item(t_size p_index) {return m_list[p_index];} 16 | t_object * operator[](t_size p_index) {return m_list[p_index];} 17 | 18 | private: 19 | ptr_list_hybrid_t m_list; 20 | }; 21 | 22 | 23 | template & p_server> 24 | class instance_tracker_client_t { 25 | public: 26 | instance_tracker_client_t(t_object* p_ptr) : m_ptr(NULL), m_added(false) {initialize(p_ptr);} 27 | instance_tracker_client_t() : m_ptr(NULL), m_added(false) {} 28 | 29 | void initialize(t_object * p_ptr) { 30 | uninitialize(); 31 | p_server.add(p_ptr); 32 | m_ptr = p_ptr; 33 | m_added = true; 34 | } 35 | 36 | void uninitialize() { 37 | if (m_added) { 38 | p_server.remove(m_ptr); 39 | m_ptr = NULL; 40 | m_added = false; 41 | } 42 | } 43 | 44 | ~instance_tracker_client_t() { 45 | uninitialize(); 46 | } 47 | private: 48 | bool m_added; 49 | t_object * m_ptr; 50 | }; 51 | } -------------------------------------------------------------------------------- /pfc/killswitch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace pfc { 6 | struct killSwitchData_t { 7 | killSwitchData_t() : m_val() {} 8 | volatile bool m_val; 9 | }; 10 | 11 | 12 | typedef std::shared_ptr killSwitchRef_t; 13 | 14 | class killSwitchRef { 15 | public: 16 | killSwitchRef( killSwitchRef_t ks ) : m_ks(ks) {} 17 | 18 | operator bool () const { 19 | return m_ks->m_val; 20 | } 21 | 22 | void set(bool val = true) { 23 | m_ks->m_val = val; 24 | } 25 | private: 26 | killSwitchRef_t m_ks; 27 | }; 28 | 29 | killSwitchRef killSwitchMake() { 30 | return std::make_shared(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pfc/lockless.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _MSC_VER 4 | #include 5 | #endif 6 | namespace pfc { 7 | 8 | class threadSafeInt { 9 | public: 10 | typedef long val_t; 11 | typedef val_t t_val; 12 | 13 | threadSafeInt(t_val p_val = 0) : m_val(p_val) {} 14 | long operator++() throw() { return inc(); } 15 | long operator--() throw() { return dec(); } 16 | long operator++(int) throw() { return inc() - 1; } 17 | long operator--(int) throw() { return dec() + 1; } 18 | operator t_val() const throw() { return m_val; } 19 | 20 | static val_t exchangeHere( volatile val_t & here, val_t newVal ) { 21 | #ifdef _MSC_VER 22 | return InterlockedExchange(&here, newVal); 23 | #else 24 | return __sync_lock_test_and_set(&here, newVal); 25 | #endif 26 | } 27 | 28 | t_val exchange(t_val newVal) { 29 | return exchangeHere( m_val, newVal ); 30 | } 31 | private: 32 | t_val inc() { 33 | #ifdef _MSC_VER 34 | return _InterlockedIncrement(&m_val); 35 | #else 36 | return __sync_add_and_fetch(&m_val, 1); 37 | #endif 38 | } 39 | t_val dec() { 40 | #ifdef _MSC_VER 41 | return _InterlockedDecrement(&m_val); 42 | #else 43 | return __sync_sub_and_fetch(&m_val, 1); 44 | #endif 45 | } 46 | 47 | volatile t_val m_val; 48 | }; 49 | 50 | typedef threadSafeInt counter; 51 | typedef threadSafeInt refcounter; 52 | 53 | void yield(); // forward declaration 54 | 55 | } 56 | -------------------------------------------------------------------------------- /pfc/once.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "event.h" 5 | #include 6 | #include "lockless.h" 7 | 8 | #ifdef __ANDROID__ 9 | #define PFC_CUSTOM_ONCE_FLAG 1 10 | #endif 11 | 12 | #ifndef PFC_CUSTOM_ONCE_FLAG 13 | #define PFC_CUSTOM_ONCE_FLAG 0 14 | #endif 15 | 16 | #if ! PFC_CUSTOM_ONCE_FLAG 17 | #include 18 | #endif 19 | 20 | namespace pfc { 21 | #if PFC_CUSTOM_ONCE_FLAG 22 | struct once_flag { 23 | bool inProgress = false, done = false; 24 | std::shared_ptr<::pfc::event> waitFor; 25 | }; 26 | 27 | void call_once( once_flag &, std::function ); 28 | #else 29 | using std::once_flag; 30 | using std::call_once; 31 | #endif 32 | 33 | //! Minimalist class to call some function only once. \n 34 | //! Presumes low probability of concurrent run() calls actually happening, \n 35 | //! but frequent calls once already initialized, hence only using basic volatile bool check. \n 36 | //! If using a modern compiler you might want to use std::call_once instead. \n 37 | //! The called function is not expected to throw exceptions. 38 | struct once_flag_lite { 39 | threadSafeInt::val_t guard = 0; 40 | volatile bool done = false; 41 | }; 42 | 43 | void call_once( once_flag_lite &, std::function ); 44 | 45 | class runOnceLock { 46 | public: 47 | void run(std::function f) {call_once(m_flag, f);} 48 | private: 49 | once_flag_lite m_flag; 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /pfc/pfc-fb2k-hooks.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc-lite.h" 2 | #include "pfc-fb2k-hooks.h" 3 | 4 | #include "suppress_fb2k_hooks.h" 5 | -------------------------------------------------------------------------------- /pfc/pfc-fb2k-hooks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace pfc { 4 | [[noreturn]] void crashImpl(); 5 | [[noreturn]] void crashHook(); 6 | #ifdef _WIN32 7 | BOOL winFormatSystemErrorMessageImpl(pfc::string_base & p_out, DWORD p_code); 8 | BOOL winFormatSystemErrorMessageHook(pfc::string_base & p_out, DWORD p_code); 9 | #endif 10 | } 11 | -------------------------------------------------------------------------------- /pfc/pfc-license.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2002-2024 Peter Pawlowski 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------------------------- /pfc/pfc-readme.txt: -------------------------------------------------------------------------------- 1 | PFC : Peter's Foundation Classes 2 | 3 | A library of loosely connected classes used by foobar2000 codebase; freely available and reusable for other projects. 4 | 5 | PFC is not state-of-art code. Many parts of it exist only to keep old bits of foobar2000 codebase ( also third party foobar2000 components ) compiling without modification. For an example, certain classes predating 'pfc' namespace use exist outside the namespace. 6 | 7 | Regarding build configurations- 8 | "Release FB2K" and "Debug FB2K" suppress the compilation of pfc-fb2k-hooks.cpp - which allows relevant calls to be redirected to shared.dll 9 | These configurations should be used when compiling fb2k components. Regular configurations should be used for non fb2k apps instead. -------------------------------------------------------------------------------- /pfc/platform-objects.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _WIN32 4 | #include "win-objects.h" 5 | #else 6 | #include "nix-objects.h" 7 | #endif 8 | 9 | -------------------------------------------------------------------------------- /pfc/pool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "synchro.h" 3 | #include 4 | #include 5 | 6 | namespace pfc { 7 | template 8 | class objPool { 9 | public: 10 | objPool() : m_maxCount(pfc_infinite) {} 11 | typedef std::shared_ptr objRef_t; 12 | 13 | objRef_t get() { 14 | insync(m_sync); 15 | auto i = m_pool.begin(); 16 | if ( i == m_pool.end() ) return nullptr; 17 | auto ret = *i; 18 | m_pool.erase(i); 19 | return ret; 20 | } 21 | objRef_t make() { 22 | auto obj = get(); 23 | if ( ! obj ) obj = std::make_shared(); 24 | return obj; 25 | } 26 | void setMaxCount(size_t c) { 27 | insync(m_sync); 28 | m_maxCount = c; 29 | } 30 | void put(objRef_t obj) { 31 | insync(m_sync); 32 | if ( m_pool.size() < m_maxCount ) { 33 | m_pool.push_back(obj); 34 | } 35 | } 36 | private: 37 | size_t m_maxCount; 38 | std::list m_pool; 39 | critical_section m_sync; 40 | }; 41 | 42 | } -------------------------------------------------------------------------------- /pfc/primitives_part2.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace pfc { 4 | template 5 | static bool guess_reorder_pattern(pfc::array_t & out, const t_list1 & from, const t_list2 & to) { 6 | typedef typename t_list1::t_item t_item; 7 | const t_size count = from.get_size(); 8 | if (count != to.get_size()) return false; 9 | out.set_size(count); 10 | for(t_size walk = 0; walk < count; ++walk) out[walk] = walk; 11 | //required output: to[n] = from[out[n]]; 12 | typedef pfc::chain_list_v2_t t_queue; 13 | pfc::map_t content; 14 | for(t_size walk = 0; walk < count; ++walk) { 15 | content.find_or_add(from[walk]).add_item(walk); 16 | } 17 | for(t_size walk = 0; walk < count; ++walk) { 18 | t_queue * q = content.query_ptr(to[walk]); 19 | if (q == NULL) return false; 20 | if (q->get_count() == 0) return false; 21 | out[walk] = *q->first(); 22 | q->remove(q->first()); 23 | } 24 | return true; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /pfc/ptr_list.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "list.h" 3 | 4 | namespace pfc { 5 | 6 | template > 7 | class ptr_list_t : public B { 8 | public: 9 | typedef ptr_list_t self_t; 10 | 11 | void free_by_idx(t_size n) {free_mask(bit_array_one(n));} 12 | void free_all() {this->remove_all_ex(free);} 13 | void free_mask(const bit_array & p_mask) {this->remove_mask_ex(p_mask,free);} 14 | 15 | void delete_item(T* ptr) {delete_by_idx(find_item(ptr));} 16 | 17 | void delete_by_idx(t_size p_index) { 18 | delete_mask(bit_array_one(p_index)); 19 | } 20 | 21 | void delete_all() { 22 | this->remove_all_ex(pfc::delete_t); 23 | } 24 | 25 | void delete_mask(const bit_array & p_mask) { 26 | this->remove_mask_ex(p_mask,pfc::delete_t); 27 | } 28 | 29 | T * operator[](t_size n) const {return this->get_item(n);} 30 | }; 31 | 32 | template 33 | class ptr_list_hybrid_t : public ptr_list_t > { 34 | public: 35 | }; 36 | 37 | typedef ptr_list_t ptr_list; 38 | 39 | template class traits_t > : public traits_t {}; 40 | } 41 | -------------------------------------------------------------------------------- /pfc/sort2.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "sort.h" 4 | 5 | // 2023 additions 6 | 7 | 8 | namespace pfc { 9 | 10 | typedef array_t permutation_t; 11 | 12 | permutation_t make_identitiy(size_t); 13 | 14 | template 15 | permutation_t sort_get_permutation(container_t const& data, compare_t compare) { 16 | const size_t count = std::size(data); 17 | auto ret = make_identitiy( count ); 18 | if ( count > 0 ) sort_get_permutation_t(data, compare, count, ret.get_ptr() ); 19 | return ret; 20 | } 21 | template 22 | permutation_t sort_stable_get_permutation(container_t const& data, compare_t compare) { 23 | const size_t count = std::size(data); 24 | auto ret = make_identitiy( count ); 25 | if ( count > 0 ) sort_stable_get_permutation_t(data, compare, count, ret.get_ptr() ); 26 | return ret; 27 | } 28 | 29 | template 30 | void reorder(container_t& data, permutation_t const& order) { 31 | PFC_ASSERT( std::size(data) == std::size(order) ); 32 | reorder_t( data, order.get_ptr(), order.get_size() ); 33 | } 34 | } -------------------------------------------------------------------------------- /pfc/sortstring.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _WIN32 4 | #include // std::unique_ptr<> 5 | #endif 6 | #ifdef __APPLE__ 7 | #include "CFObject.h" 8 | #endif 9 | 10 | namespace pfc { 11 | #ifdef _WIN32 12 | typedef std::unique_ptr sortString_t; 13 | sortString_t makeSortString(const char* str); 14 | sortString_t makeSortString(const wchar_t* str); 15 | int sortStringCompare(sortString_t const& s1, sortString_t const& s2); 16 | int sortStringCompareI(sortString_t const& s1, sortString_t const& s2); 17 | #elif defined(__APPLE__) 18 | typedef CFObject sortString_t; 19 | sortString_t makeSortString(const char* str); 20 | int sortStringCompare(sortString_t const& s1, sortString_t const& s2); 21 | int sortStringCompareI(sortString_t const& s1, sortString_t const& s2); 22 | #else 23 | #define PFC_SORTSTRING_GENERIC 24 | typedef pfc::string8 sortString_t; 25 | inline sortString_t makeSortString(const char* str) { return str; } 26 | inline sortString_t makeSortString(pfc::string8&& str) { return std::move(str); } 27 | int sortStringCompare(const char* str1, const char* str2); 28 | int sortStringCompareI(const char* str1, const char* str2); 29 | #endif 30 | } 31 | -------------------------------------------------------------------------------- /pfc/splitString2.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc-lite.h" 2 | #include "pfc.h" 3 | #include "splitString.h" 4 | #include "splitString2.h" 5 | 6 | namespace { 7 | class counter_t { 8 | public: 9 | size_t count = 0; 10 | inline void operator+=(pfc::string_part_ref const& p) { ++count; } 11 | }; 12 | template 13 | class wrapper_t { 14 | public: 15 | ret_t * ret; 16 | 17 | inline void operator+=(pfc::string_part_ref const & p) { 18 | ret->emplace_back(p); 19 | } 20 | }; 21 | } 22 | 23 | namespace pfc { 24 | 25 | std::list splitString2(const char* str, const char* delim) { 26 | std::list ret; 27 | wrapper_t w; w.ret = &ret; 28 | pfc::splitStringBySubstring(w, str, delim); 29 | return ret; 30 | } 31 | std::list splitStringByLines2(const char* str) { 32 | std::list ret; 33 | wrapper_t w; w.ret = &ret; 34 | pfc::splitStringByLines(w, str); 35 | return ret; 36 | } 37 | 38 | std::vector splitString2v(const char* str, const char* delim) { 39 | counter_t counter; 40 | pfc::splitStringBySubstring(counter, str, delim); 41 | std::vector ret; ret.reserve(counter.count); 42 | wrapper_t w; w.ret = &ret; 43 | pfc::splitStringBySubstring(w, str, delim); 44 | return ret; 45 | 46 | } 47 | std::vector splitStringByLines2v(const char* str) { 48 | counter_t counter; 49 | pfc::splitStringByLines(counter, str); 50 | std::vector ret; ret.reserve(counter.count); 51 | wrapper_t w; w.ret = &ret; 52 | pfc::splitStringByLines(w, str); 53 | return ret; 54 | } 55 | 56 | } -------------------------------------------------------------------------------- /pfc/splitString2.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | namespace pfc { 5 | std::list splitString2(const char* str, const char* delim); 6 | std::list splitStringByLines2(const char* str); 7 | std::vector splitString2v(const char* str, const char* delim); 8 | std::vector splitStringByLines2v(const char* str); 9 | } -------------------------------------------------------------------------------- /pfc/stdafx.cpp: -------------------------------------------------------------------------------- 1 | //cpp used to generate precompiled header 2 | #include "pfc-lite.h" -------------------------------------------------------------------------------- /pfc/stdsort.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // OPTIONAL pfc feature, include on need to use basis 4 | // std sort interop methods 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace pfc { 11 | 12 | std::vector sort_identity( size_t count ) { 13 | std::vector ret; ret.resize(count); 14 | for( size_t walk = 0; walk < ret.size(); ++ walk) ret[walk] = walk; 15 | return ret; 16 | } 17 | 18 | template 19 | std::vector sort_get_order(iterator_t i1, iterator_t i2, predicate_t pred ) { 20 | auto ret = sort_identity( i2 - i1 ); 21 | auto pred2 = [pred, i1] (size_t idx1, size_t idx2) { 22 | return pred( *(i1+idx1), *(i1+idx2)); 23 | }; 24 | std::sort(ret.begin(), ret.end(), pred2); 25 | return ret; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /pfc/string-conv-lite.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc-lite.h" 2 | #include "string_conv.h" 3 | #include "string-conv-lite.h" 4 | 5 | namespace pfc { 6 | wstringLite wideFromUTF8(const char* pUTF8, size_t inSize) { 7 | wstringLite ret; 8 | size_t estimate = pfc::stringcvt::estimate_utf8_to_wide(pUTF8, inSize); 9 | ret.m_buffer.resize(estimate); 10 | pfc::stringcvt::convert_utf8_to_wide(ret.m_buffer.get_ptr(), estimate, pUTF8, inSize); 11 | return ret; 12 | } 13 | string8 utf8FromWide(const wchar_t* pWide, size_t inSize) { 14 | string8 ret; 15 | size_t estimate = pfc::stringcvt::estimate_wide_to_utf8(pWide,inSize); 16 | PFC_ASSERT(estimate > 0); 17 | char* ptr = ret.lock_buffer(estimate-1/*nullterm included in estimate*/); 18 | pfc::stringcvt::convert_wide_to_utf8(ptr, estimate, pWide, inSize); 19 | ret.unlock_buffer(); 20 | return ret; 21 | } 22 | wstringLite wideFromUTF8(const char* pUTF8) { 23 | wstringLite ret; 24 | size_t estimate = pfc::stringcvt::estimate_utf8_to_wide(pUTF8); 25 | ret.m_buffer.resize(estimate); 26 | pfc::stringcvt::convert_utf8_to_wide_unchecked(ret.m_buffer.get_ptr(), pUTF8); 27 | return ret; 28 | } 29 | string8 utf8FromWide(const wchar_t* pWide) { 30 | return utf8FromWide(pWide, SIZE_MAX); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pfc/string-conv-lite.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "array.h" 3 | #include "string_base.h" 4 | namespace pfc { 5 | 6 | class wstringLite { 7 | public: 8 | const wchar_t* c_str() const noexcept { 9 | return m_buffer.size() > 0 ? m_buffer.get_ptr() : L""; 10 | } 11 | operator const wchar_t* () const noexcept { return c_str(); } 12 | size_t length() const noexcept { return wcslen(c_str()); } 13 | 14 | pfc::array_t m_buffer; 15 | }; 16 | 17 | wstringLite wideFromUTF8(const char* pUTF8, size_t inSize); 18 | string8 utf8FromWide(const wchar_t* pWide, size_t inSize); 19 | 20 | wstringLite wideFromUTF8(const char* pUTF8); 21 | string8 utf8FromWide(const wchar_t* pWide); 22 | } -------------------------------------------------------------------------------- /pfc/string-part.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace pfc { 4 | struct string_part_ref { 5 | const char* m_ptr; 6 | t_size m_len; 7 | 8 | 9 | static string_part_ref make(const char* ptr, t_size len); 10 | string_part_ref substring(t_size base) const; 11 | string_part_ref substring(t_size base, t_size len) const; 12 | static string_part_ref make(const char* str); 13 | bool equals(string_part_ref other) const; 14 | bool equals(const char* str) const; 15 | }; 16 | 17 | inline string_part_ref string_part(const char* ptr, t_size len) { 18 | string_part_ref val = { ptr, len }; return val; 19 | } 20 | 21 | template static string_part_ref stringToRef(T const& val) { return string_part(stringToPtr(val), val.length()); } 22 | inline string_part_ref stringToRef(string_part_ref val) { return val; } 23 | inline string_part_ref stringToRef(const char* val) { return string_part(val, strlen(val)); } 24 | } -------------------------------------------------------------------------------- /pfc/suppress_fb2k_hooks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | foobar2000 shared.dll hook implementations 5 | If you're getting linker multiple-definition errors on these, change build configuration of PFC from "Debug" / "Release" to "Debug FB2K" / "Release FB2K" 6 | Configurations with "FB2K" suffix disable compilation of pfc-fb2k-hooks.cpp allowing these methods to be redirected to shared.dll calls 7 | */ 8 | 9 | namespace pfc { 10 | [[noreturn]] void crashImpl(); 11 | // Fix: error LNK2005: "void __cdecl pfc::crashHook(void)" (?crashHook@pfc@@YAXXZ) already defined in pfc.lib(pfc-fb2k-hooks.obj) 12 | /*[[noreturn]] void crashHook() { 13 | crashImpl(); 14 | }*/ 15 | #ifdef _WIN32 16 | BOOL winFormatSystemErrorMessageImpl(pfc::string_base & p_out, DWORD p_code); 17 | // Fix: error LNK2005: "int __cdecl pfc::winFormatSystemErrorMessageHook(class pfc::string_base &,unsigned long)" (?winFormatSystemErrorMessageHook@pfc@@YAHAAVstring_base@1@K@Z) already defined in pfc.lib(pfc-fb2k-hooks.obj) 18 | /*BOOL winFormatSystemErrorMessageHook(pfc::string_base& p_out, DWORD p_code) { 19 | return winFormatSystemErrorMessageImpl(p_out, p_code); 20 | }*/ 21 | #endif 22 | } 23 | -------------------------------------------------------------------------------- /pfc/synchro_nix.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc.h" 2 | 3 | #ifndef _WIN32 4 | 5 | namespace pfc { 6 | 7 | void mutexBase::create( const pthread_mutexattr_t * attr ) { 8 | if (pthread_mutex_init( &obj, attr) != 0) { 9 | throw exception_bug_check(); 10 | } 11 | } 12 | void mutexBase::destroy() { 13 | pthread_mutex_destroy( &obj ); 14 | } 15 | void mutexBase::createRecur() { 16 | mutexAttr a; a.setRecursive(); create(&a.attr); 17 | } 18 | void mutexBase::create( const mutexAttr & a ) { 19 | create( & a.attr ); 20 | } 21 | 22 | void readWriteLockBase::create( const pthread_rwlockattr_t * attr ) { 23 | if (pthread_rwlock_init( &obj, attr) != 0) { 24 | throw exception_bug_check(); 25 | } 26 | } 27 | void readWriteLockBase::create( const readWriteLockAttr & a) { 28 | create(&a.attr); 29 | } 30 | 31 | } 32 | 33 | #endif // _WIN32 34 | -------------------------------------------------------------------------------- /pfc/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _WIN32_WINNT 4 | #define _WIN32_WINNT 0x0601 5 | #include 6 | #endif -------------------------------------------------------------------------------- /pfc/threadSafeObj.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | namespace pfc { 3 | 4 | template 5 | struct threadSafeObjCommon { 6 | typedef mutex_t_ mutex_t; 7 | typedef obj_t_ obj_t; 8 | template threadSafeObjCommon( arg_t && ... arg ) : m_obj(std::forward(arg) ... ) {} 9 | mutex_t m_mutex; 10 | obj_t m_obj; 11 | }; 12 | 13 | template 14 | class threadSafeObjLock { 15 | typedef threadSafeObjLock self_t; 16 | common_t & m_common; 17 | public: 18 | typename common_t::obj_t & operator*() { return m_common.m_obj; } 19 | typename common_t::obj_t * operator->() { return & m_common.m_obj; } 20 | 21 | threadSafeObjLock( common_t & arg ) : m_common(arg) { m_common.m_mutex.lock(); } 22 | ~threadSafeObjLock( ) { m_common.m_mutex.unlock(); } 23 | threadSafeObjLock( const self_t & ) = delete; 24 | void operator=( const self_t & ) = delete; 25 | }; 26 | 27 | template 28 | class threadSafeObj { 29 | typedef threadSafeObjCommon common_t; 30 | typedef threadSafeObjLock lock_t; 31 | common_t m_common; 32 | public: 33 | template 34 | threadSafeObj( arg_t && ... arg ) : m_common( std::forward(arg) ... ) {} 35 | 36 | lock_t get() { return lock_t(m_common); } 37 | }; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /pfc/unicode-normalize.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace pfc { 4 | 5 | // Unicode normalization. 6 | // If you have no idea WTF this is about - good for you. The less you know the better for your sanity. 7 | 8 | // _Lite versions are simplified portable versions implemented using hardcoded tables, they're not meant to be complete. They cover only a subset of known two-char sequences. 9 | // Normal versions (not _Lite) are implemented using operating system methods where possible (MS, Apple), fall back to calling _Lite otherwise. 10 | 11 | // Normalize to form C 12 | pfc::string8 unicodeNormalizeC(const char * in); 13 | pfc::string8 unicodeNormalizeC_Lite(const char* in); 14 | 15 | // Normalize to form D 16 | pfc::string8 unicodeNormalizeD(const char* in); 17 | pfc::string8 unicodeNormalizeD_Lite(const char* in); 18 | 19 | bool stringContainsFormD(const char* in); 20 | } 21 | -------------------------------------------------------------------------------- /pfc/wildcard.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc-lite.h" 2 | #include "wildcard.h" 3 | #include "string_base.h" 4 | 5 | static bool test_recur(const char * fn,const char * rm,bool b_sep) 6 | { 7 | for(;;) 8 | { 9 | if ((b_sep && *rm==';') || *rm==0) return *fn==0; 10 | else if (*rm=='*') 11 | { 12 | rm++; 13 | do 14 | { 15 | if (test_recur(fn,rm,b_sep)) return true; 16 | } while(pfc::utf8_advance(fn)); 17 | return false; 18 | } 19 | else if (*fn==0) return false; 20 | else if (*rm!='?' && pfc::charLower(pfc::utf8_get_char(fn))!=pfc::charLower(pfc::utf8_get_char(rm))) return false; 21 | 22 | fn = pfc::utf8_char_next(fn); rm = pfc::utf8_char_next(rm); 23 | } 24 | } 25 | 26 | bool wildcard_helper::test_path(const char * path,const char * pattern,bool b_sep) {return test(path + pfc::scan_filename(path),pattern,b_sep);} 27 | 28 | bool wildcard_helper::test(const char * fn,const char * pattern,bool b_sep) 29 | { 30 | if (!b_sep) return test_recur(fn,pattern,false); 31 | const char * rm=pattern; 32 | while(*rm) 33 | { 34 | if (test_recur(fn,rm,true)) return true; 35 | while(*rm && *rm!=';') rm++; 36 | if (*rm==';') 37 | { 38 | while(*rm==';') rm++; 39 | while(*rm==' ') rm++; 40 | } 41 | }; 42 | 43 | return false; 44 | } 45 | 46 | bool wildcard_helper::has_wildcards(const char * str) {return strchr(str,'*') || strchr(str,'?');} 47 | 48 | const char * wildcard_helper::get_wildcard_list() {return "*?";} 49 | 50 | bool wildcard_helper::is_wildcard(char c) { 51 | return c == '*' || c == '?'; 52 | } 53 | -------------------------------------------------------------------------------- /pfc/wildcard.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace wildcard_helper 4 | { 5 | bool test_path(const char * path,const char * pattern,bool b_separate_by_semicolon = false);//will extract filename from path first 6 | bool test(const char * str,const char * pattern,bool b_separate_by_semicolon = false);//tests if str matches pattern 7 | bool has_wildcards(const char * str); 8 | const char * get_wildcard_list(); 9 | bool is_wildcard(char c); 10 | }; 11 | -------------------------------------------------------------------------------- /sdk-license.txt: -------------------------------------------------------------------------------- 1 | foobar2000 2.x SDK 2 | Copyright (c) 2002-2024, Peter Pawlowski 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 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. 9 | 10 | 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 AUTHORS 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. 11 | 12 | Note that separate less restrictive licenses apply to the included 'pfc' and 'libPPUI' libraries. See license files included in respective folders for details. 13 | --------------------------------------------------------------------------------