Date: Mon, 15 Feb 2021 21:28:15 +0000 (UTC) From: Jan Beich <jbeich@FreeBSD.org> To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r565343 - in head/www/firefox: . files Message-ID: <202102152128.11FLSFWk045209@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jbeich Date: Mon Feb 15 21:28:15 2021 New Revision: 565343 URL: https://svnweb.freebsd.org/changeset/ports/565343 Log: www/firefox: update to 86.0 Changes: https://www.mozilla.org/firefox/86.0/releasenotes/ Added: head/www/firefox/files/patch-bug1680982 (contents, props changed) head/www/firefox/files/patch-bug1686713 (contents, props changed) Deleted: head/www/firefox/files/patch-bug1684261 head/www/firefox/files/patch-bug1687487 head/www/firefox/files/patch-bug1690152 Modified: head/www/firefox/Makefile (contents, props changed) head/www/firefox/distinfo (contents, props changed) head/www/firefox/files/patch-addon-search (contents, props changed) head/www/firefox/pkg-message (contents, props changed) Modified: head/www/firefox/Makefile ============================================================================== --- head/www/firefox/Makefile Mon Feb 15 21:21:04 2021 (r565342) +++ head/www/firefox/Makefile Mon Feb 15 21:28:15 2021 (r565343) @@ -2,8 +2,7 @@ # $FreeBSD$ PORTNAME= firefox -DISTVERSION= 85.0.2 -PORTREVISION= 1 +DISTVERSION= 86.0 PORTEPOCH= 2 CATEGORIES= www MASTER_SITES= MOZILLA/${PORTNAME}/releases/${DISTVERSION}/source \ Modified: head/www/firefox/distinfo ============================================================================== --- head/www/firefox/distinfo Mon Feb 15 21:21:04 2021 (r565342) +++ head/www/firefox/distinfo Mon Feb 15 21:28:15 2021 (r565343) @@ -1,3 +1,3 @@ -TIMESTAMP = 1612802741 -SHA256 (firefox-85.0.2.source.tar.xz) = b157cdc265daa6140ec8daef2bc98d335f871e7e9ac235287fb199e11c164287 -SIZE (firefox-85.0.2.source.tar.xz) = 372234168 +TIMESTAMP = 1613411049 +SHA256 (firefox-86.0.source.tar.xz) = 5a12bca96ec5d7e5febc750b5400fbd78ffa143cc3a90942bd045af34ac9fdd7 +SIZE (firefox-86.0.source.tar.xz) = 368780392 Modified: head/www/firefox/files/patch-addon-search ============================================================================== --- head/www/firefox/files/patch-addon-search Mon Feb 15 21:21:04 2021 (r565342) +++ head/www/firefox/files/patch-addon-search Mon Feb 15 21:28:15 2021 (r565343) @@ -5,16 +5,16 @@ diff --git browser/app/profile/firefox.js browser/app/ index 75c2c5e435e35..4d8c09c02759b 100644 --- browser/app/profile/firefox.js +++ browser/app/profile/firefox.js -@@ -37,7 +37,7 @@ pref("extensions.webextOptionalPermissionPrompts", true); +@@ -39,7 +39,7 @@ pref("extensions.postDownloadThirdPartyPrompt", true); // Preferences for AMO integration pref("extensions.getAddons.cache.enabled", true); - pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/api/v3/addons/search/?guid=%IDS%&lang=%LOCALE%"); + pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/api/v4/addons/search/?guid=%IDS%&lang=%LOCALE%"); -pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/firefox/search?q=%TERMS%&platform=%OS%&appver=%VERSION%"); +pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/firefox/search?q=%TERMS%&platform=Linux&appver=%VERSION%"); pref("extensions.getAddons.link.url", "https://addons.mozilla.org/%LOCALE%/firefox/"); - pref("extensions.getAddons.langpacks.url", "https://services.addons.mozilla.org/api/v3/addons/language-tools/?app=firefox&type=language&appversion=%VERSION%"); + pref("extensions.getAddons.langpacks.url", "https://services.addons.mozilla.org/api/v4/addons/language-tools/?app=firefox&type=language&appversion=%VERSION%"); pref("extensions.getAddons.discovery.api_url", "https://services.addons.mozilla.org/api/v4/discovery/?lang=%LOCALE%&edition=%DISTRIBUTION%"); -@@ -168,8 +168,8 @@ pref("app.update.staging.enabled", true); +@@ -176,8 +176,8 @@ pref("app.update.langpack.enabled", true); // .. etc .. // pref("extensions.update.enabled", true); Added: head/www/firefox/files/patch-bug1680982 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/www/firefox/files/patch-bug1680982 Mon Feb 15 21:28:15 2021 (r565343) @@ -0,0 +1,369 @@ +commit d947b92c7503 +Author: Greg V <greg@unrelenting.technology> +Date: Sun Dec 6 22:07:00 2020 +0000 + + Bug 1680982 - Use evdev for gamepads on Linux/FreeBSD + + Switch from the legacy Linux joystick API to the generic evdev API. + + - BTN_GAMEPAD semantic buttons are interpreted directly, + since all kernel drivers are supposed to use them correctly: + https://www.kernel.org/doc/html/latest/input/gamepad.html + - BTN_JOYSTICK legacy style numbered buttons use the model specific remappers + - using evdev is a prerequisite for adding rumble (haptic feedback) and other extras + - the Linux gamepad module is enabled on FreeBSD, because + FreeBSD provides evdev, and libudev-devd provides enough of libudev + (evdev headers are provided by the devel/evdev-proto package) + + Differential Revision: https://phabricator.services.mozilla.com/D98868 +--- + dom/gamepad/linux/LinuxGamepad.cpp | 243 +++++++++++++++++++++++++++++++------ + dom/gamepad/moz.build | 2 +- + 2 files changed, 210 insertions(+), 35 deletions(-) + +diff --git dom/gamepad/linux/LinuxGamepad.cpp dom/gamepad/linux/LinuxGamepad.cpp +index 512ac765020d..0e51183c2a2d 100644 +--- dom/gamepad/linux/LinuxGamepad.cpp ++++ dom/gamepad/linux/LinuxGamepad.cpp +@@ -5,15 +5,16 @@ + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + /* +- * LinuxGamepadService: A Linux backend for the GamepadService. +- * Derived from the kernel documentation at +- * http://www.kernel.org/doc/Documentation/input/joystick-api.txt ++ * LinuxGamepadService: An evdev backend for the GamepadService. ++ * ++ * Ref: https://www.kernel.org/doc/html/latest/input/gamepad.html + */ + #include <algorithm> ++#include <unordered_map> + #include <cstddef> + + #include <glib.h> +-#include <linux/joystick.h> ++#include <linux/input.h> + #include <stdio.h> + #include <stdint.h> + #include <sys/ioctl.h> +@@ -21,10 +22,14 @@ + #include "nscore.h" + #include "mozilla/dom/GamepadHandle.h" + #include "mozilla/dom/GamepadPlatformService.h" ++#include "mozilla/dom/GamepadRemapping.h" + #include "mozilla/Tainting.h" + #include "mozilla/UniquePtr.h" + #include "udev.h" + ++#define LONG_BITS (sizeof(long) * 8) ++#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS) ++ + namespace { + + using namespace mozilla::dom; +@@ -36,19 +41,29 @@ using mozilla::udev_list_entry; + using mozilla::udev_monitor; + using mozilla::UniquePtr; + +-static const float kMaxAxisValue = 32767.0; +-static const char kJoystickPath[] = "/dev/input/js"; ++static const char kEvdevPath[] = "/dev/input/event"; ++ ++static inline bool TestBit(const unsigned long* arr, int bit) { ++ return !!(arr[bit / LONG_BITS] & (1LL << (bit % LONG_BITS))); ++} ++ ++static inline double ScaleAxis(const input_absinfo& info, int value) { ++ return 2.0 * (value - info.minimum) / (double)(info.maximum - info.minimum) - ++ 1.0; ++} + + // TODO: should find a USB identifier for each device so we can + // provide something that persists across connect/disconnect cycles. +-typedef struct { ++struct Gamepad { + GamepadHandle handle; +- guint source_id; +- int numAxes; +- int numButtons; +- char idstring[256]; +- char devpath[PATH_MAX]; +-} Gamepad; ++ RefPtr<GamepadRemapper> remapper = nullptr; ++ guint source_id = UINT_MAX; ++ char idstring[256] = {0}; ++ char devpath[PATH_MAX] = {0}; ++ uint8_t key_map[KEY_MAX] = {0}; ++ uint8_t abs_map[ABS_MAX] = {0}; ++ std::unordered_map<uint16_t, input_absinfo> abs_info; ++}; + + class LinuxGamepadService { + public: +@@ -66,7 +81,7 @@ class LinuxGamepadService { + bool is_gamepad(struct udev_device* dev); + void ReadUdevChange(); + +- // handler for data from /dev/input/jsN ++ // handler for data from /dev/input/eventN + static gboolean OnGamepadData(GIOChannel* source, GIOCondition condition, + gpointer data); + +@@ -114,8 +129,12 @@ void LinuxGamepadService::AddDevice(struct udev_device* dev) { + g_io_channel_set_encoding(channel, nullptr, nullptr); + g_io_channel_set_buffered(channel, FALSE); + int fd = g_io_channel_unix_get_fd(channel); ++ ++ struct input_id id = {0}; ++ ioctl(fd, EVIOCGID, &id); ++ + char name[128]; +- if (ioctl(fd, JSIOCGNAME(sizeof(name)), &name) == -1) { ++ if (ioctl(fd, EVIOCGNAME(sizeof(name)), &name) == -1) { + strcpy(name, "unknown"); + } + const char* vendor_id = +@@ -131,20 +150,69 @@ void LinuxGamepadService::AddDevice(struct udev_device* dev) { + model_id = mUdev.udev_device_get_sysattr_value(parent, "id/product"); + } + } ++ if (!vendor_id && id.vendor != 0) { ++ vendor_id = (const char*)alloca(5); ++ snprintf((char*)vendor_id, 5, "%04x", id.vendor); ++ } ++ if (!model_id && id.product != 0) { ++ model_id = (const char*)alloca(5); ++ snprintf((char*)model_id, 5, "%04x", id.product); ++ } + snprintf(gamepad->idstring, sizeof(gamepad->idstring), "%s-%s-%s", + vendor_id ? vendor_id : "unknown", model_id ? model_id : "unknown", + name); + + char numAxes = 0, numButtons = 0; +- ioctl(fd, JSIOCGAXES, &numAxes); +- gamepad->numAxes = numAxes; +- ioctl(fd, JSIOCGBUTTONS, &numButtons); +- gamepad->numButtons = numButtons; ++ unsigned long key_bits[NLONGS(KEY_CNT)] = {0}; ++ unsigned long abs_bits[NLONGS(ABS_CNT)] = {0}; ++ ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits); ++ ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits); ++ for (uint16_t i = BTN_JOYSTICK; i < KEY_MAX; i++) { ++ /* Skip proper gamepad events, they are handled directly */ ++ if (i == BTN_GAMEPAD) { ++ i = BTN_THUMBR + 1; ++ continue; ++ } ++ if (i == BTN_DPAD_UP) { ++ i = BTN_DPAD_RIGHT + 1; ++ continue; ++ } ++ if (TestBit(key_bits, i)) { ++ gamepad->key_map[i] = numButtons++; ++ } ++ } ++ for (uint16_t i = 0; i < BTN_JOYSTICK; i++) { ++ if (TestBit(key_bits, i)) { ++ gamepad->key_map[i] = numButtons++; ++ } ++ } ++ for (uint16_t i = 0; i < ABS_MAX; ++i) { ++ if (TestBit(abs_bits, i)) { ++ gamepad->abs_info.emplace(i, input_absinfo{}); ++ if (ioctl(fd, EVIOCGABS(i), &gamepad->abs_info[i]) < 0) { ++ continue; ++ } ++ if (gamepad->abs_info[i].minimum == gamepad->abs_info[i].maximum) { ++ gamepad->abs_info.erase(i); ++ continue; ++ } ++ gamepad->abs_map[i] = numAxes++; ++ } ++ } ++ ++ bool defaultRemapper = false; ++ RefPtr<GamepadRemapper> remapper = ++ GetGamepadRemapper(id.vendor, id.product, defaultRemapper); ++ MOZ_ASSERT(remapper); ++ remapper->SetAxisCount(numAxes); ++ remapper->SetButtonCount(numButtons); + + gamepad->handle = service->AddGamepad( +- gamepad->idstring, mozilla::dom::GamepadMappingType::_empty, +- mozilla::dom::GamepadHand::_empty, gamepad->numButtons, gamepad->numAxes, +- 0, 0, 0); // TODO: Bug 680289, implement gamepad haptics for Linux. ++ gamepad->idstring, remapper->GetMappingType(), GamepadHand::_empty, ++ remapper->GetButtonCount(), remapper->GetAxisCount(), 0, ++ remapper->GetLightIndicatorCount(), remapper->GetTouchEventCount()); ++ gamepad->remapper = remapper.forget(); ++ // TODO: Bug 680289, implement gamepad haptics for Linux. + // TODO: Bug 1523355, implement gamepad lighindicator and touch for Linux. + + gamepad->source_id = +@@ -257,7 +325,7 @@ bool LinuxGamepadService::is_gamepad(struct udev_device* dev) { + if (!devpath) { + return false; + } +- if (strncmp(kJoystickPath, devpath, sizeof(kJoystickPath) - 1) != 0) { ++ if (strncmp(kEvdevPath, devpath, sizeof(kEvdevPath) - 1) != 0) { + return false; + } + +@@ -292,7 +360,7 @@ gboolean LinuxGamepadService::OnGamepadData(GIOChannel* source, + if (condition & G_IO_ERR || condition & G_IO_HUP) return FALSE; + + while (true) { +- struct js_event event; ++ struct input_event event = {0}; + gsize count; + GError* err = nullptr; + if (g_io_channel_read_chars(source, (gchar*)&event, sizeof(event), &count, +@@ -301,18 +369,125 @@ gboolean LinuxGamepadService::OnGamepadData(GIOChannel* source, + break; + } + +- // TODO: store device state? +- if (event.type & JS_EVENT_INIT) { +- continue; +- } +- + switch (event.type) { +- case JS_EVENT_BUTTON: +- service->NewButtonEvent(gamepad->handle, event.number, !!event.value); ++ case EV_KEY: ++ switch (event.code) { ++ /* The gamepad events are meaningful, and according to ++ * https://www.kernel.org/doc/html/latest/input/gamepad.html ++ * "No other devices, that do not look/feel like a gamepad, shall ++ * report these events" */ ++ case BTN_SOUTH: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_PRIMARY, ++ !!event.value); ++ break; ++ case BTN_EAST: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_SECONDARY, ++ !!event.value); ++ break; ++ case BTN_NORTH: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_QUATERNARY, ++ !!event.value); ++ break; ++ case BTN_WEST: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_TERTIARY, ++ !!event.value); ++ break; ++ case BTN_TL: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_LEFT_SHOULDER, ++ !!event.value); ++ break; ++ case BTN_TR: ++ service->NewButtonEvent(gamepad->handle, ++ BUTTON_INDEX_RIGHT_SHOULDER, !!event.value); ++ break; ++ case BTN_TL2: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_LEFT_TRIGGER, ++ !!event.value); ++ break; ++ case BTN_TR2: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_RIGHT_TRIGGER, ++ !!event.value); ++ break; ++ case BTN_SELECT: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_BACK_SELECT, ++ !!event.value); ++ break; ++ case BTN_START: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_START, ++ !!event.value); ++ break; ++ case BTN_MODE: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_META, ++ !!event.value); ++ break; ++ case BTN_THUMBL: ++ service->NewButtonEvent( ++ gamepad->handle, BUTTON_INDEX_LEFT_THUMBSTICK, !!event.value); ++ break; ++ case BTN_THUMBR: ++ service->NewButtonEvent( ++ gamepad->handle, BUTTON_INDEX_RIGHT_THUMBSTICK, !!event.value); ++ break; ++ case BTN_DPAD_UP: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_DPAD_UP, ++ !!event.value); ++ break; ++ case BTN_DPAD_DOWN: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_DPAD_DOWN, ++ !!event.value); ++ break; ++ case BTN_DPAD_LEFT: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_DPAD_LEFT, ++ !!event.value); ++ break; ++ case BTN_DPAD_RIGHT: ++ service->NewButtonEvent(gamepad->handle, BUTTON_INDEX_DPAD_RIGHT, ++ !!event.value); ++ break; ++ default: ++ /* For non-gamepad events, this is the "anything goes" numbered ++ * handling that should be handled with remappers. */ ++ gamepad->remapper->RemapButtonEvent( ++ gamepad->handle, gamepad->key_map[event.code], !!event.value); ++ break; ++ } + break; +- case JS_EVENT_AXIS: +- service->NewAxisMoveEvent(gamepad->handle, event.number, +- ((float)event.value) / kMaxAxisValue); ++ case EV_ABS: ++ if (!gamepad->abs_info.count(event.code)) continue; ++ switch (event.code) { ++ case ABS_HAT0X: ++ service->NewButtonEvent( ++ gamepad->handle, BUTTON_INDEX_DPAD_LEFT, ++ AxisNegativeAsButton( ++ ScaleAxis(gamepad->abs_info[event.code], event.value))); ++ service->NewButtonEvent( ++ gamepad->handle, BUTTON_INDEX_DPAD_RIGHT, ++ AxisPositiveAsButton( ++ ScaleAxis(gamepad->abs_info[event.code], event.value))); ++ break; ++ case ABS_HAT0Y: ++ service->NewButtonEvent( ++ gamepad->handle, BUTTON_INDEX_DPAD_UP, ++ AxisNegativeAsButton( ++ ScaleAxis(gamepad->abs_info[event.code], event.value))); ++ service->NewButtonEvent( ++ gamepad->handle, BUTTON_INDEX_DPAD_DOWN, ++ AxisPositiveAsButton( ++ ScaleAxis(gamepad->abs_info[event.code], event.value))); ++ break; ++ case ABS_HAT1X: ++ case ABS_HAT1Y: ++ case ABS_HAT2X: ++ case ABS_HAT2Y: ++ case ABS_HAT3X: ++ case ABS_HAT3Y: ++ break; ++ default: ++ gamepad->remapper->RemapAxisMoveEvent( ++ gamepad->handle, gamepad->abs_map[event.code], ++ ScaleAxis(gamepad->abs_info[event.code], event.value)); ++ break; ++ } + break; + } + } +diff --git dom/gamepad/moz.build dom/gamepad/moz.build +index 5f55d5a95e96..b5d10e9d095a 100644 +--- dom/gamepad/moz.build ++++ dom/gamepad/moz.build +@@ -59,7 +59,7 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows": + UNIFIED_SOURCES += ["windows/WindowsGamepad.cpp"] + elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "android": + UNIFIED_SOURCES += ["android/AndroidGamepad.cpp"] +-elif CONFIG["OS_ARCH"] == "Linux": ++elif CONFIG["OS_ARCH"] == "Linux" or CONFIG["OS_ARCH"] == "FreeBSD": + UNIFIED_SOURCES += ["linux/LinuxGamepad.cpp"] + else: + UNIFIED_SOURCES += ["fallback/FallbackGamepad.cpp"] Added: head/www/firefox/files/patch-bug1686713 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/www/firefox/files/patch-bug1686713 Mon Feb 15 21:28:15 2021 (r565343) @@ -0,0 +1,76 @@ +commit 89e72841a8f5 +Author: Greg V <greg@unrelenting.technology> +Date: Thu Jan 14 22:16:53 2021 +0000 + + Bug 1686713 - Fix mozglue/misc/Uptime build on *BSD +--- + mozglue/misc/Uptime.cpp | 28 +++++++++++++++++----------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +diff --git mozglue/misc/Uptime.cpp mozglue/misc/Uptime.cpp +index bded4017ec13..0e953101994d 100644 +--- mozglue/misc/Uptime.cpp ++++ mozglue/misc/Uptime.cpp +@@ -43,9 +43,7 @@ Maybe<uint64_t> NowIncludingSuspendMs() { + return Some(clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) / kNSperMS); + } + +-#endif // macOS +- +-#if defined(XP_WIN) ++#elif defined(XP_WIN) + + // Number of hundreds of nanoseconds in a millisecond + static constexpr uint64_t kHNSperMS = 10000; +@@ -77,11 +75,23 @@ Maybe<uint64_t> NowIncludingSuspendMs() { + pQueryInterruptTime(&interrupt_time); + return Some(interrupt_time / kHNSperMS); + } +-#endif // XP_WIN + +-#if defined(XP_LINUX) // including Android ++#else ++ + # include <time.h> + ++# ifdef CLOCK_UPTIME // FreeBSD, OpenBSD ++# define CLOCK_EXCLUDING_SUSPEND CLOCK_UPTIME ++# else ++# define CLOCK_EXCLUDING_SUSPEND CLOCK_MONOTONIC ++# endif ++ ++# ifdef CLOCK_BOOTTIME // Linux (including Android), OpenBSD (== MONOTONIC) ++# define CLOCK_INCLUDING_SUSPEND CLOCK_BOOTTIME ++# else ++# define CLOCK_INCLUDING_SUSPEND CLOCK_MONOTONIC ++# endif ++ + // Number of nanoseconds in a millisecond. + static constexpr uint64_t kNSperMS = 1000000; + +@@ -92,23 +102,19 @@ uint64_t TimespecToMilliseconds(struct timespec aTs) { + Maybe<uint64_t> NowExcludingSuspendMs() { + struct timespec ts = {0}; + +- if (clock_gettime(CLOCK_MONOTONIC, &ts)) { ++ if (clock_gettime(CLOCK_EXCLUDING_SUSPEND, &ts)) { + return Nothing(); + } + return Some(TimespecToMilliseconds(ts)); + } + + Maybe<uint64_t> NowIncludingSuspendMs() { +-# ifndef CLOCK_BOOTTIME +- return Nothing(); +-# else + struct timespec ts = {0}; + +- if (clock_gettime(CLOCK_BOOTTIME, &ts)) { ++ if (clock_gettime(CLOCK_INCLUDING_SUSPEND, &ts)) { + return Nothing(); + } + return Some(TimespecToMilliseconds(ts)); +-# endif + } + + #endif // XP_LINUX Modified: head/www/firefox/pkg-message ============================================================================== --- head/www/firefox/pkg-message Mon Feb 15 21:21:04 2021 (r565342) +++ head/www/firefox/pkg-message Mon Feb 15 21:28:15 2021 (r565343) @@ -9,7 +9,6 @@ Some features found on Windows, macOS and Linux are no - Process sandboxing (requires Capsicum backend) - Reduced memory usage (requires mozjemalloc) - Crash Reporter (requires Google Breakpad and reproducible builds) -- Gamepad API (requires libusbhid backend) - WebVR (requires open source runtime) - TCP fast open - `about:networking` (requires link state notification) @@ -29,6 +28,11 @@ To force a specific backend open `about:config` page a Microphone selection only works in `oss`, `pulse`, `pulse-rust` backends. Other backends are limited to `default` which is usually `/dev/dsp`, so use virtual_oss to reroute microphones from non-default devices. + +## Gamepad API + +Requires evdev(4) joystick support. On FreeBSD 13.0 enable hgame(4) +while older versions can use sysutils/iichid or multimedia/webcamd. ## smb:// issues Network group, machine, and share browsing does not work correctly.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202102152128.11FLSFWk045209>