summaryrefslogblamecommitdiffstatshomepage
path: root/src/osd/modules/lib/osdlib.h
blob: 967cb0d61aec16b201eed6ace90a4341965bf203 (plain) (tree)
1
2
3
4
5
6
7
8

                                                 

                                                              
            
  

                                              




                                                            
                                                              

                             
 
            
 
                  
                           
                 

                       

                      
                 
 
 
                                                                               









                                                                               
 
                        
 
 
                                                                               














                                                                               
 















                                                                            
 
 

               
                                                                                











                                          

                                                           




                                                                                         

                                                                                                      
         
                                                                         
         
                                                                                                                                                          









                                                    



                                                                          
 
                                                                                      






                                                                                                                   
                                                                     







                                                  
                                                                                       














                                                            


                                                                                                                                              





                                                  










                                                                               






                                                              
                                     

                             
                                                                                   











                                                                          

                                                                                                           
  
                                    
                                                                          
  

                                                                                                           
 



                                                                                                                                                                    
 
                               
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert, R. Belmont
//============================================================
//
//  osdlib.h
//
//  SDLMAME by Olivier Galibert and R. Belmont
//
//  - Common low level routines
//  - Source files also provide the following from osdcore.h
//
//    - osd_ticks
//    - osd_sleep
//============================================================
#ifndef MAME_OSD_LIB_OSDLIB_H
#define MAME_OSD_LIB_OSDLIB_H

#pragma once

#include <cstdint>
#include <initializer_list>
#include <string>
#include <string_view>
#include <system_error>
#include <type_traits>
#include <vector>
#include <memory>


/*-----------------------------------------------------------------------------
    osd_process_kill: kill the current process

    Parameters:

        None.

    Return value:

        None.
-----------------------------------------------------------------------------*/

void osd_process_kill();


/*-----------------------------------------------------------------------------
    osd_setenv: set environment variable

    Parameters:

        name  - name of environment variable
        value - value to write
        overwrite - overwrite if it exists

    Return value:

        0 on success
-----------------------------------------------------------------------------*/

int osd_setenv(const char *name, const char *value, int overwrite);


/// \brief Get clipboard text
///
/// Gets current clipboard content as UTF-8 text.  Returns an empty
/// string if the clipboard contents cannot be converted to plain text.
/// \return Clipboard contents or an empty string.
std::string osd_get_clipboard_text() noexcept;


/// \brief Set clipboard text
///
/// Sets the desktop environment's clipboard contents to the supplied
/// UTF-8 text.  The contents of the clipboard may be changed on error.
/// \param [in] text The text to copy to the clipboard.
/// \return An error condition if the operation failed or is
///   unsupported.
std::error_condition osd_set_clipboard_text(std::string_view text) noexcept;


namespace osd {

bool invalidate_instruction_cache(void const *start, std::size_t size) noexcept;


class virtual_memory_allocation
{
public:
	enum : unsigned
	{
		NONE = 0x00,
		READ = 0x01,
		WRITE = 0x02,
		EXECUTE = 0x04,
		READ_WRITE = READ | WRITE,
		READ_EXECUTE = READ | EXECUTE,
		READ_WRITE_EXECUTE = READ | WRITE | EXECUTE
	};

	virtual_memory_allocation(virtual_memory_allocation const &) = delete;
	virtual_memory_allocation &operator=(virtual_memory_allocation const &) = delete;

	virtual_memory_allocation() noexcept { }
	virtual_memory_allocation(std::initializer_list<std::size_t> blocks, unsigned intent) noexcept
	{
		m_memory = do_alloc(blocks, intent, m_size, m_page_size);
	}
	virtual_memory_allocation(virtual_memory_allocation &&that) noexcept : m_memory(that.m_memory), m_size(that.m_size), m_page_size(that.m_page_size)
	{
		that.m_memory = nullptr;
		that.m_size = that.m_page_size = 0U;
	}
	~virtual_memory_allocation()
	{
		if (m_memory)
			do_free(m_memory, m_size);
	}

	explicit operator bool() const noexcept { return bool(m_memory); }
	void *get() noexcept { return m_memory; }
	std::size_t size() const noexcept { return m_size; }
	std::size_t page_size() const noexcept { return m_page_size; }

	bool set_access(std::size_t start, std::size_t size, unsigned access) noexcept
	{
		if ((start % m_page_size) || (size % m_page_size) || (start > m_size) || ((m_size - start) < size))
			return false;
		else
			return do_set_access(reinterpret_cast<std::uint8_t *>(m_memory) + start, size, access);
	}

	virtual_memory_allocation &operator=(std::nullptr_t) noexcept
	{
		if (m_memory)
			do_free(m_memory, m_size);
		m_memory = nullptr;
		m_size = m_page_size = 0U;
		return *this;
	}

	virtual_memory_allocation &operator=(virtual_memory_allocation &&that) noexcept
	{
		if (&that != this)
		{
			if (m_memory)
				do_free(m_memory, m_size);
			m_memory = that.m_memory;
			m_size = that.m_size;
			m_page_size = that.m_page_size;
			that.m_memory = nullptr;
			that.m_size = that.m_page_size = 0U;
		}
		return *this;
	}

private:
	static void *do_alloc(std::initializer_list<std::size_t> blocks, unsigned intent, std::size_t &size, std::size_t &page_size) noexcept;
	static void do_free(void *start, std::size_t size) noexcept;
	static bool do_set_access(void *start, std::size_t size, unsigned access) noexcept;

	void *m_memory = nullptr;
	std::size_t m_size = 0U, m_page_size = 0U;
};


/*-----------------------------------------------------------------------------
    dynamic_module: load functions from optional shared libraries

    Notes:

        - Supports Mac OS X, Unix and Windows (both desktop and Windows
          Store universal applications)
        - A symbol can be searched in a list of libraries (e.g. more
          revisions of a same library)
-----------------------------------------------------------------------------*/

class dynamic_module
{
public:
	typedef std::unique_ptr<dynamic_module> ptr;

	static ptr open(std::vector<std::string> &&libraries);

	virtual ~dynamic_module() { }

	template <typename T>
	typename std::enable_if_t<std::is_pointer_v<T>, T> bind(char const *symbol)
	{
		return reinterpret_cast<T>(get_symbol_address(symbol));
	}

protected:
	typedef void (*generic_fptr_t)();

	virtual generic_fptr_t get_symbol_address(char const *symbol) = 0;
};

} // namespace osd

//=========================================================================================================
// Dynamic API helpers. Useful in creating a class members that expose dynamically bound API functions.
//
// OSD_DYNAMIC_API(dxgi, "dxgi.dll")
// DYNAMIC_API_FN(dxgi, DWORD, WINAPI, CreateDXGIFactory1, REFIID, void**)
//
// Calling then looks like: DYNAMIC_CALL(CreateDXGIFactory1, p1, p2, etc)
//=========================================================================================================

#define OSD_DYNAMIC_API(apiname, ...) osd::dynamic_module::ptr m_##apiname##module = osd::dynamic_module::open( { __VA_ARGS__ } )
#define OSD_DYNAMIC_API_FN(apiname, ret, conv, fname, ...) ret(conv *m_##fname##_pfn)( __VA_ARGS__ ) = m_##apiname##module->bind<ret(conv *)( __VA_ARGS__ )>(#fname)
#define OSD_DYNAMIC_CALL(fname, ...) (*m_##fname##_pfn) ( __VA_ARGS__ )
#define OSD_DYNAMIC_API_TEST(fname) (m_##fname##_pfn != nullptr)

#endif // MAME_OSD_LIB_OSDLIB_H