summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/libuv/src/win/getnameinfo.c
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/libuv/src/win/getnameinfo.c')
-rw-r--r--3rdparty/libuv/src/win/getnameinfo.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/3rdparty/libuv/src/win/getnameinfo.c b/3rdparty/libuv/src/win/getnameinfo.c
new file mode 100644
index 00000000000..66b64b88324
--- /dev/null
+++ b/3rdparty/libuv/src/win/getnameinfo.c
@@ -0,0 +1,150 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to
+* deal in the Software without restriction, including without limitation the
+* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+* sell copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+* IN THE SOFTWARE.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "req-inl.h"
+
+#ifndef GetNameInfo
+int WSAAPI GetNameInfoW(
+ const SOCKADDR *pSockaddr,
+ socklen_t SockaddrLength,
+ PWCHAR pNodeBuffer,
+ DWORD NodeBufferSize,
+ PWCHAR pServiceBuffer,
+ DWORD ServiceBufferSize,
+ INT Flags
+);
+#endif
+
+static void uv__getnameinfo_work(struct uv__work* w) {
+ uv_getnameinfo_t* req;
+ WCHAR host[NI_MAXHOST];
+ WCHAR service[NI_MAXSERV];
+ int ret = 0;
+
+ req = container_of(w, uv_getnameinfo_t, work_req);
+ if (GetNameInfoW((struct sockaddr*)&req->storage,
+ sizeof(req->storage),
+ host,
+ ARRAY_SIZE(host),
+ service,
+ ARRAY_SIZE(service),
+ req->flags)) {
+ ret = WSAGetLastError();
+ }
+ req->retcode = uv__getaddrinfo_translate_error(ret);
+
+ /* convert results to UTF-8 */
+ WideCharToMultiByte(CP_UTF8,
+ 0,
+ host,
+ -1,
+ req->host,
+ sizeof(req->host),
+ NULL,
+ NULL);
+
+ WideCharToMultiByte(CP_UTF8,
+ 0,
+ service,
+ -1,
+ req->service,
+ sizeof(req->service),
+ NULL,
+ NULL);
+}
+
+
+/*
+* Called from uv_run when complete.
+*/
+static void uv__getnameinfo_done(struct uv__work* w, int status) {
+ uv_getnameinfo_t* req;
+ char* host;
+ char* service;
+
+ req = container_of(w, uv_getnameinfo_t, work_req);
+ uv__req_unregister(req->loop, req);
+ host = service = NULL;
+
+ if (status == UV_ECANCELED) {
+ assert(req->retcode == 0);
+ req->retcode = UV_EAI_CANCELED;
+ } else if (req->retcode == 0) {
+ host = req->host;
+ service = req->service;
+ }
+
+ if (req->getnameinfo_cb)
+ req->getnameinfo_cb(req, req->retcode, host, service);
+}
+
+
+/*
+* Entry point for getnameinfo
+* return 0 if a callback will be made
+* return error code if validation fails
+*/
+int uv_getnameinfo(uv_loop_t* loop,
+ uv_getnameinfo_t* req,
+ uv_getnameinfo_cb getnameinfo_cb,
+ const struct sockaddr* addr,
+ int flags) {
+ if (req == NULL || addr == NULL)
+ return UV_EINVAL;
+
+ if (addr->sa_family == AF_INET) {
+ memcpy(&req->storage,
+ addr,
+ sizeof(struct sockaddr_in));
+ } else if (addr->sa_family == AF_INET6) {
+ memcpy(&req->storage,
+ addr,
+ sizeof(struct sockaddr_in6));
+ } else {
+ return UV_EINVAL;
+ }
+
+ uv_req_init(loop, (uv_req_t*)req);
+ uv__req_register(loop, req);
+
+ req->getnameinfo_cb = getnameinfo_cb;
+ req->flags = flags;
+ req->type = UV_GETNAMEINFO;
+ req->loop = loop;
+ req->retcode = 0;
+
+ if (getnameinfo_cb) {
+ uv__work_submit(loop,
+ &req->work_req,
+ uv__getnameinfo_work,
+ uv__getnameinfo_done);
+ return 0;
+ } else {
+ uv__getnameinfo_work(&req->work_req);
+ uv__getnameinfo_done(&req->work_req, 0);
+ return req->retcode;
+ }
+}
>307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
// license:BSD-3-Clause
// copyright-holders:Nathan Woods
/*********************************************************************

    ui/devopt.cpp

    Internal menu for the device configuration.

*********************************************************************/

#include "emu.h"
#include "ui/devopt.h"

#include "ui/ui.h"
#include "romload.h"


namespace ui {

/*-------------------------------------------------
 device_config - handle the game information
 menu
 -------------------------------------------------*/

menu_device_config::menu_device_config(
		mame_ui_manager &mui,
		render_container &container,
		device_slot_interface *slot,
		device_slot_interface::slot_option const *option)
	: menu_textbox(mui, container)
	, m_option(option)
	, m_mounted(machine().root_device().subdevice(slot->device().subtag(option->name())) != nullptr)
{
	set_process_flags(PROCESS_CUSTOM_NAV);
}

menu_device_config::~menu_device_config()
{
}

void menu_device_config::populate_text(std::optional<text_layout> &layout, float &width, int &lines)
{
	if (!layout || (layout->width() != width))
	{
		rgb_t const color = ui().colors().text_color();
		layout.emplace(ui().create_layout(container(), width));

		machine_config &mconfig(const_cast<machine_config &>(machine().config()));
		machine_config::token const tok(mconfig.begin_configuration(mconfig.root_device()));
		device_t *const dev = mconfig.device_add(m_option->name(), m_option->devtype(), 0);
		for (device_t &d : device_enumerator(*dev))
			if (!d.configured())
				d.config_complete();

		layout->add_text(
				util::string_format(
					m_mounted
						? _("[This option is currently mounted in the running system]\n\nOption: %1$s\nDevice: %2$s\n\nThe selected option enables the following items:\n")
						: _("[This option is NOT currently mounted in the running system]\n\nOption: %1$s\nDevice: %2$s\n\nIf you select this option, the following items will be enabled:\n"),
					m_option->name(),
					dev->name()),
				color);

		// loop over all CPUs
		execute_interface_enumerator execiter(*dev);
		if (execiter.count() > 0)
		{
			layout->add_text(_("* CPU:\n"), color);
			std::unordered_set<std::string> exectags;
			for (device_execute_interface &exec : execiter)
			{
				if (!exectags.insert(exec.device().tag()).second)
					continue;

				// get cpu specific clock that takes internal multiplier/dividers into account
				u32 clock = exec.device().clock();

				// count how many identical CPUs we have
				int count = 1;
				const char *name = exec.device().name();
				for (device_execute_interface &scan : execiter)
				{
					if (exec.device().type() == scan.device().type() && strcmp(name, scan.device().name()) == 0 && exec.device().clock() == scan.device().clock())
						if (exectags.insert(scan.device().tag()).second)
							count++;
				}

				std::string hz(std::to_string(clock));
				int d = (clock >= 1'000'000'000) ? 9 : (clock >= 1'000'000) ? 6 : (clock >= 1000) ? 3 : 0;
				if (d > 0)
				{
					size_t dpos = hz.length() - d;
					hz.insert(dpos, ".");
					size_t last = hz.find_last_not_of('0');
					hz = hz.substr(0, last + (last != dpos ? 1 : 0));
				}

				// if more than one, prepend a #x in front of the CPU name and display clock
				layout->add_text(
						util::string_format(
							(count > 1)
								? ((clock != 0) ? "  %1$d" UTF8_MULTIPLY "%2$s %3$s" UTF8_NBSP "%4$s\n" : "  %1$d" UTF8_MULTIPLY "%2$s\n")
								: ((clock != 0) ? "  %2$s %3$s" UTF8_NBSP "%4$s\n" : "  %2$s\n"),
							count, name, hz,
							(d == 9) ? _("GHz") : (d == 6) ? _("MHz") : (d == 3) ? _("kHz") : _("Hz")),
						color);
			}
		}

		// display screen information
		screen_device_enumerator scriter(*dev);
		if (scriter.count() > 0)
		{
			layout->add_text(_("* Video:\n"), color);
			for (screen_device &screen : scriter)
			{
				if (screen.screen_type() == SCREEN_TYPE_VECTOR)
				{
					layout->add_text(util::string_format(_("  Screen '%1$s': Vector\n"), screen.tag()), color);
				}
				else
				{
					const u32 rate = u32(screen.frame_period().as_hz() * 1'000'000 + 0.5);
					const bool valid = rate >= 1'000'000;
					std::string hz(valid ? std::to_string(rate) : "?");
					if (valid)
					{
						size_t dpos = hz.length() - 6;
						hz.insert(dpos, ".");
						size_t last = hz.find_last_not_of('0');
						hz = hz.substr(0, last + (last != dpos ? 1 : 0));
					}

					const rectangle &visarea = screen.visible_area();
					layout->add_text(
							util::string_format(
								(screen.orientation() & ORIENTATION_SWAP_XY)
									? _("  Screen '%1$s': %2$d \xC3\x97 %3$d (V) %4$s\xC2\xA0Hz\n")
									: _("  Screen '%1$s': %2$d \xC3\x97 %3$d (H) %4$s\xC2\xA0Hz\n"),
								screen.tag(),
								visarea.width(),
								visarea.height(),
								hz),
							color);
				}
			}
		}

		// loop over all sound chips
		sound_interface_enumerator snditer(*dev);
		if (snditer.count() > 0)
		{
			layout->add_text(_("* Sound:\n"), color);
			std::unordered_set<std::string> soundtags;
			for (device_sound_interface &sound : snditer)
			{
				if (!sound.issound() || !soundtags.insert(sound.device().tag()).second)
					continue;

				// count how many identical sound chips we have
				int count = 1;
				for (device_sound_interface &scan : snditer)
				{
					if (sound.device().type() == scan.device().type() && sound.device().clock() == scan.device().clock())
						if (soundtags.insert(scan.device().tag()).second)
							count++;
				}

				const u32 clock = sound.device().clock();
				std::string hz(std::to_string(clock));
				int d = (clock >= 1'000'000'000) ? 9 : (clock >= 1'000'000) ? 6 : (clock >= 1000) ? 3 : 0;
				if (d > 0)
				{
					size_t dpos = hz.length() - d;
					hz.insert(dpos, ".");
					size_t last = hz.find_last_not_of('0');
					hz = hz.substr(0, last + (last != dpos ? 1 : 0));
				}

				// if more than one, prepend a #x in front of the name and display clock
				layout->add_text(
						util::string_format(
							(count > 1)
								? ((clock != 0) ? "  %1$d" UTF8_MULTIPLY "%2$s %3$s" UTF8_NBSP "%4$s\n" : "  %1$d" UTF8_MULTIPLY "%2$s\n")
								: ((clock != 0) ? "  %2$s %3$s" UTF8_NBSP "%4$s\n" : "  %2$s\n"),
							count, sound.device().name(), hz,
							(d == 9) ? _("GHz") : (d == 6) ? _("MHz") : (d == 3) ? _("kHz") : _("Hz")),
						color);
			}
		}

		// scan for BIOS settings
		int bios = 0;
		if (dev->rom_region())
		{
			// first loop through roms in search of default bios (shortname)
			char const *bios_str(nullptr);
			for (const tiny_rom_entry *rom = dev->rom_region(); !ROMENTRY_ISEND(rom); ++rom)
			{
				if (ROMENTRY_ISDEFAULT_BIOS(rom))
					bios_str = rom->name;
			}

			// then loop again to count bios options and to get the default bios complete name
			char const *bios_desc(nullptr);
			for (romload::system_bios const &rom : romload::entries(dev->rom_region()).get_system_bioses())
			{
				bios++;
				if (bios_str && !std::strcmp(bios_str, rom.get_name()))
					bios_desc = rom.get_description();
			}

			if (bios)
			{
				layout->add_text(
						util::string_format(
							_("* BIOS settings:\n  %1$d options    [default: %2$s]\n"),
							bios,
							bios_desc ? bios_desc : bios_str ? bios_str : ""),
						color);
			}
		}

		int input = 0, input_mj = 0, input_hana = 0, input_gamble = 0, input_analog = 0, input_adjust = 0;
		int input_keypad = 0, input_keyboard = 0, dips = 0, confs = 0;
		std::string errors;
		std::ostringstream dips_opt, confs_opt;
		ioport_list portlist;
		for (device_t &iptdev : device_enumerator(*dev))
			portlist.append(iptdev, errors);

		// check if the device adds inputs to the system
		for (auto &port : portlist)
			for (ioport_field &field : port.second->fields())
			{
				if (field.type() >= IPT_MAHJONG_FIRST && field.type() < IPT_MAHJONG_LAST)
					input_mj++;
				else if (field.type() >= IPT_HANAFUDA_FIRST && field.type() < IPT_HANAFUDA_LAST)
					input_hana++;
				else if (field.type() >= IPT_GAMBLING_FIRST && field.type() < IPT_GAMBLING_LAST)
					input_gamble++;
				else if (field.type() >= IPT_ANALOG_FIRST && field.type() < IPT_ANALOG_LAST)
					input_analog++;
				else if (field.type() == IPT_ADJUSTER)
					input_adjust++;
				else if (field.type() == IPT_KEYPAD)
					input_keypad++;
				else if (field.type() == IPT_KEYBOARD)
					input_keyboard++;
				else if (field.type() >= IPT_START1 && field.type() < IPT_UI_FIRST)
					input++;
				else if (field.type() == IPT_DIPSWITCH)
				{
					dips++;
					bool def(false);
					for (ioport_setting const &setting : field.settings())
					{
						if (setting.value() == field.defvalue())
						{
							def = true;
							util::stream_format(dips_opt, _("  %1$s    [default: %2$s]\n"), field.specific_name(), setting.name());
							break;
						}
					}
					if (!def)
						util::stream_format(dips_opt, _("  %1$s\n"), field.specific_name());
				}
				else if (field.type() == IPT_CONFIG)
				{
					confs++;
					bool def(false);
					for (ioport_setting const &setting : field.settings())
					{
						if (setting.value() == field.defvalue())
						{
							def = true;
							util::stream_format(confs_opt, _("  %1$s    [default: %2$s]\n"), field.specific_name(), setting.name());
							break;
						}
					}
					if (!def)
						util::stream_format(confs_opt, _("  %1$s\n"), field.specific_name());
				}
			}

		if (dips)
		{
			layout->add_text(_("* DIP switch settings:\n"), color);
			layout->add_text(std::move(dips_opt).str(), color);
		}
		if (confs)
		{
			layout->add_text(_("* Configuration settings:\n"), color);
			layout->add_text(std::move(confs_opt).str(), color);
		}
		if (input || input_mj || input_hana || input_gamble || input_analog || input_adjust || input_keypad || input_keyboard)
			layout->add_text(_("* Input device(s):\n"), color);
		if (input)
			layout->add_text(util::string_format(_("  User inputs    [%1$d inputs]\n"), input), color);
		if (input_mj)
			layout->add_text(util::string_format(_("  Mahjong inputs    [%1$d inputs]\n"), input_mj), color);
		if (input_hana)
			layout->add_text(util::string_format(_("  Hanafuda inputs    [%1$d inputs]\n"), input_hana), color);
		if (input_gamble)
			layout->add_text(util::string_format(_("  Gambling inputs    [%1$d inputs]\n"), input_gamble), color);
		if (input_analog)
			layout->add_text(util::string_format(_("  Analog inputs    [%1$d inputs]\n"), input_analog), color);
		if (input_adjust)
			layout->add_text(util::string_format(_("  Adjuster inputs    [%1$d inputs]\n"), input_adjust), color);
		if (input_keypad)
			layout->add_text(util::string_format(_("  Keypad inputs    [%1$d inputs]\n"), input_keypad), color);
		if (input_keyboard)
			layout->add_text(util::string_format(_("  Keyboard inputs    [%1$d inputs]\n"), input_keyboard), color);

		image_interface_enumerator imgiter(*dev);
		if (imgiter.count() > 0)
		{
			layout->add_text(_("* Media Options:\n"), color);
			for (const device_image_interface &imagedev : imgiter)
			{
				layout->add_text(
						util::string_format(
							_("  %1$s    [tag: %2$s]\n"),
							imagedev.image_type_name(),
							imagedev.device().tag()),
						color);
			}
		}

		slot_interface_enumerator slotiter(*dev);
		if (slotiter.count() > 0)
		{
			layout->add_text(_("* Slot Options:\n"), color);
			for (const device_slot_interface &slot : slotiter)
			{
				layout->add_text(
						util::string_format(
							_("  %1$s    [default: %2$s]\n"),
							slot.device().tag(),
							slot.default_option() ? slot.default_option() : "----"),
						color);
			}
		}

		if ((execiter.count() + scriter.count() + snditer.count() + imgiter.count() + slotiter.count() + bios + dips + confs
				+ input + input_mj + input_hana + input_gamble + input_analog + input_adjust + input_keypad + input_keyboard) == 0)
			layout->add_text(_("[None]\n"), color);

		mconfig.device_remove(m_option->name());
		lines = layout->lines();
	}
	width = layout->actual_width();
}

void menu_device_config::populate(float &customtop, float &custombottom)
{
}

void menu_device_config::handle(event const *ev)
{
	if (ev)
		handle_key(ev->iptkey);
}

} // namespace ui