// license:BSD-3-Clause// copyright-holders:Olivier Galibert, R. Belmont//============================================================//// sdlos_*.c - OS specific low level code//// SDLMAME by Olivier Galibert and R. Belmont////============================================================#include<windows.h>#include<mmsystem.h>#include<cstdlib>#ifndef _MSC_VER#include<unistd.h>#endif#include<cstdio>#include<memory>// MAME headers#include"osdlib.h"#include"osdcomm.h"#include"osdcore.h"#include"strconv.h"#ifdef OSD_WINDOWS#include"winutf8.h"#endif//============================================================// GLOBAL VARIABLES//============================================================#ifdef OSD_WINDOWSvoid(*s_debugger_stack_crawler)()=nullptr;#endif//============================================================// osd_getenv//============================================================constchar*osd_getenv(constchar*name){returngetenv(name);}//============================================================// osd_setenv//============================================================intosd_setenv(constchar*name,constchar*value,intoverwrite){char*buf;intresult;if(!overwrite){if(osd_getenv(name)!=nullptr)return0;}buf=(char*)malloc(strlen(name)+strlen(value)+2);sprintf(buf,"%s=%s",name,value);result=putenv(buf);/* will be referenced by environment * Therefore it is not freed here */returnresult;}//============================================================// osd_process_kill//============================================================voidosd_process_kill(){TerminateProcess(GetCurrentProcess(),-1);}//============================================================// osd_alloc_executable//// allocates "size" bytes of executable memory. this must take// things like NX support into account.//============================================================void*osd_alloc_executable(size_tsize){returnVirtualAlloc(nullptr,size,MEM_COMMIT,PAGE_EXECUTE_READWRITE);}//============================================================// osd_free_executable//// frees memory allocated with osd_alloc_executable//============================================================voidosd_free_executable(void*ptr,size_tsize){VirtualFree(ptr,0,MEM_RELEASE);}//============================================================// osd_break_into_debugger//============================================================voidosd_break_into_debugger(constchar*message){#ifdef OSD_WINDOWSif(IsDebuggerPresent()){win_output_debug_string_utf8(message);DebugBreak();}elseif(s_debugger_stack_crawler!=nullptr)(*s_debugger_stack_crawler)();#elseif(IsDebuggerPresent()){OutputDebugStringA(message);DebugBreak();}#endif}//============================================================// get_clipboard_text_by_format//============================================================staticboolget_clipboard_text_by_format(std::string&result_text,UINTformat,std::string(*convert)(LPCVOIDdata)){boolresult=false;HANDLEdata_handle;LPVOIDdata;// check to see if this format is availableif(IsClipboardFormatAvailable(format)){// open the clipboardif(OpenClipboard(nullptr)){// try to access clipboard datadata_handle=GetClipboardData(format);if(data_handle!=nullptr){// lock the datadata=GlobalLock(data_handle);if(data!=nullptr){// invoke the convertresult_text=(*convert)(data);result=true;// unlock the dataGlobalUnlock(data_handle);}}// close out the clipboardCloseClipboard();}}returnresult;}//============================================================// convert_wide//============================================================staticstd::stringconvert_wide(LPCVOIDdata){returnosd::text::from_wstring((LPCWSTR)data);}//============================================================// convert_ansi//============================================================staticstd::stringconvert_ansi(LPCVOIDdata){returnosd::text::from_astring((LPCSTR)data);}//============================================================// osd_get_clipboard_text//============================================================std::stringosd_get_clipboard_text(void){std::stringresult;// try to access unicode textif(!get_clipboard_text_by_format(result,CF_UNICODETEXT,convert_wide)){// try to access ANSI textget_clipboard_text_by_format(result,CF_TEXT,convert_ansi);}returnresult;}//============================================================// osd_getpid//============================================================intosd_getpid(void){returnGetCurrentProcessId();}//============================================================// osd_dynamic_bind//============================================================#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)// for classic desktop applications#define load_library(filename) LoadLibrary(filename)#else// for Windows Store universal applications#define load_library(filename) LoadPackagedLibrary(filename, 0)#endifnamespaceosd{classdynamic_module_win32_impl:publicdynamic_module{public:dynamic_module_win32_impl(std::vector<std::string>&libraries):m_module(nullptr){m_libraries=libraries;}virtual~dynamic_module_win32_impl()override{if(m_module!=nullptr)FreeLibrary(m_module);};protected:virtualgeneric_fptr_tget_symbol_address(charconst*symbol)override{/* * given a list of libraries, if a first symbol is successfully loaded from * one of them, all additional symbols will be loaded from the same library */if(m_module){returnreinterpret_cast<generic_fptr_t>(GetProcAddress(m_module,symbol));}for(autoconst&library:m_libraries){osd::text::tstringtempstr=osd::text::to_tstring(library);HMODULEmodule=load_library(tempstr.c_str());if(module!=nullptr){generic_fptr_tfunction=reinterpret_cast<generic_fptr_t>(GetProcAddress(module,symbol));if(function!=nullptr){m_module=module;returnfunction;}else{FreeLibrary(module);}}}returnnullptr;}private:std::vector<std::string>m_libraries;HMODULEm_module;};dynamic_module::ptrdynamic_module::open(std::vector<std::string>&&names){returnstd::make_unique<dynamic_module_win32_impl>(names);}}// namespace osd